docpouch-client 1.0.1 → 1.0.4
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/.gravatarKey +1 -0
- package/README.md +630 -630
- package/coverage/lcov-report/base.css +224 -0
- package/coverage/lcov-report/block-navigation.js +87 -0
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +131 -0
- package/coverage/lcov-report/prettify.css +1 -0
- package/coverage/lcov-report/prettify.js +2 -0
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +210 -0
- package/coverage/lcov.info +1169 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +42 -1
- package/package.json +4 -4
- package/chat-09e440bd-c52c-44b9-bba4-01cebc84bd7b.txt +0 -223
- package/jest.config.cjs +0 -18
- package/src/index.ts +0 -1004
- package/tests/docPouchClient.test.ts +0 -654
- package/tests/mock-server.ts +0 -613
- package/tsconfig.build.json +0 -7
- package/tsconfig.json +0 -27
package/dist/index.d.ts
CHANGED
|
@@ -179,6 +179,15 @@ export default class docPouchClient {
|
|
|
179
179
|
* @returns {void}
|
|
180
180
|
*/
|
|
181
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;
|
|
182
191
|
/**
|
|
183
192
|
* Initiates the OIDC authentication flow by redirecting to the authorization endpoint.
|
|
184
193
|
*
|
|
@@ -330,6 +339,7 @@ export interface I_OidcConfig {
|
|
|
330
339
|
issuer: string;
|
|
331
340
|
clientId: string;
|
|
332
341
|
redirectUri: string;
|
|
342
|
+
scope?: string;
|
|
333
343
|
scopes?: string[];
|
|
334
344
|
clientSecret?: string;
|
|
335
345
|
}
|
package/dist/index.js
CHANGED
|
@@ -305,6 +305,17 @@ export default class docPouchClient {
|
|
|
305
305
|
}
|
|
306
306
|
}
|
|
307
307
|
// OIDC Authentication Methods
|
|
308
|
+
/**
|
|
309
|
+
* Sets the OIDC configuration to use for the callback and token exchange.
|
|
310
|
+
* Call this before {@link handleOidcCallback} if the client was freshly
|
|
311
|
+
* instantiated after a page reload (the config is otherwise only set
|
|
312
|
+
* internally by {@link loginWithOidc} before the redirect).
|
|
313
|
+
*
|
|
314
|
+
* @param {I_OidcConfig} config - OIDC provider configuration.
|
|
315
|
+
*/
|
|
316
|
+
setOidcConfig(config) {
|
|
317
|
+
this.oidcConfig = config;
|
|
318
|
+
}
|
|
308
319
|
/**
|
|
309
320
|
* Initiates the OIDC authentication flow by redirecting to the authorization endpoint.
|
|
310
321
|
*
|
|
@@ -318,11 +329,19 @@ export default class docPouchClient {
|
|
|
318
329
|
this.codeVerifier = this.generateCodeVerifier();
|
|
319
330
|
this.oidcState = this.generateState();
|
|
320
331
|
const codeChallenge = await this.generateCodeChallenge(this.codeVerifier);
|
|
332
|
+
if (typeof window !== 'undefined' && window.sessionStorage) {
|
|
333
|
+
sessionStorage.setItem('docpouch_oidc_state', this.oidcState);
|
|
334
|
+
sessionStorage.setItem('docpouch_oidc_code_verifier', this.codeVerifier);
|
|
335
|
+
sessionStorage.setItem('docpouch_oidc_issuer', config.issuer);
|
|
336
|
+
sessionStorage.setItem('docpouch_oidc_client_id', config.clientId);
|
|
337
|
+
sessionStorage.setItem('docpouch_oidc_redirect_uri', config.redirectUri);
|
|
338
|
+
}
|
|
339
|
+
const scope = config.scope || config.scopes?.join(' ') || 'openid profile';
|
|
321
340
|
const params = new URLSearchParams({
|
|
322
341
|
response_type: 'code',
|
|
323
342
|
client_id: config.clientId,
|
|
324
343
|
redirect_uri: config.redirectUri,
|
|
325
|
-
scope
|
|
344
|
+
scope,
|
|
326
345
|
state: this.oidcState,
|
|
327
346
|
code_challenge: codeChallenge,
|
|
328
347
|
code_challenge_method: 'S256'
|
|
@@ -343,6 +362,23 @@ export default class docPouchClient {
|
|
|
343
362
|
throw new Error(`OAuth error: ${error}`);
|
|
344
363
|
if (!code || !state)
|
|
345
364
|
return false;
|
|
365
|
+
if (typeof window !== 'undefined' && window.sessionStorage) {
|
|
366
|
+
this.oidcState = sessionStorage.getItem('docpouch_oidc_state') || this.oidcState;
|
|
367
|
+
this.codeVerifier = sessionStorage.getItem('docpouch_oidc_code_verifier') || this.codeVerifier;
|
|
368
|
+
sessionStorage.removeItem('docpouch_oidc_state');
|
|
369
|
+
sessionStorage.removeItem('docpouch_oidc_code_verifier');
|
|
370
|
+
if (!this.oidcConfig) {
|
|
371
|
+
const issuer = sessionStorage.getItem('docpouch_oidc_issuer');
|
|
372
|
+
const clientId = sessionStorage.getItem('docpouch_oidc_client_id');
|
|
373
|
+
const redirectUri = sessionStorage.getItem('docpouch_oidc_redirect_uri');
|
|
374
|
+
if (issuer && clientId && redirectUri) {
|
|
375
|
+
this.oidcConfig = { issuer, clientId, redirectUri };
|
|
376
|
+
sessionStorage.removeItem('docpouch_oidc_issuer');
|
|
377
|
+
sessionStorage.removeItem('docpouch_oidc_client_id');
|
|
378
|
+
sessionStorage.removeItem('docpouch_oidc_redirect_uri');
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
}
|
|
346
382
|
if (state !== this.oidcState)
|
|
347
383
|
throw new Error('State mismatch');
|
|
348
384
|
const discovery = await this.discoverOidc();
|
|
@@ -441,6 +477,7 @@ export default class docPouchClient {
|
|
|
441
477
|
* @returns {Promise<void>}
|
|
442
478
|
*/
|
|
443
479
|
async logout() {
|
|
480
|
+
const wasOidc = this.authMethod === 'oidc';
|
|
444
481
|
this.authToken = null;
|
|
445
482
|
this.clearOidcTokens();
|
|
446
483
|
this.authMethod = 'none';
|
|
@@ -450,6 +487,10 @@ export default class docPouchClient {
|
|
|
450
487
|
(window.location.search.includes('code=') || window.location.search.includes('state='))) {
|
|
451
488
|
window.history.replaceState({}, '', window.location.pathname);
|
|
452
489
|
}
|
|
490
|
+
if (wasOidc && this.oidcConfig && typeof window !== 'undefined') {
|
|
491
|
+
const logoutUrl = `${this.oidcConfig.issuer}/session/end?post_logout_redirect_uri=${encodeURIComponent(this.oidcConfig.redirectUri)}`;
|
|
492
|
+
window.location.href = logoutUrl;
|
|
493
|
+
}
|
|
453
494
|
}
|
|
454
495
|
// OIDC Dynamic Client Registration Methods
|
|
455
496
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "docpouch-client",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"exports": {
|
|
@@ -23,16 +23,16 @@
|
|
|
23
23
|
"description": "Client SDK for DocPouch API - supports JWT and OIDC authentication",
|
|
24
24
|
"repository": {
|
|
25
25
|
"type": "git",
|
|
26
|
-
"url": "https://github.com/BFH-JTF/docpouch-client"
|
|
26
|
+
"url": "git+https://github.com/BFH-JTF/docpouch-client.git"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"@types/express": "^5.0.6",
|
|
30
30
|
"@types/jest": "^30.0.0",
|
|
31
|
-
"@types/node": "^25.
|
|
31
|
+
"@types/node": "^25.9.1",
|
|
32
32
|
"express": "^5.2.1",
|
|
33
33
|
"jest": "^30.4.2",
|
|
34
34
|
"socket.io": "^4.8.3",
|
|
35
|
-
"ts-jest": "^29.4.
|
|
35
|
+
"ts-jest": "^29.4.10",
|
|
36
36
|
"typescript": "^6.0.3"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
@@ -1,223 +0,0 @@
|
|
|
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/jest.config.cjs
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
module.exports = {
|
|
2
|
-
preset: 'ts-jest',
|
|
3
|
-
testEnvironment: 'node',
|
|
4
|
-
moduleNameMapper: {
|
|
5
|
-
'^(\\.{1,2}/.*)\\.js$': '$1',
|
|
6
|
-
},
|
|
7
|
-
transform: {
|
|
8
|
-
'^.+\\.tsx?$': ['ts-jest', {
|
|
9
|
-
useESM: true,
|
|
10
|
-
}],
|
|
11
|
-
},
|
|
12
|
-
extensionsToTreatAsEsm: ['.ts'],
|
|
13
|
-
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
|
|
14
|
-
testMatch: ['**/__tests__/**/*.ts?(x)', '**/?(*.)+(spec|test).ts?(x)', 'tests/**/*.test.ts'],
|
|
15
|
-
collectCoverage: true,
|
|
16
|
-
coverageDirectory: 'coverage',
|
|
17
|
-
coverageReporters: ['text', 'lcov'],
|
|
18
|
-
};
|