@authly/sdk 1.1.1 → 1.2.0
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/globals/clients/AuthlyClient.d.ts +91 -58
- package/dist/globals/clients/AuthlyClient.js +255 -17
- package/dist/globals/configuration/AuthlyConfiguration.d.ts +40 -0
- package/dist/globals/configuration/AuthlyConfiguration.js +43 -0
- package/dist/globals/{clients → internal}/HttpClient.d.ts +7 -7
- package/dist/globals/{clients → internal}/HttpClient.js +7 -7
- package/dist/globals/internal/JWTVerifier.d.ts +37 -0
- package/dist/globals/internal/JWTVerifier.js +71 -0
- package/dist/globals/internal/PKCEUtils.d.ts +23 -0
- package/dist/globals/internal/PKCEUtils.js +59 -0
- package/dist/index.d.ts +25 -2
- package/dist/index.js +25 -2
- package/dist/models/builders/process-errors/base/AuthlyError.d.ts +11 -0
- package/dist/models/builders/process-errors/base/AuthlyError.js +18 -0
- package/dist/models/builders/process-errors/base/AuthlyTokenError.d.ts +12 -0
- package/dist/models/builders/process-errors/base/AuthlyTokenError.js +19 -0
- package/dist/models/builders/process-errors/tokens/AuthlyTokenExpiredError.d.ts +13 -0
- package/dist/models/builders/process-errors/tokens/AuthlyTokenExpiredError.js +20 -0
- package/dist/models/builders/process-errors/tokens/AuthlyTokenInvalidError.d.ts +16 -0
- package/dist/models/builders/process-errors/tokens/AuthlyTokenInvalidError.js +23 -0
- package/dist/models/globals/clients/interfaces/IAuthlyClientOptions.d.ts +62 -0
- package/dist/models/globals/clients/interfaces/IAuthlyStorage.d.ts +22 -0
- package/dist/models/globals/clients/interfaces/IAuthlyStorage.js +2 -0
- package/dist/models/globals/clients/interfaces/IAuthorizeUrlOptions.d.ts +36 -0
- package/dist/models/globals/clients/interfaces/IAuthorizeUrlOptions.js +2 -0
- package/dist/models/globals/clients/interfaces/IDecodedTokenClaim.d.ts +68 -0
- package/dist/models/globals/clients/interfaces/IDecodedTokenClaim.js +2 -0
- package/dist/models/globals/clients/interfaces/ITokenResponse.d.ts +29 -0
- package/dist/models/globals/clients/interfaces/ITokenResponse.js +2 -0
- package/dist/models/globals/clients/interfaces/IUserProfile.d.ts +42 -0
- package/dist/models/globals/clients/interfaces/IUserProfile.js +2 -0
- package/dist/models/globals/clients/internal/interfaces/IJWTVerifierOptions.d.ts +33 -0
- package/dist/models/globals/clients/internal/interfaces/IJWTVerifierOptions.js +2 -0
- package/dist/react/AuthlyCallback.d.ts +20 -0
- package/dist/react/AuthlyCallback.js +45 -0
- package/dist/react/AuthlyContext.d.ts +16 -0
- package/dist/react/AuthlyContext.js +14 -0
- package/dist/react/AuthlyProvider.d.ts +8 -0
- package/dist/react/AuthlyProvider.js +54 -0
- package/dist/react/index.d.ts +3 -0
- package/dist/react/index.js +19 -0
- package/package.json +27 -4
- package/dist/config.d.ts +0 -3
- package/dist/config.js +0 -6
- package/dist/exceptions/index.d.ts +0 -27
- package/dist/exceptions/index.js +0 -46
- package/dist/globals/clients/internal/JWTVerifier.d.ts +0 -26
- package/dist/globals/clients/internal/JWTVerifier.js +0 -55
- package/dist/models/Claims.d.ts +0 -48
- /package/dist/models/{Claims.js → globals/clients/interfaces/IAuthlyClientOptions.js} +0 -0
|
@@ -1,92 +1,125 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { IAuthlyClientOptions } from "../../models/globals/clients/interfaces/IAuthlyClientOptions";
|
|
2
|
+
import type { IAuthorizeUrlOptions } from "../../models/globals/clients/interfaces/IAuthorizeUrlOptions";
|
|
3
|
+
import type { IDecodedTokenClaim } from "../../models/globals/clients/interfaces/IDecodedTokenClaim";
|
|
4
|
+
import type { ITokenResponse } from "../../models/globals/clients/interfaces/ITokenResponse";
|
|
5
|
+
import type { IUserProfile } from "../../models/globals/clients/interfaces/IUserProfile";
|
|
2
6
|
/**
|
|
3
|
-
*
|
|
7
|
+
* @summary A client for interacting with Authly.
|
|
8
|
+
* @description This client handles the validation of tokens against a specific issuer and audience,
|
|
9
|
+
* fetching the public keys (JWKS) automatically, and provides utilities for
|
|
10
|
+
* starting the OAuth2 flow.
|
|
4
11
|
*/
|
|
5
|
-
|
|
12
|
+
declare class AuthlyClient {
|
|
13
|
+
private static readonly ACCESS_TOKEN_KEY;
|
|
6
14
|
/**
|
|
7
|
-
* The
|
|
15
|
+
* @summary The JWT verifier for the client.
|
|
8
16
|
*/
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* The expected audience claim (aud) in the token.
|
|
12
|
-
*/
|
|
13
|
-
audience: string;
|
|
17
|
+
private readonly verifier;
|
|
14
18
|
/**
|
|
15
|
-
* The ID of the
|
|
19
|
+
* @summary The service ID of the client.
|
|
16
20
|
*/
|
|
17
|
-
serviceId
|
|
21
|
+
private readonly serviceId;
|
|
18
22
|
/**
|
|
19
|
-
* The
|
|
23
|
+
* @summary The issuer of the client.
|
|
20
24
|
*/
|
|
21
|
-
|
|
25
|
+
private readonly issuer;
|
|
22
26
|
/**
|
|
23
|
-
* The
|
|
27
|
+
* @summary The authorize path of the client.
|
|
24
28
|
*/
|
|
25
|
-
authorizePath
|
|
29
|
+
private readonly authorizePath;
|
|
26
30
|
/**
|
|
27
|
-
*
|
|
31
|
+
* @summary The token path of the client.
|
|
28
32
|
*/
|
|
29
|
-
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* Options for generating an authorization URL.
|
|
33
|
-
*/
|
|
34
|
-
export interface AuthorizeUrlOptions {
|
|
33
|
+
private readonly tokenPath;
|
|
35
34
|
/**
|
|
36
|
-
* The
|
|
35
|
+
* @summary The user info path of the client.
|
|
37
36
|
*/
|
|
38
|
-
|
|
37
|
+
private readonly userInfoPath;
|
|
39
38
|
/**
|
|
40
|
-
*
|
|
39
|
+
* @summary The redirect URI for the client.
|
|
41
40
|
*/
|
|
42
|
-
|
|
41
|
+
private readonly redirectUri?;
|
|
43
42
|
/**
|
|
44
|
-
* The
|
|
43
|
+
* @summary The storage implementation.
|
|
45
44
|
*/
|
|
46
|
-
|
|
45
|
+
private readonly storage?;
|
|
47
46
|
/**
|
|
48
|
-
*
|
|
47
|
+
* @summary Memory cache for the access token.
|
|
49
48
|
*/
|
|
50
|
-
|
|
49
|
+
private accessToken;
|
|
51
50
|
/**
|
|
52
|
-
*
|
|
51
|
+
* @summary Constructs a new AuthlyClient.
|
|
52
|
+
* @param options - The options for the client.
|
|
53
53
|
*/
|
|
54
|
-
|
|
54
|
+
constructor(options: IAuthlyClientOptions);
|
|
55
55
|
/**
|
|
56
|
-
*
|
|
56
|
+
* @summary Prepares the authorization request, stores PKCE state, and returns the URL.
|
|
57
|
+
* @param options - Optional overrides for the authorization request.
|
|
58
|
+
* @returns A promise that resolves to the authorization URL.
|
|
57
59
|
*/
|
|
58
|
-
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* A client for interacting with Authly.
|
|
62
|
-
*
|
|
63
|
-
* This client handles the validation of tokens against a specific issuer and audience,
|
|
64
|
-
* fetching the public keys (JWKS) automatically, and provides utilities for
|
|
65
|
-
* starting the OAuth2 flow.
|
|
66
|
-
*/
|
|
67
|
-
export declare class AuthlyClient {
|
|
68
|
-
private readonly verifier;
|
|
69
|
-
private readonly serviceId;
|
|
70
|
-
private readonly issuer;
|
|
71
|
-
private readonly authorizePath;
|
|
72
|
-
constructor(options: AuthlyClientOptions);
|
|
60
|
+
authorize(options?: Partial<IAuthorizeUrlOptions>): Promise<string>;
|
|
73
61
|
/**
|
|
74
|
-
* Generate the authorization URL to redirect the user to.
|
|
75
|
-
*
|
|
62
|
+
* @summary Generate the authorization URL to redirect the user to.
|
|
76
63
|
* @param options - Options for generating the URL.
|
|
77
64
|
* @returns The full authorization URL.
|
|
78
65
|
*/
|
|
79
|
-
getAuthorizeUrl(options:
|
|
66
|
+
getAuthorizeUrl(options: IAuthorizeUrlOptions): string;
|
|
67
|
+
/**
|
|
68
|
+
* @summary Exchanges the authorization code for tokens using PKCE flow and state validation.
|
|
69
|
+
* @param urlParams - The URLSearchParams containing 'code' and 'state'.
|
|
70
|
+
* @returns A promise that resolves to the token response.
|
|
71
|
+
*/
|
|
72
|
+
exchangeToken(urlParams: URLSearchParams): Promise<ITokenResponse>;
|
|
73
|
+
/**
|
|
74
|
+
* @summary Set the current session.
|
|
75
|
+
* @param response - The token response from Authly.
|
|
76
|
+
*/
|
|
77
|
+
setSession(response: ITokenResponse): Promise<void>;
|
|
78
|
+
/**
|
|
79
|
+
* @summary Get the current access token.
|
|
80
|
+
* @returns The access token or null if not found.
|
|
81
|
+
*/
|
|
82
|
+
getAccessToken(): Promise<string | null>;
|
|
83
|
+
/**
|
|
84
|
+
* @summary Refreshes the access token using the refresh_token grant.
|
|
85
|
+
* @description In the browser, this relies on the 'session' cookie if no explicit refresh token is provided.
|
|
86
|
+
* @param refreshToken - Optional explicit refresh token.
|
|
87
|
+
* @returns A promise that resolves to the new access token.
|
|
88
|
+
*/
|
|
89
|
+
refreshToken(refreshToken?: string): Promise<string | null>;
|
|
90
|
+
/**
|
|
91
|
+
* @summary Fetches the user profile from the userinfo endpoint.
|
|
92
|
+
* @description Automatically handles token expiration by attempting to refresh the token once.
|
|
93
|
+
* @returns A promise that resolves to the user profile or null if not authenticated.
|
|
94
|
+
*/
|
|
95
|
+
getUser(): Promise<IUserProfile | null>;
|
|
96
|
+
/**
|
|
97
|
+
* @summary Synchronously check if the user is authenticated based on token presence and expiration.
|
|
98
|
+
* @description This only checks the token locally and does not perform a network request.
|
|
99
|
+
* @returns True if a valid token exists and is not expired.
|
|
100
|
+
*/
|
|
101
|
+
isAuthenticated(): Promise<boolean>;
|
|
102
|
+
/**
|
|
103
|
+
* @summary Logs out the user by clearing the session from storage and memory.
|
|
104
|
+
*/
|
|
105
|
+
logout(): Promise<void>;
|
|
106
|
+
/**
|
|
107
|
+
* @summary Exchange the authorization code for an access token.
|
|
108
|
+
* @param code - The authorization code received from the callback.
|
|
109
|
+
* @param redirectUri - The redirect URI used in the authorize request.
|
|
110
|
+
* @param codeVerifier - The PKCE code verifier (required if used in authorize).
|
|
111
|
+
* @returns A promise that resolves to the token response.
|
|
112
|
+
*/
|
|
113
|
+
exchangeCodeForToken(code: string, redirectUri: string, codeVerifier?: string): Promise<ITokenResponse>;
|
|
80
114
|
/**
|
|
81
|
-
* Verify a JWT token and return its decoded claims.
|
|
82
|
-
*
|
|
83
|
-
* This method verifies the token's signature using the provider's JWKS,
|
|
115
|
+
* @summary Verify a JWT token and return its decoded claims.
|
|
116
|
+
* @description This method verifies the token's signature using the provider's JWKS,
|
|
84
117
|
* and validates standard claims like expiration, issuer, and audience.
|
|
85
|
-
*
|
|
86
118
|
* @param token - The encoded JWT token string.
|
|
87
119
|
* @returns A promise that resolves to the token claims (e.g., sub, iss, aud).
|
|
88
|
-
* @throws {
|
|
89
|
-
* @throws {
|
|
120
|
+
* @throws {AuthlyTokenExpiredError} If the token has expired.
|
|
121
|
+
* @throws {AuthlyTokenInvalidError} If the token is invalid (e.g., bad signature, invalid audience).
|
|
90
122
|
*/
|
|
91
|
-
verify(token: string): Promise<
|
|
123
|
+
verify(token: string): Promise<IDecodedTokenClaim>;
|
|
92
124
|
}
|
|
125
|
+
export { AuthlyClient };
|
|
@@ -1,35 +1,104 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.AuthlyClient = void 0;
|
|
4
|
-
const
|
|
5
|
-
const JWTVerifier_1 = require("
|
|
4
|
+
const jose_1 = require("jose");
|
|
5
|
+
const JWTVerifier_1 = require("../internal/JWTVerifier");
|
|
6
|
+
const HttpClient_1 = require("../internal/HttpClient");
|
|
7
|
+
const PKCEUtils_1 = require("../internal/PKCEUtils");
|
|
8
|
+
const AuthlyConfiguration_1 = require("../configuration/AuthlyConfiguration");
|
|
6
9
|
/**
|
|
7
|
-
* A client for interacting with Authly.
|
|
8
|
-
*
|
|
9
|
-
* This client handles the validation of tokens against a specific issuer and audience,
|
|
10
|
+
* @summary A client for interacting with Authly.
|
|
11
|
+
* @description This client handles the validation of tokens against a specific issuer and audience,
|
|
10
12
|
* fetching the public keys (JWKS) automatically, and provides utilities for
|
|
11
13
|
* starting the OAuth2 flow.
|
|
12
14
|
*/
|
|
13
15
|
class AuthlyClient {
|
|
16
|
+
static ACCESS_TOKEN_KEY = "authly_access_token";
|
|
17
|
+
/**
|
|
18
|
+
* @summary The JWT verifier for the client.
|
|
19
|
+
*/
|
|
14
20
|
verifier;
|
|
21
|
+
/**
|
|
22
|
+
* @summary The service ID of the client.
|
|
23
|
+
*/
|
|
15
24
|
serviceId;
|
|
25
|
+
/**
|
|
26
|
+
* @summary The issuer of the client.
|
|
27
|
+
*/
|
|
16
28
|
issuer;
|
|
29
|
+
/**
|
|
30
|
+
* @summary The authorize path of the client.
|
|
31
|
+
*/
|
|
17
32
|
authorizePath;
|
|
33
|
+
/**
|
|
34
|
+
* @summary The token path of the client.
|
|
35
|
+
*/
|
|
36
|
+
tokenPath;
|
|
37
|
+
/**
|
|
38
|
+
* @summary The user info path of the client.
|
|
39
|
+
*/
|
|
40
|
+
userInfoPath;
|
|
41
|
+
/**
|
|
42
|
+
* @summary The redirect URI for the client.
|
|
43
|
+
*/
|
|
44
|
+
redirectUri;
|
|
45
|
+
/**
|
|
46
|
+
* @summary The storage implementation.
|
|
47
|
+
*/
|
|
48
|
+
storage;
|
|
49
|
+
/**
|
|
50
|
+
* @summary Memory cache for the access token.
|
|
51
|
+
*/
|
|
52
|
+
accessToken = null;
|
|
53
|
+
/**
|
|
54
|
+
* @summary Constructs a new AuthlyClient.
|
|
55
|
+
* @param options - The options for the client.
|
|
56
|
+
*/
|
|
18
57
|
constructor(options) {
|
|
19
58
|
this.issuer = options.issuer.replace(/\/$/, "");
|
|
20
59
|
this.serviceId = options.serviceId;
|
|
21
|
-
|
|
22
|
-
this.
|
|
60
|
+
this.authorizePath = options.authorizePath || AuthlyConfiguration_1.AuthlyConfiguration.DEFAULT_AUTHORIZE_PATH;
|
|
61
|
+
this.tokenPath = options.tokenPath || AuthlyConfiguration_1.AuthlyConfiguration.DEFAULT_TOKEN_PATH;
|
|
62
|
+
this.userInfoPath = options.userInfoPath || AuthlyConfiguration_1.AuthlyConfiguration.DEFAULT_USER_INFO_PATH;
|
|
63
|
+
this.redirectUri = options.redirectUri;
|
|
64
|
+
this.storage = options.storage;
|
|
65
|
+
if (!this.storage && typeof window !== "undefined" && window.sessionStorage) {
|
|
66
|
+
this.storage = window.sessionStorage;
|
|
67
|
+
}
|
|
23
68
|
this.verifier = new JWTVerifier_1.JWTVerifier({
|
|
24
69
|
issuer: this.issuer,
|
|
25
70
|
audience: options.audience,
|
|
26
|
-
jwksUrl: `${this.issuer}${jwksPath}`,
|
|
71
|
+
jwksUrl: `${this.issuer}${options.jwksPath || AuthlyConfiguration_1.AuthlyConfiguration.DEFAULT_JWKS_PATH}`,
|
|
27
72
|
algorithms: options.algorithms,
|
|
28
73
|
});
|
|
29
74
|
}
|
|
30
75
|
/**
|
|
31
|
-
*
|
|
32
|
-
*
|
|
76
|
+
* @summary Prepares the authorization request, stores PKCE state, and returns the URL.
|
|
77
|
+
* @param options - Optional overrides for the authorization request.
|
|
78
|
+
* @returns A promise that resolves to the authorization URL.
|
|
79
|
+
*/
|
|
80
|
+
async authorize(options) {
|
|
81
|
+
if (!this.storage) {
|
|
82
|
+
throw new Error("Storage is not configured. Cannot save state and code verifier.");
|
|
83
|
+
}
|
|
84
|
+
if (!this.redirectUri && !options?.redirectUri) {
|
|
85
|
+
throw new Error("Redirect URI is required but not configured.");
|
|
86
|
+
}
|
|
87
|
+
const state = options?.state || PKCEUtils_1.PKCEUtils.generateRandomString();
|
|
88
|
+
const codeVerifier = PKCEUtils_1.PKCEUtils.generateRandomString();
|
|
89
|
+
const codeChallenge = await PKCEUtils_1.PKCEUtils.generateCodeChallenge(codeVerifier);
|
|
90
|
+
await this.storage.setItem("pkce_state", state);
|
|
91
|
+
await this.storage.setItem("pkce_verifier", codeVerifier);
|
|
92
|
+
return this.getAuthorizeUrl({
|
|
93
|
+
redirectUri: (options?.redirectUri || this.redirectUri),
|
|
94
|
+
...options,
|
|
95
|
+
state,
|
|
96
|
+
codeChallenge,
|
|
97
|
+
codeChallengeMethod: "S256",
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* @summary Generate the authorization URL to redirect the user to.
|
|
33
102
|
* @param options - Options for generating the URL.
|
|
34
103
|
* @returns The full authorization URL.
|
|
35
104
|
*/
|
|
@@ -41,19 +110,188 @@ class AuthlyClient {
|
|
|
41
110
|
url.searchParams.set("scope", options.scope || "openid profile email");
|
|
42
111
|
url.searchParams.set("state", options.state);
|
|
43
112
|
url.searchParams.set("code_challenge", options.codeChallenge);
|
|
44
|
-
url.searchParams.set("code_challenge_method", options.codeChallengeMethod || "
|
|
113
|
+
url.searchParams.set("code_challenge_method", options.codeChallengeMethod || "s256");
|
|
45
114
|
return url.toString();
|
|
46
115
|
}
|
|
47
116
|
/**
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
117
|
+
* @summary Exchanges the authorization code for tokens using PKCE flow and state validation.
|
|
118
|
+
* @param urlParams - The URLSearchParams containing 'code' and 'state'.
|
|
119
|
+
* @returns A promise that resolves to the token response.
|
|
120
|
+
*/
|
|
121
|
+
async exchangeToken(urlParams) {
|
|
122
|
+
const code = urlParams.get("code");
|
|
123
|
+
const state = urlParams.get("state");
|
|
124
|
+
if (!code) {
|
|
125
|
+
throw new Error("No authorization code found in URL parameters.");
|
|
126
|
+
}
|
|
127
|
+
if (!this.storage) {
|
|
128
|
+
throw new Error("Storage is not configured. Cannot retrieve state and code verifier.");
|
|
129
|
+
}
|
|
130
|
+
const storedState = await this.storage.getItem("pkce_state");
|
|
131
|
+
if (!state || state !== storedState) {
|
|
132
|
+
throw new Error("Invalid state. Possible CSRF attack.");
|
|
133
|
+
}
|
|
134
|
+
const codeVerifier = await this.storage.getItem("pkce_verifier");
|
|
135
|
+
if (!codeVerifier) {
|
|
136
|
+
throw new Error("No code verifier found in storage.");
|
|
137
|
+
}
|
|
138
|
+
if (!this.redirectUri) {
|
|
139
|
+
throw new Error("Redirect URI is not configured in AuthlyClient options.");
|
|
140
|
+
}
|
|
141
|
+
const tokenResponse = await this.exchangeCodeForToken(code, this.redirectUri, codeVerifier);
|
|
142
|
+
await this.setSession(tokenResponse);
|
|
143
|
+
// Clear temporary storage
|
|
144
|
+
await this.storage.removeItem("pkce_state");
|
|
145
|
+
await this.storage.removeItem("pkce_verifier");
|
|
146
|
+
return tokenResponse;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* @summary Set the current session.
|
|
150
|
+
* @param response - The token response from Authly.
|
|
151
|
+
*/
|
|
152
|
+
async setSession(response) {
|
|
153
|
+
this.accessToken = response.access_token;
|
|
154
|
+
if (this.storage) {
|
|
155
|
+
await this.storage.setItem(AuthlyClient.ACCESS_TOKEN_KEY, response.access_token);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* @summary Get the current access token.
|
|
160
|
+
* @returns The access token or null if not found.
|
|
161
|
+
*/
|
|
162
|
+
async getAccessToken() {
|
|
163
|
+
if (this.accessToken)
|
|
164
|
+
return this.accessToken;
|
|
165
|
+
if (this.storage) {
|
|
166
|
+
this.accessToken = await this.storage.getItem(AuthlyClient.ACCESS_TOKEN_KEY);
|
|
167
|
+
}
|
|
168
|
+
return this.accessToken;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* @summary Refreshes the access token using the refresh_token grant.
|
|
172
|
+
* @description In the browser, this relies on the 'session' cookie if no explicit refresh token is provided.
|
|
173
|
+
* @param refreshToken - Optional explicit refresh token.
|
|
174
|
+
* @returns A promise that resolves to the new access token.
|
|
175
|
+
*/
|
|
176
|
+
async refreshToken(refreshToken) {
|
|
177
|
+
const url = `${this.issuer}${this.tokenPath}`;
|
|
178
|
+
const body = {
|
|
179
|
+
grant_type: "refresh_token",
|
|
180
|
+
client_id: this.serviceId,
|
|
181
|
+
};
|
|
182
|
+
if (refreshToken) {
|
|
183
|
+
body.refresh_token = refreshToken;
|
|
184
|
+
}
|
|
185
|
+
const response = await HttpClient_1.HttpClient.post(url, {
|
|
186
|
+
headers: {
|
|
187
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
188
|
+
},
|
|
189
|
+
body: new URLSearchParams(body).toString(),
|
|
190
|
+
});
|
|
191
|
+
if (!response.success) {
|
|
192
|
+
return null;
|
|
193
|
+
}
|
|
194
|
+
await this.setSession(response.data);
|
|
195
|
+
return response.data.access_token;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* @summary Fetches the user profile from the userinfo endpoint.
|
|
199
|
+
* @description Automatically handles token expiration by attempting to refresh the token once.
|
|
200
|
+
* @returns A promise that resolves to the user profile or null if not authenticated.
|
|
201
|
+
*/
|
|
202
|
+
async getUser() {
|
|
203
|
+
let token = await this.getAccessToken();
|
|
204
|
+
if (!token)
|
|
205
|
+
return null;
|
|
206
|
+
const fetchInfo = async (currentBuffer) => {
|
|
207
|
+
return HttpClient_1.HttpClient.get(`${this.issuer}${this.userInfoPath}`, {
|
|
208
|
+
headers: {
|
|
209
|
+
Authorization: `Bearer ${currentBuffer}`,
|
|
210
|
+
},
|
|
211
|
+
});
|
|
212
|
+
};
|
|
213
|
+
let response = await fetchInfo(token);
|
|
214
|
+
// If unauthorized (401), try to refresh token once
|
|
215
|
+
if (!response.success && response.error?.code === "UNAUTHORIZED") {
|
|
216
|
+
token = await this.refreshToken();
|
|
217
|
+
if (token) {
|
|
218
|
+
response = await fetchInfo(token);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
if (!response.success) {
|
|
222
|
+
if (response.error?.code === "UNAUTHORIZED") {
|
|
223
|
+
await this.logout();
|
|
224
|
+
}
|
|
225
|
+
return null;
|
|
226
|
+
}
|
|
227
|
+
return response.data;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* @summary Synchronously check if the user is authenticated based on token presence and expiration.
|
|
231
|
+
* @description This only checks the token locally and does not perform a network request.
|
|
232
|
+
* @returns True if a valid token exists and is not expired.
|
|
233
|
+
*/
|
|
234
|
+
async isAuthenticated() {
|
|
235
|
+
const token = await this.getAccessToken();
|
|
236
|
+
if (!token)
|
|
237
|
+
return false;
|
|
238
|
+
try {
|
|
239
|
+
const decoded = (0, jose_1.decodeJwt)(token);
|
|
240
|
+
if (!decoded.exp)
|
|
241
|
+
return true;
|
|
242
|
+
const now = Math.floor(Date.now() / 1000);
|
|
243
|
+
return decoded.exp > now + 10;
|
|
244
|
+
}
|
|
245
|
+
catch {
|
|
246
|
+
return false;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* @summary Logs out the user by clearing the session from storage and memory.
|
|
251
|
+
*/
|
|
252
|
+
async logout() {
|
|
253
|
+
this.accessToken = null;
|
|
254
|
+
if (this.storage) {
|
|
255
|
+
await this.storage.removeItem(AuthlyClient.ACCESS_TOKEN_KEY);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* @summary Exchange the authorization code for an access token.
|
|
260
|
+
* @param code - The authorization code received from the callback.
|
|
261
|
+
* @param redirectUri - The redirect URI used in the authorize request.
|
|
262
|
+
* @param codeVerifier - The PKCE code verifier (required if used in authorize).
|
|
263
|
+
* @returns A promise that resolves to the token response.
|
|
264
|
+
*/
|
|
265
|
+
async exchangeCodeForToken(code, redirectUri, codeVerifier) {
|
|
266
|
+
const url = `${this.issuer}${this.tokenPath}`;
|
|
267
|
+
const body = {
|
|
268
|
+
grant_type: "authorization_code",
|
|
269
|
+
client_id: this.serviceId,
|
|
270
|
+
code,
|
|
271
|
+
redirect_uri: redirectUri,
|
|
272
|
+
};
|
|
273
|
+
if (codeVerifier) {
|
|
274
|
+
body.code_verifier = codeVerifier;
|
|
275
|
+
}
|
|
276
|
+
const response = await HttpClient_1.HttpClient.post(url, {
|
|
277
|
+
headers: {
|
|
278
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
279
|
+
},
|
|
280
|
+
body: new URLSearchParams(body).toString(),
|
|
281
|
+
});
|
|
282
|
+
if (!response.success) {
|
|
283
|
+
throw new Error(response.error?.message || "Failed to exchange code for token");
|
|
284
|
+
}
|
|
285
|
+
return response.data;
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* @summary Verify a JWT token and return its decoded claims.
|
|
289
|
+
* @description This method verifies the token's signature using the provider's JWKS,
|
|
51
290
|
* and validates standard claims like expiration, issuer, and audience.
|
|
52
|
-
*
|
|
53
291
|
* @param token - The encoded JWT token string.
|
|
54
292
|
* @returns A promise that resolves to the token claims (e.g., sub, iss, aud).
|
|
55
|
-
* @throws {
|
|
56
|
-
* @throws {
|
|
293
|
+
* @throws {AuthlyTokenExpiredError} If the token has expired.
|
|
294
|
+
* @throws {AuthlyTokenInvalidError} If the token is invalid (e.g., bad signature, invalid audience).
|
|
57
295
|
*/
|
|
58
296
|
async verify(token) {
|
|
59
297
|
return this.verifier.verify(token);
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @summary Configuration for the Authly library.
|
|
3
|
+
*/
|
|
4
|
+
declare class AuthlyConfiguration {
|
|
5
|
+
/**
|
|
6
|
+
* @summary Private constructor to prevent instantiation.
|
|
7
|
+
*/
|
|
8
|
+
private constructor();
|
|
9
|
+
/**
|
|
10
|
+
* @summary The default JWKS path.
|
|
11
|
+
* @readonly This property is readonly and cannot be changed.
|
|
12
|
+
* @default "/.well-known/jwks.json"
|
|
13
|
+
*/
|
|
14
|
+
static readonly DEFAULT_JWKS_PATH: string;
|
|
15
|
+
/**
|
|
16
|
+
* @summary The default authorize path.
|
|
17
|
+
* @readonly This property is readonly and cannot be changed.
|
|
18
|
+
* @default "/authorize"
|
|
19
|
+
*/
|
|
20
|
+
static readonly DEFAULT_AUTHORIZE_PATH: string;
|
|
21
|
+
/**
|
|
22
|
+
* @summary The default token path.
|
|
23
|
+
* @readonly This property is readonly and cannot be changed.
|
|
24
|
+
* @default "/oauth/token"
|
|
25
|
+
*/
|
|
26
|
+
static readonly DEFAULT_TOKEN_PATH: string;
|
|
27
|
+
/**
|
|
28
|
+
* @summary The default user info path.
|
|
29
|
+
* @readonly This property is readonly and cannot be changed.
|
|
30
|
+
* @default "/v1/oauth/userinfo"
|
|
31
|
+
*/
|
|
32
|
+
static readonly DEFAULT_USER_INFO_PATH: string;
|
|
33
|
+
/**
|
|
34
|
+
* @summary The default algorithms.
|
|
35
|
+
* @readonly This property is readonly and cannot be changed.
|
|
36
|
+
* @default ["RS256"]
|
|
37
|
+
*/
|
|
38
|
+
static readonly DEFAULT_ALGORITHMS: readonly string[];
|
|
39
|
+
}
|
|
40
|
+
export { AuthlyConfiguration };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AuthlyConfiguration = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* @summary Configuration for the Authly library.
|
|
6
|
+
*/
|
|
7
|
+
class AuthlyConfiguration {
|
|
8
|
+
/**
|
|
9
|
+
* @summary Private constructor to prevent instantiation.
|
|
10
|
+
*/
|
|
11
|
+
constructor() { }
|
|
12
|
+
/**
|
|
13
|
+
* @summary The default JWKS path.
|
|
14
|
+
* @readonly This property is readonly and cannot be changed.
|
|
15
|
+
* @default "/.well-known/jwks.json"
|
|
16
|
+
*/
|
|
17
|
+
static DEFAULT_JWKS_PATH = "/.well-known/jwks.json";
|
|
18
|
+
/**
|
|
19
|
+
* @summary The default authorize path.
|
|
20
|
+
* @readonly This property is readonly and cannot be changed.
|
|
21
|
+
* @default "/authorize"
|
|
22
|
+
*/
|
|
23
|
+
static DEFAULT_AUTHORIZE_PATH = "/authorize";
|
|
24
|
+
/**
|
|
25
|
+
* @summary The default token path.
|
|
26
|
+
* @readonly This property is readonly and cannot be changed.
|
|
27
|
+
* @default "/oauth/token"
|
|
28
|
+
*/
|
|
29
|
+
static DEFAULT_TOKEN_PATH = "/oauth/token";
|
|
30
|
+
/**
|
|
31
|
+
* @summary The default user info path.
|
|
32
|
+
* @readonly This property is readonly and cannot be changed.
|
|
33
|
+
* @default "/v1/oauth/userinfo"
|
|
34
|
+
*/
|
|
35
|
+
static DEFAULT_USER_INFO_PATH = "/v1/oauth/userinfo";
|
|
36
|
+
/**
|
|
37
|
+
* @summary The default algorithms.
|
|
38
|
+
* @readonly This property is readonly and cannot be changed.
|
|
39
|
+
* @default ["RS256"]
|
|
40
|
+
*/
|
|
41
|
+
static DEFAULT_ALGORITHMS = ["RS256"];
|
|
42
|
+
}
|
|
43
|
+
exports.AuthlyConfiguration = AuthlyConfiguration;
|
|
@@ -1,46 +1,46 @@
|
|
|
1
1
|
import type { IRequestResponseClient } from "../../models/globals/clients/interfaces/IRequestResponseClient";
|
|
2
2
|
/**
|
|
3
|
-
* A class that provides a static method for making HTTP requests.
|
|
3
|
+
* @summary A class that provides a static method for making HTTP requests.
|
|
4
4
|
*/
|
|
5
5
|
declare class HttpClient {
|
|
6
6
|
private constructor();
|
|
7
7
|
/**
|
|
8
|
-
* Makes an HTTP request to the specified URL.
|
|
8
|
+
* @summary Makes an HTTP request to the specified URL.
|
|
9
9
|
* @param url - The URL to make the request to.
|
|
10
10
|
* @param options - The options for the request.
|
|
11
11
|
* @returns A promise that resolves to the response data.
|
|
12
12
|
*/
|
|
13
13
|
private static request;
|
|
14
14
|
/**
|
|
15
|
-
* Makes a GET request to the specified URL.
|
|
15
|
+
* @summary Makes a GET request to the specified URL.
|
|
16
16
|
* @param url - The URL to make the request to.
|
|
17
17
|
* @param options - The options for the request.
|
|
18
18
|
* @returns A promise that resolves to the response data.
|
|
19
19
|
*/
|
|
20
20
|
static get<D>(url: string, options?: Omit<RequestInit, "method">): Promise<IRequestResponseClient<D>>;
|
|
21
21
|
/**
|
|
22
|
-
* Makes a POST request to the specified URL.
|
|
22
|
+
* @summary Makes a POST request to the specified URL.
|
|
23
23
|
* @param url - The URL to make the request to.
|
|
24
24
|
* @param options - The options for the request.
|
|
25
25
|
* @returns A promise that resolves to the response data.
|
|
26
26
|
*/
|
|
27
27
|
static post<D>(url: string, options?: Omit<RequestInit, "method">): Promise<IRequestResponseClient<D>>;
|
|
28
28
|
/**
|
|
29
|
-
* Makes a PUT request to the specified URL.
|
|
29
|
+
* @summary Makes a PUT request to the specified URL.
|
|
30
30
|
* @param url - The URL to make the request to.
|
|
31
31
|
* @param options - The options for the request.
|
|
32
32
|
* @returns A promise that resolves to the response data.
|
|
33
33
|
*/
|
|
34
34
|
static put<D>(url: string, options?: Omit<RequestInit, "method">): Promise<IRequestResponseClient<D>>;
|
|
35
35
|
/**
|
|
36
|
-
* Makes a PATCH request to the specified URL.
|
|
36
|
+
* @summary Makes a PATCH request to the specified URL.
|
|
37
37
|
* @param url - The URL to make the request to.
|
|
38
38
|
* @param options - The options for the request.
|
|
39
39
|
* @returns A promise that resolves to the response data.
|
|
40
40
|
*/
|
|
41
41
|
static patch<D>(url: string, options?: Omit<RequestInit, "method">): Promise<IRequestResponseClient<D>>;
|
|
42
42
|
/**
|
|
43
|
-
* Makes a DELETE request to the specified URL.
|
|
43
|
+
* @summary Makes a DELETE request to the specified URL.
|
|
44
44
|
* @param url - The URL to make the request to.
|
|
45
45
|
* @param options - The options for the request.
|
|
46
46
|
* @returns A promise that resolves to the response data.
|