@zskj-idaas/sdk 1.0.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/dist/index.d.mts +14 -1
- package/dist/index.d.ts +14 -1
- package/dist/index.js +52 -6
- package/dist/index.mjs +52 -6
- package/package.json +4 -3
package/dist/index.d.mts
CHANGED
|
@@ -18,6 +18,11 @@ interface TokenSet {
|
|
|
18
18
|
refresh_token?: string;
|
|
19
19
|
scope: string;
|
|
20
20
|
}
|
|
21
|
+
interface ServiceTokenState {
|
|
22
|
+
accessToken: string;
|
|
23
|
+
expiresAt: number;
|
|
24
|
+
scope: string;
|
|
25
|
+
}
|
|
21
26
|
interface UserInfo {
|
|
22
27
|
sub: string;
|
|
23
28
|
preferred_username?: string;
|
|
@@ -35,6 +40,10 @@ interface AuthState {
|
|
|
35
40
|
idToken: string | null;
|
|
36
41
|
expiresAt: number | null;
|
|
37
42
|
}
|
|
43
|
+
interface SessionLogoutOptions {
|
|
44
|
+
/** Redirect after the server-side session and local tokens are cleared. */
|
|
45
|
+
redirectTo?: string;
|
|
46
|
+
}
|
|
38
47
|
interface PKCEPair {
|
|
39
48
|
codeVerifier: string;
|
|
40
49
|
codeChallenge: string;
|
|
@@ -45,6 +54,7 @@ declare class IdaasClient {
|
|
|
45
54
|
private endpoints;
|
|
46
55
|
private storage;
|
|
47
56
|
private userInfo;
|
|
57
|
+
private serviceTokens;
|
|
48
58
|
constructor(config: IdaasConfig);
|
|
49
59
|
init(): Promise<AuthState>;
|
|
50
60
|
private discover;
|
|
@@ -53,13 +63,16 @@ declare class IdaasClient {
|
|
|
53
63
|
refreshToken(): Promise<TokenSet | null>;
|
|
54
64
|
getUserInfo(forceRefresh?: boolean): Promise<UserInfo | null>;
|
|
55
65
|
getAccessToken(): Promise<string | null>;
|
|
66
|
+
getServiceToken(serviceKey: string): Promise<string | null>;
|
|
56
67
|
getIdToken(): string | null;
|
|
57
68
|
getAuthState(): AuthState;
|
|
58
69
|
isAuthenticated(): boolean;
|
|
59
70
|
logout(): Promise<void>;
|
|
71
|
+
logoutSession(options?: SessionLogoutOptions): Promise<void>;
|
|
60
72
|
revokeToken(): Promise<void>;
|
|
61
73
|
/** Create an authenticated fetch wrapper */
|
|
62
74
|
fetch(url: string, init?: RequestInit): Promise<Response>;
|
|
75
|
+
fetchService(serviceKey: string, url: string, init?: RequestInit): Promise<Response>;
|
|
63
76
|
}
|
|
64
77
|
|
|
65
78
|
declare function createPKCE(): Promise<PKCEPair>;
|
|
@@ -86,4 +99,4 @@ declare class TokenStorage {
|
|
|
86
99
|
clearAuthState(): void;
|
|
87
100
|
}
|
|
88
101
|
|
|
89
|
-
export { type AuthState, IdaasClient, type IdaasConfig, type TokenSet, TokenStorage, type UserInfo, createPKCE, generateNonce, generateState };
|
|
102
|
+
export { type AuthState, IdaasClient, type IdaasConfig, type ServiceTokenState, type SessionLogoutOptions, type TokenSet, TokenStorage, type UserInfo, createPKCE, generateNonce, generateState };
|
package/dist/index.d.ts
CHANGED
|
@@ -18,6 +18,11 @@ interface TokenSet {
|
|
|
18
18
|
refresh_token?: string;
|
|
19
19
|
scope: string;
|
|
20
20
|
}
|
|
21
|
+
interface ServiceTokenState {
|
|
22
|
+
accessToken: string;
|
|
23
|
+
expiresAt: number;
|
|
24
|
+
scope: string;
|
|
25
|
+
}
|
|
21
26
|
interface UserInfo {
|
|
22
27
|
sub: string;
|
|
23
28
|
preferred_username?: string;
|
|
@@ -35,6 +40,10 @@ interface AuthState {
|
|
|
35
40
|
idToken: string | null;
|
|
36
41
|
expiresAt: number | null;
|
|
37
42
|
}
|
|
43
|
+
interface SessionLogoutOptions {
|
|
44
|
+
/** Redirect after the server-side session and local tokens are cleared. */
|
|
45
|
+
redirectTo?: string;
|
|
46
|
+
}
|
|
38
47
|
interface PKCEPair {
|
|
39
48
|
codeVerifier: string;
|
|
40
49
|
codeChallenge: string;
|
|
@@ -45,6 +54,7 @@ declare class IdaasClient {
|
|
|
45
54
|
private endpoints;
|
|
46
55
|
private storage;
|
|
47
56
|
private userInfo;
|
|
57
|
+
private serviceTokens;
|
|
48
58
|
constructor(config: IdaasConfig);
|
|
49
59
|
init(): Promise<AuthState>;
|
|
50
60
|
private discover;
|
|
@@ -53,13 +63,16 @@ declare class IdaasClient {
|
|
|
53
63
|
refreshToken(): Promise<TokenSet | null>;
|
|
54
64
|
getUserInfo(forceRefresh?: boolean): Promise<UserInfo | null>;
|
|
55
65
|
getAccessToken(): Promise<string | null>;
|
|
66
|
+
getServiceToken(serviceKey: string): Promise<string | null>;
|
|
56
67
|
getIdToken(): string | null;
|
|
57
68
|
getAuthState(): AuthState;
|
|
58
69
|
isAuthenticated(): boolean;
|
|
59
70
|
logout(): Promise<void>;
|
|
71
|
+
logoutSession(options?: SessionLogoutOptions): Promise<void>;
|
|
60
72
|
revokeToken(): Promise<void>;
|
|
61
73
|
/** Create an authenticated fetch wrapper */
|
|
62
74
|
fetch(url: string, init?: RequestInit): Promise<Response>;
|
|
75
|
+
fetchService(serviceKey: string, url: string, init?: RequestInit): Promise<Response>;
|
|
63
76
|
}
|
|
64
77
|
|
|
65
78
|
declare function createPKCE(): Promise<PKCEPair>;
|
|
@@ -86,4 +99,4 @@ declare class TokenStorage {
|
|
|
86
99
|
clearAuthState(): void;
|
|
87
100
|
}
|
|
88
101
|
|
|
89
|
-
export { type AuthState, IdaasClient, type IdaasConfig, type TokenSet, TokenStorage, type UserInfo, createPKCE, generateNonce, generateState };
|
|
102
|
+
export { type AuthState, IdaasClient, type IdaasConfig, type ServiceTokenState, type SessionLogoutOptions, type TokenSet, TokenStorage, type UserInfo, createPKCE, generateNonce, generateState };
|
package/dist/index.js
CHANGED
|
@@ -254,6 +254,7 @@ var IdaasClient = class {
|
|
|
254
254
|
constructor(config) {
|
|
255
255
|
this.endpoints = null;
|
|
256
256
|
this.userInfo = null;
|
|
257
|
+
this.serviceTokens = /* @__PURE__ */ new Map();
|
|
257
258
|
this.config = {
|
|
258
259
|
scope: "openid profile email",
|
|
259
260
|
autoDiscovery: true,
|
|
@@ -276,6 +277,7 @@ var IdaasClient = class {
|
|
|
276
277
|
introspection_endpoint: `${this.config.issuer}/oauth2/introspect`
|
|
277
278
|
};
|
|
278
279
|
}
|
|
280
|
+
await this.getAccessToken();
|
|
279
281
|
return this.getAuthState();
|
|
280
282
|
}
|
|
281
283
|
async discover() {
|
|
@@ -392,14 +394,40 @@ var IdaasClient = class {
|
|
|
392
394
|
return this.userInfo;
|
|
393
395
|
}
|
|
394
396
|
async getAccessToken() {
|
|
395
|
-
|
|
396
|
-
if (token) return token;
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
if (tokens) return tokens.access_token;
|
|
400
|
-
}
|
|
397
|
+
const token = this.storage.getAccessToken();
|
|
398
|
+
if (token && !this.storage.isTokenExpired()) return token;
|
|
399
|
+
const tokens = await this.refreshToken();
|
|
400
|
+
if (tokens) return tokens.access_token;
|
|
401
401
|
return null;
|
|
402
402
|
}
|
|
403
|
+
async getServiceToken(serviceKey) {
|
|
404
|
+
if (!this.endpoints) await this.init();
|
|
405
|
+
const cached = this.serviceTokens.get(serviceKey);
|
|
406
|
+
if (cached && Date.now() < cached.expiresAt - 6e4) {
|
|
407
|
+
return cached.accessToken;
|
|
408
|
+
}
|
|
409
|
+
const baseToken = await this.getAccessToken();
|
|
410
|
+
if (!baseToken) return null;
|
|
411
|
+
const res = await fetch(`${this.config.issuer}/oauth2/business-token`, {
|
|
412
|
+
method: "POST",
|
|
413
|
+
headers: {
|
|
414
|
+
"Content-Type": "application/json",
|
|
415
|
+
Authorization: `Bearer ${baseToken}`
|
|
416
|
+
},
|
|
417
|
+
body: JSON.stringify({ service_key: serviceKey })
|
|
418
|
+
});
|
|
419
|
+
if (!res.ok) {
|
|
420
|
+
this.serviceTokens.delete(serviceKey);
|
|
421
|
+
return null;
|
|
422
|
+
}
|
|
423
|
+
const tokenSet = await res.json();
|
|
424
|
+
this.serviceTokens.set(serviceKey, {
|
|
425
|
+
accessToken: tokenSet.access_token,
|
|
426
|
+
expiresAt: Date.now() + tokenSet.expires_in * 1e3,
|
|
427
|
+
scope: tokenSet.scope
|
|
428
|
+
});
|
|
429
|
+
return tokenSet.access_token;
|
|
430
|
+
}
|
|
403
431
|
getIdToken() {
|
|
404
432
|
return this.storage.getIdToken();
|
|
405
433
|
}
|
|
@@ -428,6 +456,17 @@ var IdaasClient = class {
|
|
|
428
456
|
}
|
|
429
457
|
window.location.href = `${this.endpoints.end_session_endpoint}?${params.toString()}`;
|
|
430
458
|
}
|
|
459
|
+
async logoutSession(options = {}) {
|
|
460
|
+
this.storage.clear();
|
|
461
|
+
this.userInfo = null;
|
|
462
|
+
await fetch(`${this.config.issuer}/auth/logout`, {
|
|
463
|
+
method: "POST",
|
|
464
|
+
credentials: "include"
|
|
465
|
+
}).catch(() => void 0);
|
|
466
|
+
if (options.redirectTo) {
|
|
467
|
+
window.location.href = options.redirectTo;
|
|
468
|
+
}
|
|
469
|
+
}
|
|
431
470
|
async revokeToken() {
|
|
432
471
|
if (!this.endpoints) await this.init();
|
|
433
472
|
const refreshToken = this.storage.getRefreshToken();
|
|
@@ -451,6 +490,13 @@ var IdaasClient = class {
|
|
|
451
490
|
}
|
|
452
491
|
return fetch(url, { ...init, headers });
|
|
453
492
|
}
|
|
493
|
+
async fetchService(serviceKey, url, init) {
|
|
494
|
+
const token = await this.getServiceToken(serviceKey);
|
|
495
|
+
if (!token) throw new Error(`No service token available for ${serviceKey}`);
|
|
496
|
+
const headers = new Headers(init?.headers);
|
|
497
|
+
headers.set("Authorization", `Bearer ${token}`);
|
|
498
|
+
return fetch(url, { ...init, headers });
|
|
499
|
+
}
|
|
454
500
|
};
|
|
455
501
|
// Annotate the CommonJS export names for ESM import in node:
|
|
456
502
|
0 && (module.exports = {
|
package/dist/index.mjs
CHANGED
|
@@ -224,6 +224,7 @@ var IdaasClient = class {
|
|
|
224
224
|
constructor(config) {
|
|
225
225
|
this.endpoints = null;
|
|
226
226
|
this.userInfo = null;
|
|
227
|
+
this.serviceTokens = /* @__PURE__ */ new Map();
|
|
227
228
|
this.config = {
|
|
228
229
|
scope: "openid profile email",
|
|
229
230
|
autoDiscovery: true,
|
|
@@ -246,6 +247,7 @@ var IdaasClient = class {
|
|
|
246
247
|
introspection_endpoint: `${this.config.issuer}/oauth2/introspect`
|
|
247
248
|
};
|
|
248
249
|
}
|
|
250
|
+
await this.getAccessToken();
|
|
249
251
|
return this.getAuthState();
|
|
250
252
|
}
|
|
251
253
|
async discover() {
|
|
@@ -362,14 +364,40 @@ var IdaasClient = class {
|
|
|
362
364
|
return this.userInfo;
|
|
363
365
|
}
|
|
364
366
|
async getAccessToken() {
|
|
365
|
-
|
|
366
|
-
if (token) return token;
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
if (tokens) return tokens.access_token;
|
|
370
|
-
}
|
|
367
|
+
const token = this.storage.getAccessToken();
|
|
368
|
+
if (token && !this.storage.isTokenExpired()) return token;
|
|
369
|
+
const tokens = await this.refreshToken();
|
|
370
|
+
if (tokens) return tokens.access_token;
|
|
371
371
|
return null;
|
|
372
372
|
}
|
|
373
|
+
async getServiceToken(serviceKey) {
|
|
374
|
+
if (!this.endpoints) await this.init();
|
|
375
|
+
const cached = this.serviceTokens.get(serviceKey);
|
|
376
|
+
if (cached && Date.now() < cached.expiresAt - 6e4) {
|
|
377
|
+
return cached.accessToken;
|
|
378
|
+
}
|
|
379
|
+
const baseToken = await this.getAccessToken();
|
|
380
|
+
if (!baseToken) return null;
|
|
381
|
+
const res = await fetch(`${this.config.issuer}/oauth2/business-token`, {
|
|
382
|
+
method: "POST",
|
|
383
|
+
headers: {
|
|
384
|
+
"Content-Type": "application/json",
|
|
385
|
+
Authorization: `Bearer ${baseToken}`
|
|
386
|
+
},
|
|
387
|
+
body: JSON.stringify({ service_key: serviceKey })
|
|
388
|
+
});
|
|
389
|
+
if (!res.ok) {
|
|
390
|
+
this.serviceTokens.delete(serviceKey);
|
|
391
|
+
return null;
|
|
392
|
+
}
|
|
393
|
+
const tokenSet = await res.json();
|
|
394
|
+
this.serviceTokens.set(serviceKey, {
|
|
395
|
+
accessToken: tokenSet.access_token,
|
|
396
|
+
expiresAt: Date.now() + tokenSet.expires_in * 1e3,
|
|
397
|
+
scope: tokenSet.scope
|
|
398
|
+
});
|
|
399
|
+
return tokenSet.access_token;
|
|
400
|
+
}
|
|
373
401
|
getIdToken() {
|
|
374
402
|
return this.storage.getIdToken();
|
|
375
403
|
}
|
|
@@ -398,6 +426,17 @@ var IdaasClient = class {
|
|
|
398
426
|
}
|
|
399
427
|
window.location.href = `${this.endpoints.end_session_endpoint}?${params.toString()}`;
|
|
400
428
|
}
|
|
429
|
+
async logoutSession(options = {}) {
|
|
430
|
+
this.storage.clear();
|
|
431
|
+
this.userInfo = null;
|
|
432
|
+
await fetch(`${this.config.issuer}/auth/logout`, {
|
|
433
|
+
method: "POST",
|
|
434
|
+
credentials: "include"
|
|
435
|
+
}).catch(() => void 0);
|
|
436
|
+
if (options.redirectTo) {
|
|
437
|
+
window.location.href = options.redirectTo;
|
|
438
|
+
}
|
|
439
|
+
}
|
|
401
440
|
async revokeToken() {
|
|
402
441
|
if (!this.endpoints) await this.init();
|
|
403
442
|
const refreshToken = this.storage.getRefreshToken();
|
|
@@ -421,6 +460,13 @@ var IdaasClient = class {
|
|
|
421
460
|
}
|
|
422
461
|
return fetch(url, { ...init, headers });
|
|
423
462
|
}
|
|
463
|
+
async fetchService(serviceKey, url, init) {
|
|
464
|
+
const token = await this.getServiceToken(serviceKey);
|
|
465
|
+
if (!token) throw new Error(`No service token available for ${serviceKey}`);
|
|
466
|
+
const headers = new Headers(init?.headers);
|
|
467
|
+
headers.set("Authorization", `Bearer ${token}`);
|
|
468
|
+
return fetch(url, { ...init, headers });
|
|
469
|
+
}
|
|
424
470
|
};
|
|
425
471
|
export {
|
|
426
472
|
IdaasClient,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zskj-idaas/sdk",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "IDaaS OIDC Client SDK for browser applications — supports Authorization Code Flow with PKCE, token management, and authenticated fetch.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
"scripts": {
|
|
27
27
|
"build": "tsup src/index.ts --format cjs,esm --dts --clean",
|
|
28
28
|
"dev": "tsup src/index.ts --format cjs,esm --dts --watch",
|
|
29
|
+
"test": "vitest run",
|
|
29
30
|
"prepublishOnly": "npm run build"
|
|
30
31
|
},
|
|
31
32
|
"keywords": [
|
|
@@ -57,9 +58,9 @@
|
|
|
57
58
|
"not dead",
|
|
58
59
|
"not ie 11"
|
|
59
60
|
],
|
|
60
|
-
"dependencies": {},
|
|
61
61
|
"devDependencies": {
|
|
62
62
|
"tsup": "^8.2.0",
|
|
63
|
-
"typescript": "^5.6.0"
|
|
63
|
+
"typescript": "^5.6.0",
|
|
64
|
+
"vitest": "^4.1.7"
|
|
64
65
|
}
|
|
65
66
|
}
|