docpouch-client 0.9.1 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +630 -449
- package/chat-09e440bd-c52c-44b9-bba4-01cebc84bd7b.txt +223 -0
- package/dist/index.d.ts +156 -5
- package/dist/index.js +344 -10
- package/hff +114 -0
- package/{jest.config.js → jest.config.cjs} +1 -1
- package/package.json +41 -38
- package/src/index.ts +1045 -622
- package/tests/docPouchClient.test.ts +654 -0
- package/tests/mock-server.ts +613 -0
- package/tsconfig.build.json +7 -0
- package/tsconfig.json +9 -7
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
Chat 'ChatTitle(text="I am adding authent…" with OpenCode, isCustom=true)' (09e440bd-c52c-44b9-bba4-01cebc84bd7b)
|
|
2
|
+
Context:
|
|
3
|
+
|
|
4
|
+
Messages: 18
|
|
5
|
+
=================================================================================================================
|
|
6
|
+
|
|
7
|
+
==== RestoredMessage #1 ====
|
|
8
|
+
User:
|
|
9
|
+
I am adding authentication using node-oidcProvider to my app in addition to the already present localStorage solution. To give clients the possibility to register, is it enough to create a call to `this.expressApp.post` and get the necessary information from the client including some kind of secret?
|
|
10
|
+
Attachments:
|
|
11
|
+
Attachment Name: Console Selection
|
|
12
|
+
Attachments Kind: Visible
|
|
13
|
+
Attachments Source: Other / RestoredChatAttachment
|
|
14
|
+
Attachments Text:
|
|
15
|
+
this.expressApp.get
|
|
16
|
+
Attachment Name: Console Selection
|
|
17
|
+
Attachments Kind: Visible
|
|
18
|
+
Attachments Source: Other / RestoredChatAttachment
|
|
19
|
+
Attachments Text:
|
|
20
|
+
validate
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
kotlin.Unit
|
|
24
|
+
|
|
25
|
+
==== RestoredMessage #2 ====
|
|
26
|
+
Assistant:
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
kotlin.Unit
|
|
30
|
+
|
|
31
|
+
==== RestoredMessage #3 ====
|
|
32
|
+
User:
|
|
33
|
+
Yes, good idea
|
|
34
|
+
Attachments:
|
|
35
|
+
Attachment Name: Console Selection
|
|
36
|
+
Attachments Kind: Visible
|
|
37
|
+
Attachments Source: Other / RestoredChatAttachment
|
|
38
|
+
Attachments Text:
|
|
39
|
+
validate
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
kotlin.Unit
|
|
43
|
+
|
|
44
|
+
==== RestoredMessage #4 ====
|
|
45
|
+
Assistant:
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
kotlin.Unit
|
|
49
|
+
|
|
50
|
+
==== RestoredMessage #5 ====
|
|
51
|
+
User:
|
|
52
|
+
1. I want a controlled registration. I changed initialAccessToken to `process.env.OIDC_REGISTRATION_TOKEN`.
|
|
53
|
+
2. I don't even know what JWKS is, let alone have anything set up for it.
|
|
54
|
+
Yes, please proceed
|
|
55
|
+
Attachments:
|
|
56
|
+
Attachment Name: Console Selection
|
|
57
|
+
Attachments Kind: Visible
|
|
58
|
+
Attachments Source: Other / RestoredChatAttachment
|
|
59
|
+
Attachments Text:
|
|
60
|
+
process.env.OIDC_REGISTRATION_TOKEN
|
|
61
|
+
Attachment Name: Console Selection
|
|
62
|
+
Attachments Kind: Visible
|
|
63
|
+
Attachments Source: Other / RestoredChatAttachment
|
|
64
|
+
Attachments Text:
|
|
65
|
+
validate
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
kotlin.Unit
|
|
69
|
+
|
|
70
|
+
==== RestoredMessage #6 ====
|
|
71
|
+
Assistant:
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
kotlin.Unit
|
|
75
|
+
|
|
76
|
+
==== RestoredMessage #7 ====
|
|
77
|
+
User:
|
|
78
|
+
Let's go with a static JWKS for starters. Yes, I would like the clients to have their choice, whether they want to use the localStorage or the OIDC approach for authentication. For both, the clients are expected to build their own login masks.
|
|
79
|
+
If the registration token is not just a random string, I need help, yes.
|
|
80
|
+
Attachments:
|
|
81
|
+
Attachment Name: Console Selection
|
|
82
|
+
Attachments Kind: Visible
|
|
83
|
+
Attachments Source: Other / RestoredChatAttachment
|
|
84
|
+
Attachments Text:
|
|
85
|
+
process.env.OIDC_REGISTRATION_TOKEN
|
|
86
|
+
Attachment Name: Console Selection
|
|
87
|
+
Attachments Kind: Visible
|
|
88
|
+
Attachments Source: Other / RestoredChatAttachment
|
|
89
|
+
Attachments Text:
|
|
90
|
+
validate
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
kotlin.Unit
|
|
94
|
+
|
|
95
|
+
==== RestoredMessage #8 ====
|
|
96
|
+
Assistant:
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
kotlin.Unit
|
|
100
|
+
|
|
101
|
+
==== RestoredMessage #9 ====
|
|
102
|
+
User:
|
|
103
|
+
I am unsure,now. If I give clients these options for auth, is it easier for them, than having to build their own login mask?
|
|
104
|
+
1. The old approach using the token in localStorage.
|
|
105
|
+
2. OIDC and they can use a login mask provided by docPouch.
|
|
106
|
+
Attachments:
|
|
107
|
+
Attachment Name: Console Selection
|
|
108
|
+
Attachments Kind: Visible
|
|
109
|
+
Attachments Source: Other / RestoredChatAttachment
|
|
110
|
+
Attachments Text:
|
|
111
|
+
process.env.OIDC_REGISTRATION_TOKEN
|
|
112
|
+
Attachment Name: Console Selection
|
|
113
|
+
Attachments Kind: Visible
|
|
114
|
+
Attachments Source: Other / RestoredChatAttachment
|
|
115
|
+
Attachments Text:
|
|
116
|
+
validate
|
|
117
|
+
Attachment Name: Console Selection
|
|
118
|
+
Attachments Kind: Visible
|
|
119
|
+
Attachments Source: Other / RestoredChatAttachment
|
|
120
|
+
Attachments Text:
|
|
121
|
+
JWT_SECRET=your-secure-jwt-secret-here
|
|
122
|
+
Attachment Name: Console Selection
|
|
123
|
+
Attachments Kind: Visible
|
|
124
|
+
Attachments Source: Other / RestoredChatAttachment
|
|
125
|
+
Attachments Text:
|
|
126
|
+
NODE_ENV
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
kotlin.Unit
|
|
130
|
+
|
|
131
|
+
==== RestoredMessage #10 ====
|
|
132
|
+
Assistant:
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
kotlin.Unit
|
|
136
|
+
|
|
137
|
+
==== RestoredMessage #11 ====
|
|
138
|
+
User:
|
|
139
|
+
I want to offer both choices and build a server-side login page.
|
|
140
|
+
Attachments:
|
|
141
|
+
Attachment Name: Console Selection
|
|
142
|
+
Attachments Kind: Visible
|
|
143
|
+
Attachments Source: Other / RestoredChatAttachment
|
|
144
|
+
Attachments Text:
|
|
145
|
+
process.env.OIDC_REGISTRATION_TOKEN
|
|
146
|
+
Attachment Name: Console Selection
|
|
147
|
+
Attachments Kind: Visible
|
|
148
|
+
Attachments Source: Other / RestoredChatAttachment
|
|
149
|
+
Attachments Text:
|
|
150
|
+
validate
|
|
151
|
+
Attachment Name: Console Selection
|
|
152
|
+
Attachments Kind: Visible
|
|
153
|
+
Attachments Source: Other / RestoredChatAttachment
|
|
154
|
+
Attachments Text:
|
|
155
|
+
JWT_SECRET=your-secure-jwt-secret-here
|
|
156
|
+
Attachment Name: Console Selection
|
|
157
|
+
Attachments Kind: Visible
|
|
158
|
+
Attachments Source: Other / RestoredChatAttachment
|
|
159
|
+
Attachments Text:
|
|
160
|
+
NODE_ENV
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
kotlin.Unit
|
|
164
|
+
|
|
165
|
+
==== RestoredMessage #12 ====
|
|
166
|
+
Assistant:
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
kotlin.Unit
|
|
170
|
+
|
|
171
|
+
==== RestoredMessage #13 ====
|
|
172
|
+
User:
|
|
173
|
+
Do I need to update the express routes, so that they are able to validate users using both approaches?
|
|
174
|
+
Attachments:
|
|
175
|
+
Attachment Name: Console Selection
|
|
176
|
+
Attachments Kind: Visible
|
|
177
|
+
Attachments Source: Other / RestoredChatAttachment
|
|
178
|
+
Attachments Text:
|
|
179
|
+
JWT_SECRET=your-secure-jwt-secret-here
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
kotlin.Unit
|
|
183
|
+
|
|
184
|
+
==== RestoredMessage #14 ====
|
|
185
|
+
Assistant:
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
kotlin.Unit
|
|
189
|
+
|
|
190
|
+
==== RestoredMessage #15 ====
|
|
191
|
+
User:
|
|
192
|
+
I am importing interfaces from the docPouch client I have written. I assume I will have to update some of those, as well, when I update the docPouch client, correct?
|
|
193
|
+
Attachments:
|
|
194
|
+
Attachment Name: Console Selection
|
|
195
|
+
Attachments Kind: Visible
|
|
196
|
+
Attachments Source: Other / RestoredChatAttachment
|
|
197
|
+
Attachments Text:
|
|
198
|
+
JWT_SECRET=your-secure-jwt-secret-here
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
kotlin.Unit
|
|
202
|
+
|
|
203
|
+
==== RestoredMessage #16 ====
|
|
204
|
+
Assistant:
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
kotlin.Unit
|
|
208
|
+
|
|
209
|
+
==== UserMessageImpl #17 ====
|
|
210
|
+
User:
|
|
211
|
+
Yes, I would like to go for Option A and the client should offer different methods for the different auth methods and thus explicitly choose. Please make a detailed plan for yourself, so when I load up my docpouch-client project and give you this instruction, you know exactly what to do.
|
|
212
|
+
|
|
213
|
+
kotlin.Unit
|
|
214
|
+
|
|
215
|
+
==== AgentMessage #18 ====
|
|
216
|
+
Assistant:
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
Tool use list:
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
kotlin.Unit
|
|
223
|
+
|
package/dist/index.d.ts
CHANGED
|
@@ -34,6 +34,14 @@ export default class docPouchClient {
|
|
|
34
34
|
* @type {string | null}
|
|
35
35
|
*/
|
|
36
36
|
private authToken;
|
|
37
|
+
private oidcConfig;
|
|
38
|
+
private oidcAccessToken;
|
|
39
|
+
private oidcRefreshToken;
|
|
40
|
+
private oidcIdToken;
|
|
41
|
+
private oidcTokenExpiry;
|
|
42
|
+
private codeVerifier;
|
|
43
|
+
private oidcState;
|
|
44
|
+
private authMethod;
|
|
37
45
|
/**
|
|
38
46
|
* Flag indicating whether a connection attempt is in progress.
|
|
39
47
|
*
|
|
@@ -171,6 +179,90 @@ export default class docPouchClient {
|
|
|
171
179
|
* @returns {void}
|
|
172
180
|
*/
|
|
173
181
|
debugSocketConnection(): void;
|
|
182
|
+
/**
|
|
183
|
+
* Sets the OIDC configuration to use for the callback and token exchange.
|
|
184
|
+
* Call this before {@link handleOidcCallback} if the client was freshly
|
|
185
|
+
* instantiated after a page reload (the config is otherwise only set
|
|
186
|
+
* internally by {@link loginWithOidc} before the redirect).
|
|
187
|
+
*
|
|
188
|
+
* @param {I_OidcConfig} config - OIDC provider configuration.
|
|
189
|
+
*/
|
|
190
|
+
setOidcConfig(config: I_OidcConfig): void;
|
|
191
|
+
/**
|
|
192
|
+
* Initiates the OIDC authentication flow by redirecting to the authorization endpoint.
|
|
193
|
+
*
|
|
194
|
+
* @param {I_OidcConfig} config - OIDC provider configuration.
|
|
195
|
+
* @returns {Promise<void>}
|
|
196
|
+
*/
|
|
197
|
+
loginWithOidc(config: I_OidcConfig): Promise<void>;
|
|
198
|
+
/**
|
|
199
|
+
* Handles the OIDC callback by exchanging the authorization code for tokens.
|
|
200
|
+
*
|
|
201
|
+
* @returns {Promise<boolean>} True if the callback was handled successfully.
|
|
202
|
+
*/
|
|
203
|
+
handleOidcCallback(): Promise<boolean>;
|
|
204
|
+
restoreOidcSession(): boolean;
|
|
205
|
+
/**
|
|
206
|
+
* Ensures the OIDC access token is valid, refreshing it if necessary.
|
|
207
|
+
*/
|
|
208
|
+
ensureValidOidcToken(): Promise<string>;
|
|
209
|
+
/**
|
|
210
|
+
* Returns the current authentication method.
|
|
211
|
+
*
|
|
212
|
+
* @returns {'jwt' | 'oidc' | 'none'} The active auth method.
|
|
213
|
+
*/
|
|
214
|
+
getAuthMethod(): 'jwt' | 'oidc' | 'none';
|
|
215
|
+
/**
|
|
216
|
+
* Checks whether the client is currently authenticated.
|
|
217
|
+
*
|
|
218
|
+
* @returns {boolean} True if authenticated.
|
|
219
|
+
*/
|
|
220
|
+
isAuthenticated(): boolean;
|
|
221
|
+
/**
|
|
222
|
+
* Returns the current active token, regardless of auth method.
|
|
223
|
+
*
|
|
224
|
+
* @returns {string | null} The active token or null.
|
|
225
|
+
*/
|
|
226
|
+
getToken(): string | null;
|
|
227
|
+
/**
|
|
228
|
+
* Logs out the client, clearing all tokens and disconnecting WebSocket.
|
|
229
|
+
*
|
|
230
|
+
* @returns {Promise<void>}
|
|
231
|
+
*/
|
|
232
|
+
logout(): Promise<void>;
|
|
233
|
+
/**
|
|
234
|
+
* Registers a new OIDC client with the server (dynamic client registration).
|
|
235
|
+
*
|
|
236
|
+
* @param {I_OidcClientRegistration} registration - Client metadata for registration.
|
|
237
|
+
* @param {string} [registrationToken] - Initial registration access token. If not provided, the current auth token is used.
|
|
238
|
+
* @returns {Promise<I_OidcClientResponse>} The registered client details.
|
|
239
|
+
*/
|
|
240
|
+
registerOidcClient(registration: I_OidcClientRegistration, registrationToken?: string): Promise<I_OidcClientResponse>;
|
|
241
|
+
/**
|
|
242
|
+
* Retrieves the registration state of an existing OIDC client.
|
|
243
|
+
*
|
|
244
|
+
* @param {string} clientId - The client identifier.
|
|
245
|
+
* @param {string} [registrationToken] - The registration access token. If not provided, the current auth token is used.
|
|
246
|
+
* @returns {Promise<I_OidcClientResponse>} The client details.
|
|
247
|
+
*/
|
|
248
|
+
getOidcClient(clientId: string, registrationToken?: string): Promise<I_OidcClientResponse>;
|
|
249
|
+
/**
|
|
250
|
+
* Updates the registration of an existing OIDC client.
|
|
251
|
+
*
|
|
252
|
+
* @param {string} clientId - The client identifier.
|
|
253
|
+
* @param {I_OidcClientRegistration} registration - Updated client metadata.
|
|
254
|
+
* @param {string} [registrationToken] - The registration access token. If not provided, the current auth token is used.
|
|
255
|
+
* @returns {Promise<I_OidcClientResponse>} The updated client details.
|
|
256
|
+
*/
|
|
257
|
+
updateOidcClient(clientId: string, registration: I_OidcClientRegistration, registrationToken?: string): Promise<I_OidcClientResponse>;
|
|
258
|
+
/**
|
|
259
|
+
* Deletes an OIDC client registration.
|
|
260
|
+
*
|
|
261
|
+
* @param {string} clientId - The client identifier.
|
|
262
|
+
* @param {string} [registrationToken] - The registration access token. If not provided, the current auth token is used.
|
|
263
|
+
* @returns {Promise<void>}
|
|
264
|
+
*/
|
|
265
|
+
deleteOidcClient(clientId: string, registrationToken?: string): Promise<void>;
|
|
174
266
|
/**
|
|
175
267
|
* Sets up permanent socket listeners for the client.
|
|
176
268
|
*
|
|
@@ -195,6 +287,15 @@ export default class docPouchClient {
|
|
|
195
287
|
* @private
|
|
196
288
|
*/
|
|
197
289
|
private request;
|
|
290
|
+
private discoverOidc;
|
|
291
|
+
private setOidcTokens;
|
|
292
|
+
private clearOidcTokens;
|
|
293
|
+
private persistOidcSession;
|
|
294
|
+
private clearPersistedOidcSession;
|
|
295
|
+
private refreshOidcToken;
|
|
296
|
+
private generateCodeVerifier;
|
|
297
|
+
private generateCodeChallenge;
|
|
298
|
+
private generateState;
|
|
198
299
|
}
|
|
199
300
|
export interface I_UserEntry extends I_UserCreation {
|
|
200
301
|
_id: string;
|
|
@@ -229,10 +330,64 @@ export interface I_UserDisplay {
|
|
|
229
330
|
}
|
|
230
331
|
export interface I_LoginResponse {
|
|
231
332
|
_id: string;
|
|
232
|
-
token
|
|
333
|
+
token?: string;
|
|
233
334
|
isAdmin: boolean;
|
|
234
335
|
userName: string;
|
|
336
|
+
expiresIn?: number;
|
|
337
|
+
}
|
|
338
|
+
export interface I_OidcConfig {
|
|
339
|
+
issuer: string;
|
|
340
|
+
clientId: string;
|
|
341
|
+
redirectUri: string;
|
|
342
|
+
scope?: string;
|
|
343
|
+
scopes?: string[];
|
|
344
|
+
clientSecret?: string;
|
|
345
|
+
}
|
|
346
|
+
export interface I_OidcTokenResponse {
|
|
347
|
+
accessToken: string;
|
|
348
|
+
refreshToken?: string;
|
|
349
|
+
idToken?: string;
|
|
235
350
|
expiresIn: number;
|
|
351
|
+
tokenType: string;
|
|
352
|
+
scope: string;
|
|
353
|
+
}
|
|
354
|
+
export interface I_OidcUserInfo {
|
|
355
|
+
sub: string;
|
|
356
|
+
name?: string;
|
|
357
|
+
email?: string;
|
|
358
|
+
}
|
|
359
|
+
export interface I_OidcClientRegistration {
|
|
360
|
+
client_name: string;
|
|
361
|
+
redirect_uris: string[];
|
|
362
|
+
grant_types?: string[];
|
|
363
|
+
response_types?: string[];
|
|
364
|
+
scope?: string;
|
|
365
|
+
token_endpoint_auth_method?: 'client_secret_basic' | 'client_secret_post' | 'none';
|
|
366
|
+
application_type?: 'web' | 'native';
|
|
367
|
+
logo_uri?: string;
|
|
368
|
+
client_uri?: string;
|
|
369
|
+
policy_uri?: string;
|
|
370
|
+
tos_uri?: string;
|
|
371
|
+
}
|
|
372
|
+
export interface I_OidcClientResponse {
|
|
373
|
+
client_id: string;
|
|
374
|
+
client_secret?: string;
|
|
375
|
+
client_secret_expires_at?: number;
|
|
376
|
+
client_id_issued_at?: number;
|
|
377
|
+
registration_access_token?: string;
|
|
378
|
+
registration_client_uri?: string;
|
|
379
|
+
client_name?: string;
|
|
380
|
+
redirect_uris?: string[];
|
|
381
|
+
grant_types?: string[];
|
|
382
|
+
response_types?: string[];
|
|
383
|
+
scope?: string;
|
|
384
|
+
token_endpoint_auth_method?: string;
|
|
385
|
+
}
|
|
386
|
+
export interface I_AuthState {
|
|
387
|
+
method: 'jwt' | 'oidc' | 'none';
|
|
388
|
+
token: string | null;
|
|
389
|
+
isAdmin: boolean;
|
|
390
|
+
userName: string;
|
|
236
391
|
}
|
|
237
392
|
export interface I_DocumentEntry extends I_DocumentCreationOwned {
|
|
238
393
|
_id: string;
|
|
@@ -281,16 +436,12 @@ export interface I_StructureField {
|
|
|
281
436
|
export interface I_StructureCreation {
|
|
282
437
|
name: string;
|
|
283
438
|
description?: string;
|
|
284
|
-
type: number;
|
|
285
|
-
subType: number;
|
|
286
439
|
fields: I_StructureField[];
|
|
287
440
|
}
|
|
288
441
|
export interface I_StructureUpdate {
|
|
289
442
|
_id?: string;
|
|
290
443
|
name?: string;
|
|
291
444
|
description?: string;
|
|
292
|
-
type?: number;
|
|
293
|
-
subType?: number;
|
|
294
445
|
fields?: I_StructureField[];
|
|
295
446
|
}
|
|
296
447
|
export type I_EventString = 'heartbeatPong' | "heartbeatPing" | "newDocument" | "newStructure" | "newUser" | "newType" | "removedID" | "changedDocument" | "changedStructure" | "changedUser" | "changedType" | "removedUser" | "removedStructure" | "removedDocument" | "removedType";
|