@draftlab/auth 0.0.3 → 0.1.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/allow.d.ts +58 -1
- package/dist/allow.js +61 -2
- package/dist/client.d.ts +2 -3
- package/dist/client.js +2 -2
- package/dist/core.d.ts +128 -8
- package/dist/core.js +496 -12
- package/dist/error.d.ts +242 -1
- package/dist/error.js +235 -1
- package/dist/index.d.ts +1 -8
- package/dist/index.js +1 -12
- package/dist/keys.d.ts +1 -1
- package/dist/keys.js +138 -3
- package/dist/pkce.js +160 -1
- package/dist/provider/code.d.ts +227 -3
- package/dist/provider/code.js +27 -14
- package/dist/provider/facebook.d.ts +2 -3
- package/dist/provider/facebook.js +1 -5
- package/dist/provider/github.d.ts +2 -3
- package/dist/provider/github.js +1 -5
- package/dist/provider/google.d.ts +2 -3
- package/dist/provider/google.js +1 -5
- package/dist/provider/oauth2.d.ts +175 -3
- package/dist/provider/oauth2.js +153 -5
- package/dist/provider/password.d.ts +384 -3
- package/dist/provider/password.js +4 -4
- package/dist/provider/provider.d.ts +226 -2
- package/dist/random.js +85 -1
- package/dist/storage/memory.d.ts +2 -2
- package/dist/storage/memory.js +1 -1
- package/dist/storage/storage.d.ts +161 -1
- package/dist/storage/storage.js +60 -1
- package/dist/storage/turso.d.ts +1 -1
- package/dist/storage/turso.js +1 -1
- package/dist/storage/unstorage.d.ts +2 -2
- package/dist/storage/unstorage.js +2 -2
- package/dist/subject.d.ts +61 -2
- package/dist/themes/theme.d.ts +208 -1
- package/dist/themes/theme.js +118 -1
- package/dist/ui/base.d.ts +22 -35
- package/dist/ui/base.js +388 -3
- package/dist/ui/code.d.ts +22 -137
- package/dist/ui/code.js +199 -161
- package/dist/ui/form.d.ts +8 -6
- package/dist/ui/form.js +57 -1
- package/dist/ui/icon.d.ts +7 -84
- package/dist/ui/icon.js +69 -2
- package/dist/ui/password.d.ts +30 -37
- package/dist/ui/password.js +340 -237
- package/dist/ui/select.d.ts +19 -218
- package/dist/ui/select.js +91 -4
- package/dist/util.d.ts +71 -1
- package/dist/util.js +106 -1
- package/package.json +5 -3
- package/dist/allow-CixonwTW.d.ts +0 -59
- package/dist/allow-DX5cehSc.js +0 -63
- package/dist/base-DRutbxgL.js +0 -422
- package/dist/code-DJxdFR7p.d.ts +0 -212
- package/dist/core-BZHEAefX.d.ts +0 -129
- package/dist/core-CDM5o4rs.js +0 -498
- package/dist/error-CWAdNAzm.d.ts +0 -243
- package/dist/error-DgAKK7b2.js +0 -237
- package/dist/form-6XKM_cOk.js +0 -61
- package/dist/icon-Ci5uqGB_.js +0 -192
- package/dist/keys-EEfxEGfO.js +0 -140
- package/dist/oauth2-B7-6Z7Lc.js +0 -155
- package/dist/oauth2-CXHukHf2.d.ts +0 -176
- package/dist/password-C4KLmO0O.d.ts +0 -385
- package/dist/pkce-276Za_rZ.js +0 -162
- package/dist/provider-tndlqCzp.d.ts +0 -227
- package/dist/random-SXMYlaVr.js +0 -87
- package/dist/select-BjySLL8I.js +0 -280
- package/dist/storage-BEaqEPNQ.js +0 -62
- package/dist/storage-CxKerLlc.d.ts +0 -162
- package/dist/subject-DMIMVtaT.d.ts +0 -62
- package/dist/theme-C9by7VXf.d.ts +0 -209
- package/dist/theme-CswaLtbW.js +0 -120
- package/dist/util-CSdHUFOo.js +0 -108
- package/dist/util-DbSKG1Xm.d.ts +0 -72
package/dist/error.d.ts
CHANGED
|
@@ -1,2 +1,243 @@
|
|
|
1
|
-
|
|
1
|
+
//#region src/error.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Error classes and types for Draft Auth operations.
|
|
4
|
+
* Provides comprehensive error handling for OAuth 2.0 and authentication flows.
|
|
5
|
+
*
|
|
6
|
+
* ## Usage
|
|
7
|
+
*
|
|
8
|
+
* ```ts
|
|
9
|
+
* import {
|
|
10
|
+
* InvalidAuthorizationCodeError,
|
|
11
|
+
* OauthError,
|
|
12
|
+
* UnknownStateError
|
|
13
|
+
* } from "@draftlab/auth/error"
|
|
14
|
+
*
|
|
15
|
+
* try {
|
|
16
|
+
* await client.exchange(code, redirectUri)
|
|
17
|
+
* } catch (error) {
|
|
18
|
+
* if (error instanceof InvalidAuthorizationCodeError) {
|
|
19
|
+
* // Handle invalid authorization code
|
|
20
|
+
* // Authorization code expired or invalid
|
|
21
|
+
* } else if (error instanceof OauthError) {
|
|
22
|
+
* // Handle OAuth-specific errors
|
|
23
|
+
* // OAuth error: error.error - error.description
|
|
24
|
+
* }
|
|
25
|
+
* }
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* ## Error Categories
|
|
29
|
+
*
|
|
30
|
+
* - **OAuth Errors**: Standard OAuth error responses
|
|
31
|
+
* - **Token Errors**: Issues with access tokens, refresh tokens, and authorization codes
|
|
32
|
+
* - **Client Errors**: Problems with client configuration and authorization
|
|
33
|
+
* - **State Errors**: Session and flow state management issues
|
|
34
|
+
*
|
|
35
|
+
* @packageDocumentation
|
|
36
|
+
*/
|
|
37
|
+
/**
|
|
38
|
+
* Standard OAuth error types
|
|
39
|
+
* These error codes are returned by OAuth authorization servers.
|
|
40
|
+
*/
|
|
41
|
+
type OauthErrorType = "invalid_request" | "invalid_client" | "invalid_grant" | "invalid_token" | "invalid_redirect_uri" | "insufficient_scope" | "unauthorized_client" | "access_denied" | "unsupported_grant_type" | "server_error" | "temporarily_unavailable" | "unsupported_response_type";
|
|
42
|
+
/**
|
|
43
|
+
* Base OAuth error class for handling standard OAuth error responses.
|
|
44
|
+
* Contains both the error code and human-readable description.
|
|
45
|
+
*/
|
|
46
|
+
declare class OauthError extends Error {
|
|
47
|
+
/** The OAuth error code as defined in the specification */
|
|
48
|
+
readonly error: OauthErrorType;
|
|
49
|
+
/** Human-readable description of the error */
|
|
50
|
+
readonly description: string;
|
|
51
|
+
/**
|
|
52
|
+
* Creates a new OAuth error with the specified error code and description.
|
|
53
|
+
*
|
|
54
|
+
* @param error - The OAuth error type
|
|
55
|
+
* @param description - Human-readable error description
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```ts
|
|
59
|
+
* throw new OauthError("invalid_grant", "Authorization code has expired")
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
constructor(error: OauthErrorType, description: string);
|
|
63
|
+
/**
|
|
64
|
+
* Converts the error to a standard OAuth JSON response format.
|
|
65
|
+
*
|
|
66
|
+
* @returns Object with error and error_description fields
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```ts
|
|
70
|
+
* const oauthError = new OauthError("invalid_request", "Missing parameter")
|
|
71
|
+
* return c.json(oauthError.toJSON(), 400)
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
toJSON(): {
|
|
75
|
+
error: OauthErrorType;
|
|
76
|
+
error_description: string;
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Error thrown when a provider parameter is missing from the authorization request.
|
|
81
|
+
* Occurs when multiple providers are configured but no specific provider is selected.
|
|
82
|
+
*/
|
|
83
|
+
declare class MissingProviderError extends OauthError {
|
|
84
|
+
/**
|
|
85
|
+
* Creates a missing provider error.
|
|
86
|
+
* Thrown when the provider query parameter is required but not provided.
|
|
87
|
+
*/
|
|
88
|
+
constructor();
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Error thrown when a required parameter is missing from a request.
|
|
92
|
+
* Used for validating OAuth request parameters.
|
|
93
|
+
*/
|
|
94
|
+
declare class MissingParameterError extends OauthError {
|
|
95
|
+
/** The name of the missing parameter */
|
|
96
|
+
readonly parameter: string;
|
|
97
|
+
/**
|
|
98
|
+
* Creates a missing parameter error.
|
|
99
|
+
*
|
|
100
|
+
* @param parameter - The name of the missing parameter
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* ```ts
|
|
104
|
+
* throw new MissingParameterError("client_id")
|
|
105
|
+
* ```
|
|
106
|
+
*/
|
|
107
|
+
constructor(parameter: string);
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Error thrown when a client is not authorized to use a specific redirect URI.
|
|
111
|
+
* Prevents unauthorized clients from hijacking authorization codes.
|
|
112
|
+
*/
|
|
113
|
+
declare class UnauthorizedClientError extends OauthError {
|
|
114
|
+
/** The client ID that attempted unauthorized access */
|
|
115
|
+
readonly clientID: string;
|
|
116
|
+
/**
|
|
117
|
+
* Creates an unauthorized client error.
|
|
118
|
+
*
|
|
119
|
+
* @param clientID - The client ID attempting unauthorized access
|
|
120
|
+
* @param redirectURI - The unauthorized redirect URI
|
|
121
|
+
*
|
|
122
|
+
* @example
|
|
123
|
+
* ```ts
|
|
124
|
+
* throw new UnauthorizedClientError("malicious-client", "https://evil.com/callback")
|
|
125
|
+
* ```
|
|
126
|
+
*/
|
|
127
|
+
constructor(clientID: string, redirectURI: string);
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Error thrown when the authentication flow is in an unknown or invalid state.
|
|
131
|
+
*
|
|
132
|
+
* ## Common Causes
|
|
133
|
+
* - Session cookies have expired during the authentication flow
|
|
134
|
+
* - User switched browsers or devices mid-flow
|
|
135
|
+
* - Authentication state was manually tampered with
|
|
136
|
+
* - Server session storage was cleared
|
|
137
|
+
*
|
|
138
|
+
* @example
|
|
139
|
+
* ```ts
|
|
140
|
+
* // In provider callback handling
|
|
141
|
+
* const state = await getAuthState(request)
|
|
142
|
+
* if (!state) {
|
|
143
|
+
* throw new UnknownStateError()
|
|
144
|
+
* }
|
|
145
|
+
* ```
|
|
146
|
+
*/
|
|
147
|
+
declare class UnknownStateError extends Error {
|
|
148
|
+
/**
|
|
149
|
+
* Creates an unknown state error.
|
|
150
|
+
* Indicates that the authentication flow cannot continue due to missing state.
|
|
151
|
+
*/
|
|
152
|
+
constructor();
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Error thrown when a subject (user identifier) is invalid or malformed.
|
|
156
|
+
* Used during token verification and subject validation.
|
|
157
|
+
*
|
|
158
|
+
* @example
|
|
159
|
+
* ```ts
|
|
160
|
+
* // During token verification
|
|
161
|
+
* const subject = extractSubject(token)
|
|
162
|
+
* if (!isValidSubject(subject)) {
|
|
163
|
+
* throw new InvalidSubjectError()
|
|
164
|
+
* }
|
|
165
|
+
* ```
|
|
166
|
+
*/
|
|
167
|
+
declare class InvalidSubjectError extends Error {
|
|
168
|
+
/**
|
|
169
|
+
* Creates an invalid subject error.
|
|
170
|
+
*/
|
|
171
|
+
constructor();
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Error thrown when a refresh token is invalid, expired, or revoked.
|
|
175
|
+
* Occurs during token refresh operations.
|
|
176
|
+
*
|
|
177
|
+
* @example
|
|
178
|
+
* ```ts
|
|
179
|
+
* // During token refresh
|
|
180
|
+
* try {
|
|
181
|
+
* const newTokens = await client.refresh(refreshToken)
|
|
182
|
+
* } catch (error) {
|
|
183
|
+
* if (error instanceof InvalidRefreshTokenError) {
|
|
184
|
+
* // Redirect user to login again
|
|
185
|
+
* redirectToLogin()
|
|
186
|
+
* }
|
|
187
|
+
* }
|
|
188
|
+
* ```
|
|
189
|
+
*/
|
|
190
|
+
declare class InvalidRefreshTokenError extends Error {
|
|
191
|
+
/**
|
|
192
|
+
* Creates an invalid refresh token error.
|
|
193
|
+
*/
|
|
194
|
+
constructor();
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Error thrown when an access token is invalid, expired, or malformed.
|
|
198
|
+
* Occurs during token verification and API requests.
|
|
199
|
+
*
|
|
200
|
+
* @example
|
|
201
|
+
* ```ts
|
|
202
|
+
* // During API request
|
|
203
|
+
* try {
|
|
204
|
+
* const user = await api.getUser(accessToken)
|
|
205
|
+
* } catch (error) {
|
|
206
|
+
* if (error instanceof InvalidAccessTokenError) {
|
|
207
|
+
* // Try to refresh the token
|
|
208
|
+
* await refreshAccessToken()
|
|
209
|
+
* }
|
|
210
|
+
* }
|
|
211
|
+
* ```
|
|
212
|
+
*/
|
|
213
|
+
declare class InvalidAccessTokenError extends Error {
|
|
214
|
+
/**
|
|
215
|
+
* Creates an invalid access token error.
|
|
216
|
+
*/
|
|
217
|
+
constructor();
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Error thrown when an authorization code is invalid, expired, or already used.
|
|
221
|
+
* Occurs during the token exchange step of the OAuth flow.
|
|
222
|
+
*
|
|
223
|
+
* @example
|
|
224
|
+
* ```ts
|
|
225
|
+
* // During authorization code exchange
|
|
226
|
+
* try {
|
|
227
|
+
* const tokens = await client.exchange(code, redirectUri)
|
|
228
|
+
* } catch (error) {
|
|
229
|
+
* if (error instanceof InvalidAuthorizationCodeError) {
|
|
230
|
+
* // Code may have expired or been used already
|
|
231
|
+
* redirectToAuthorize()
|
|
232
|
+
* }
|
|
233
|
+
* }
|
|
234
|
+
* ```
|
|
235
|
+
*/
|
|
236
|
+
declare class InvalidAuthorizationCodeError extends Error {
|
|
237
|
+
/**
|
|
238
|
+
* Creates an invalid authorization code error.
|
|
239
|
+
*/
|
|
240
|
+
constructor();
|
|
241
|
+
}
|
|
242
|
+
//#endregion
|
|
2
243
|
export { InvalidAccessTokenError, InvalidAuthorizationCodeError, InvalidRefreshTokenError, InvalidSubjectError, MissingParameterError, MissingProviderError, OauthError, OauthErrorType, UnauthorizedClientError, UnknownStateError };
|
package/dist/error.js
CHANGED
|
@@ -1,3 +1,237 @@
|
|
|
1
|
-
|
|
1
|
+
//#region src/error.ts
|
|
2
|
+
/**
|
|
3
|
+
* Base OAuth error class for handling standard OAuth error responses.
|
|
4
|
+
* Contains both the error code and human-readable description.
|
|
5
|
+
*/
|
|
6
|
+
var OauthError = class extends Error {
|
|
7
|
+
/** The OAuth error code as defined in the specification */
|
|
8
|
+
error;
|
|
9
|
+
/** Human-readable description of the error */
|
|
10
|
+
description;
|
|
11
|
+
/**
|
|
12
|
+
* Creates a new OAuth error with the specified error code and description.
|
|
13
|
+
*
|
|
14
|
+
* @param error - The OAuth error type
|
|
15
|
+
* @param description - Human-readable error description
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```ts
|
|
19
|
+
* throw new OauthError("invalid_grant", "Authorization code has expired")
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
constructor(error, description) {
|
|
23
|
+
super(`${error} - ${description}`);
|
|
24
|
+
this.name = "OauthError";
|
|
25
|
+
this.error = error;
|
|
26
|
+
this.description = description;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Converts the error to a standard OAuth JSON response format.
|
|
30
|
+
*
|
|
31
|
+
* @returns Object with error and error_description fields
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```ts
|
|
35
|
+
* const oauthError = new OauthError("invalid_request", "Missing parameter")
|
|
36
|
+
* return c.json(oauthError.toJSON(), 400)
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
toJSON() {
|
|
40
|
+
return {
|
|
41
|
+
error: this.error,
|
|
42
|
+
error_description: this.description
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Error thrown when a provider parameter is missing from the authorization request.
|
|
48
|
+
* Occurs when multiple providers are configured but no specific provider is selected.
|
|
49
|
+
*/
|
|
50
|
+
var MissingProviderError = class extends OauthError {
|
|
51
|
+
/**
|
|
52
|
+
* Creates a missing provider error.
|
|
53
|
+
* Thrown when the provider query parameter is required but not provided.
|
|
54
|
+
*/
|
|
55
|
+
constructor() {
|
|
56
|
+
super("invalid_request", "Must specify `provider` query parameter if `select` callback on issuer is not specified");
|
|
57
|
+
this.name = "MissingProviderError";
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Error thrown when a required parameter is missing from a request.
|
|
62
|
+
* Used for validating OAuth request parameters.
|
|
63
|
+
*/
|
|
64
|
+
var MissingParameterError = class extends OauthError {
|
|
65
|
+
/** The name of the missing parameter */
|
|
66
|
+
parameter;
|
|
67
|
+
/**
|
|
68
|
+
* Creates a missing parameter error.
|
|
69
|
+
*
|
|
70
|
+
* @param parameter - The name of the missing parameter
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
* ```ts
|
|
74
|
+
* throw new MissingParameterError("client_id")
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
constructor(parameter) {
|
|
78
|
+
super("invalid_request", `Missing parameter: ${parameter}`);
|
|
79
|
+
this.name = "MissingParameterError";
|
|
80
|
+
this.parameter = parameter;
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* Error thrown when a client is not authorized to use a specific redirect URI.
|
|
85
|
+
* Prevents unauthorized clients from hijacking authorization codes.
|
|
86
|
+
*/
|
|
87
|
+
var UnauthorizedClientError = class extends OauthError {
|
|
88
|
+
/** The client ID that attempted unauthorized access */
|
|
89
|
+
clientID;
|
|
90
|
+
/**
|
|
91
|
+
* Creates an unauthorized client error.
|
|
92
|
+
*
|
|
93
|
+
* @param clientID - The client ID attempting unauthorized access
|
|
94
|
+
* @param redirectURI - The unauthorized redirect URI
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* ```ts
|
|
98
|
+
* throw new UnauthorizedClientError("malicious-client", "https://evil.com/callback")
|
|
99
|
+
* ```
|
|
100
|
+
*/
|
|
101
|
+
constructor(clientID, redirectURI) {
|
|
102
|
+
super("unauthorized_client", `Client ${clientID} is not authorized to use this redirect_uri: ${redirectURI}`);
|
|
103
|
+
this.name = "UnauthorizedClientError";
|
|
104
|
+
this.clientID = clientID;
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
/**
|
|
108
|
+
* Error thrown when the authentication flow is in an unknown or invalid state.
|
|
109
|
+
*
|
|
110
|
+
* ## Common Causes
|
|
111
|
+
* - Session cookies have expired during the authentication flow
|
|
112
|
+
* - User switched browsers or devices mid-flow
|
|
113
|
+
* - Authentication state was manually tampered with
|
|
114
|
+
* - Server session storage was cleared
|
|
115
|
+
*
|
|
116
|
+
* @example
|
|
117
|
+
* ```ts
|
|
118
|
+
* // In provider callback handling
|
|
119
|
+
* const state = await getAuthState(request)
|
|
120
|
+
* if (!state) {
|
|
121
|
+
* throw new UnknownStateError()
|
|
122
|
+
* }
|
|
123
|
+
* ```
|
|
124
|
+
*/
|
|
125
|
+
var UnknownStateError = class extends Error {
|
|
126
|
+
/**
|
|
127
|
+
* Creates an unknown state error.
|
|
128
|
+
* Indicates that the authentication flow cannot continue due to missing state.
|
|
129
|
+
*/
|
|
130
|
+
constructor() {
|
|
131
|
+
super("The browser was in an unknown state. This could be because certain cookies expired or the browser was switched in the middle of an authentication flow.");
|
|
132
|
+
this.name = "UnknownStateError";
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
/**
|
|
136
|
+
* Error thrown when a subject (user identifier) is invalid or malformed.
|
|
137
|
+
* Used during token verification and subject validation.
|
|
138
|
+
*
|
|
139
|
+
* @example
|
|
140
|
+
* ```ts
|
|
141
|
+
* // During token verification
|
|
142
|
+
* const subject = extractSubject(token)
|
|
143
|
+
* if (!isValidSubject(subject)) {
|
|
144
|
+
* throw new InvalidSubjectError()
|
|
145
|
+
* }
|
|
146
|
+
* ```
|
|
147
|
+
*/
|
|
148
|
+
var InvalidSubjectError = class extends Error {
|
|
149
|
+
/**
|
|
150
|
+
* Creates an invalid subject error.
|
|
151
|
+
*/
|
|
152
|
+
constructor() {
|
|
153
|
+
super("Invalid subject");
|
|
154
|
+
this.name = "InvalidSubjectError";
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
/**
|
|
158
|
+
* Error thrown when a refresh token is invalid, expired, or revoked.
|
|
159
|
+
* Occurs during token refresh operations.
|
|
160
|
+
*
|
|
161
|
+
* @example
|
|
162
|
+
* ```ts
|
|
163
|
+
* // During token refresh
|
|
164
|
+
* try {
|
|
165
|
+
* const newTokens = await client.refresh(refreshToken)
|
|
166
|
+
* } catch (error) {
|
|
167
|
+
* if (error instanceof InvalidRefreshTokenError) {
|
|
168
|
+
* // Redirect user to login again
|
|
169
|
+
* redirectToLogin()
|
|
170
|
+
* }
|
|
171
|
+
* }
|
|
172
|
+
* ```
|
|
173
|
+
*/
|
|
174
|
+
var InvalidRefreshTokenError = class extends Error {
|
|
175
|
+
/**
|
|
176
|
+
* Creates an invalid refresh token error.
|
|
177
|
+
*/
|
|
178
|
+
constructor() {
|
|
179
|
+
super("Invalid refresh token");
|
|
180
|
+
this.name = "InvalidRefreshTokenError";
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
/**
|
|
184
|
+
* Error thrown when an access token is invalid, expired, or malformed.
|
|
185
|
+
* Occurs during token verification and API requests.
|
|
186
|
+
*
|
|
187
|
+
* @example
|
|
188
|
+
* ```ts
|
|
189
|
+
* // During API request
|
|
190
|
+
* try {
|
|
191
|
+
* const user = await api.getUser(accessToken)
|
|
192
|
+
* } catch (error) {
|
|
193
|
+
* if (error instanceof InvalidAccessTokenError) {
|
|
194
|
+
* // Try to refresh the token
|
|
195
|
+
* await refreshAccessToken()
|
|
196
|
+
* }
|
|
197
|
+
* }
|
|
198
|
+
* ```
|
|
199
|
+
*/
|
|
200
|
+
var InvalidAccessTokenError = class extends Error {
|
|
201
|
+
/**
|
|
202
|
+
* Creates an invalid access token error.
|
|
203
|
+
*/
|
|
204
|
+
constructor() {
|
|
205
|
+
super("Invalid access token");
|
|
206
|
+
this.name = "InvalidAccessTokenError";
|
|
207
|
+
}
|
|
208
|
+
};
|
|
209
|
+
/**
|
|
210
|
+
* Error thrown when an authorization code is invalid, expired, or already used.
|
|
211
|
+
* Occurs during the token exchange step of the OAuth flow.
|
|
212
|
+
*
|
|
213
|
+
* @example
|
|
214
|
+
* ```ts
|
|
215
|
+
* // During authorization code exchange
|
|
216
|
+
* try {
|
|
217
|
+
* const tokens = await client.exchange(code, redirectUri)
|
|
218
|
+
* } catch (error) {
|
|
219
|
+
* if (error instanceof InvalidAuthorizationCodeError) {
|
|
220
|
+
* // Code may have expired or been used already
|
|
221
|
+
* redirectToAuthorize()
|
|
222
|
+
* }
|
|
223
|
+
* }
|
|
224
|
+
* ```
|
|
225
|
+
*/
|
|
226
|
+
var InvalidAuthorizationCodeError = class extends Error {
|
|
227
|
+
/**
|
|
228
|
+
* Creates an invalid authorization code error.
|
|
229
|
+
*/
|
|
230
|
+
constructor() {
|
|
231
|
+
super("Invalid authorization code");
|
|
232
|
+
this.name = "InvalidAuthorizationCodeError";
|
|
233
|
+
}
|
|
234
|
+
};
|
|
2
235
|
|
|
236
|
+
//#endregion
|
|
3
237
|
export { InvalidAccessTokenError, InvalidAuthorizationCodeError, InvalidRefreshTokenError, InvalidSubjectError, MissingParameterError, MissingProviderError, OauthError, UnauthorizedClientError, UnknownStateError };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,2 @@
|
|
|
1
|
-
import "./
|
|
2
|
-
import "./error-CWAdNAzm.js";
|
|
3
|
-
import "./util-DbSKG1Xm.js";
|
|
4
|
-
import "./subject-DMIMVtaT.js";
|
|
5
|
-
import "./storage-CxKerLlc.js";
|
|
6
|
-
import "./provider-tndlqCzp.js";
|
|
7
|
-
import "./theme-C9by7VXf.js";
|
|
8
|
-
import { issuer } from "./core-BZHEAefX.js";
|
|
1
|
+
import { issuer } from "./core.js";
|
|
9
2
|
export { issuer };
|
package/dist/index.js
CHANGED
|
@@ -1,14 +1,3 @@
|
|
|
1
|
-
import "./
|
|
2
|
-
import "./allow-DX5cehSc.js";
|
|
3
|
-
import "./error-DgAKK7b2.js";
|
|
4
|
-
import "./pkce-276Za_rZ.js";
|
|
5
|
-
import "./random-SXMYlaVr.js";
|
|
6
|
-
import "./storage-BEaqEPNQ.js";
|
|
7
|
-
import "./keys-EEfxEGfO.js";
|
|
8
|
-
import "./theme-CswaLtbW.js";
|
|
9
|
-
import "./base-DRutbxgL.js";
|
|
10
|
-
import "./icon-Ci5uqGB_.js";
|
|
11
|
-
import "./select-BjySLL8I.js";
|
|
12
|
-
import { issuer } from "./core-CDM5o4rs.js";
|
|
1
|
+
import { issuer } from "./core.js";
|
|
13
2
|
|
|
14
3
|
export { issuer };
|
package/dist/keys.d.ts
CHANGED
package/dist/keys.js
CHANGED
|
@@ -1,5 +1,140 @@
|
|
|
1
|
-
import "./random
|
|
2
|
-
import "./storage
|
|
3
|
-
import {
|
|
1
|
+
import { generateSecureToken } from "./random.js";
|
|
2
|
+
import { Storage } from "./storage/storage.js";
|
|
3
|
+
import { exportJWK, exportPKCS8, exportSPKI, generateKeyPair, importPKCS8, importSPKI } from "jose";
|
|
4
4
|
|
|
5
|
+
//#region src/keys.ts
|
|
6
|
+
/**
|
|
7
|
+
* Cryptographic key management for JWT signing and encryption operations.
|
|
8
|
+
* Handles automatic key generation, rotation, and storage for OAuth operations.
|
|
9
|
+
*/
|
|
10
|
+
/** Elliptic Curve algorithm used for JWT signing operations */
|
|
11
|
+
const signingAlg = "ES256";
|
|
12
|
+
/** RSA algorithm used for token encryption operations */
|
|
13
|
+
const encryptionAlg = "RSA-OAEP-512";
|
|
14
|
+
/**
|
|
15
|
+
* Loads or generates signing keys for JWT operations.
|
|
16
|
+
* Returns existing valid keys, or generates new ones if none are available.
|
|
17
|
+
* Keys are automatically sorted by creation date (newest first).
|
|
18
|
+
*
|
|
19
|
+
* @param storage - Storage adapter for persistent key storage
|
|
20
|
+
* @returns Promise resolving to array of available signing key pairs
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```ts
|
|
24
|
+
* const keys = await signingKeys(storage)
|
|
25
|
+
* const currentKey = keys[0] // Most recent key
|
|
26
|
+
*
|
|
27
|
+
* // Use for JWT signing
|
|
28
|
+
* const jwt = await new SignJWT(payload)
|
|
29
|
+
* .setProtectedHeader({ alg: currentKey.alg, kid: currentKey.id })
|
|
30
|
+
* .sign(currentKey.private)
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
const signingKeys = async (storage) => {
|
|
34
|
+
const results = [];
|
|
35
|
+
const scanner = Storage.scan(storage, ["signing:key"]);
|
|
36
|
+
for await (const [, value] of scanner) try {
|
|
37
|
+
const publicKey = await importSPKI(value.publicKey, value.alg, { extractable: true });
|
|
38
|
+
const privateKey = await importPKCS8(value.privateKey, value.alg);
|
|
39
|
+
const jwk$1 = await exportJWK(publicKey);
|
|
40
|
+
jwk$1.kid = value.id;
|
|
41
|
+
jwk$1.use = "sig";
|
|
42
|
+
results.push({
|
|
43
|
+
id: value.id,
|
|
44
|
+
alg: signingAlg,
|
|
45
|
+
created: new Date(value.created),
|
|
46
|
+
expired: value.expired ? new Date(value.expired) : void 0,
|
|
47
|
+
public: publicKey,
|
|
48
|
+
private: privateKey,
|
|
49
|
+
jwk: jwk$1
|
|
50
|
+
});
|
|
51
|
+
} catch {}
|
|
52
|
+
results.sort((a, b) => b.created.getTime() - a.created.getTime());
|
|
53
|
+
if (results.filter((item) => !item.expired).length) return results;
|
|
54
|
+
const key = await generateKeyPair(signingAlg, { extractable: true });
|
|
55
|
+
const serialized = {
|
|
56
|
+
id: generateSecureToken(16),
|
|
57
|
+
publicKey: await exportSPKI(key.publicKey),
|
|
58
|
+
privateKey: await exportPKCS8(key.privateKey),
|
|
59
|
+
created: Date.now(),
|
|
60
|
+
alg: signingAlg
|
|
61
|
+
};
|
|
62
|
+
await Storage.set(storage, ["signing:key", serialized.id], serialized);
|
|
63
|
+
const jwk = await exportJWK(key.publicKey);
|
|
64
|
+
jwk.kid = serialized.id;
|
|
65
|
+
jwk.use = "sig";
|
|
66
|
+
const newKeyPair = {
|
|
67
|
+
id: serialized.id,
|
|
68
|
+
alg: signingAlg,
|
|
69
|
+
created: new Date(serialized.created),
|
|
70
|
+
expired: serialized.expired ? new Date(serialized.expired) : void 0,
|
|
71
|
+
public: key.publicKey,
|
|
72
|
+
private: key.privateKey,
|
|
73
|
+
jwk
|
|
74
|
+
};
|
|
75
|
+
return [newKeyPair, ...results];
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* Loads or generates encryption keys for token encryption operations.
|
|
79
|
+
* Returns existing valid keys, or generates new ones if none are available.
|
|
80
|
+
* Keys are automatically sorted by creation date (newest first).
|
|
81
|
+
*
|
|
82
|
+
* @param storage - Storage adapter for persistent key storage
|
|
83
|
+
* @returns Promise resolving to array of available encryption key pairs
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* ```ts
|
|
87
|
+
* const keys = await encryptionKeys(storage)
|
|
88
|
+
* const currentKey = keys[0] // Most recent key
|
|
89
|
+
*
|
|
90
|
+
* // Use for token encryption
|
|
91
|
+
* const encrypted = await new EncryptJWT(payload)
|
|
92
|
+
* .setProtectedHeader({ alg: 'RSA-OAEP-512', enc: 'A256GCM' })
|
|
93
|
+
* .encrypt(currentKey.public)
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
const encryptionKeys = async (storage) => {
|
|
97
|
+
const results = [];
|
|
98
|
+
const scanner = Storage.scan(storage, ["encryption:key"]);
|
|
99
|
+
for await (const [, value] of scanner) try {
|
|
100
|
+
const publicKey = await importSPKI(value.publicKey, value.alg, { extractable: true });
|
|
101
|
+
const privateKey = await importPKCS8(value.privateKey, value.alg);
|
|
102
|
+
const jwk$1 = await exportJWK(publicKey);
|
|
103
|
+
jwk$1.kid = value.id;
|
|
104
|
+
results.push({
|
|
105
|
+
id: value.id,
|
|
106
|
+
alg: encryptionAlg,
|
|
107
|
+
created: new Date(value.created),
|
|
108
|
+
expired: value.expired ? new Date(value.expired) : void 0,
|
|
109
|
+
public: publicKey,
|
|
110
|
+
private: privateKey,
|
|
111
|
+
jwk: jwk$1
|
|
112
|
+
});
|
|
113
|
+
} catch {}
|
|
114
|
+
results.sort((a, b) => b.created.getTime() - a.created.getTime());
|
|
115
|
+
if (results.filter((item) => !item.expired).length) return results;
|
|
116
|
+
const key = await generateKeyPair(encryptionAlg, { extractable: true });
|
|
117
|
+
const serialized = {
|
|
118
|
+
id: generateSecureToken(16),
|
|
119
|
+
publicKey: await exportSPKI(key.publicKey),
|
|
120
|
+
privateKey: await exportPKCS8(key.privateKey),
|
|
121
|
+
created: Date.now(),
|
|
122
|
+
alg: encryptionAlg
|
|
123
|
+
};
|
|
124
|
+
await Storage.set(storage, ["encryption:key", serialized.id], serialized);
|
|
125
|
+
const jwk = await exportJWK(key.publicKey);
|
|
126
|
+
jwk.kid = serialized.id;
|
|
127
|
+
const newKeyPair = {
|
|
128
|
+
id: serialized.id,
|
|
129
|
+
alg: encryptionAlg,
|
|
130
|
+
created: new Date(serialized.created),
|
|
131
|
+
expired: serialized.expired ? new Date(serialized.expired) : void 0,
|
|
132
|
+
public: key.publicKey,
|
|
133
|
+
private: key.privateKey,
|
|
134
|
+
jwk
|
|
135
|
+
};
|
|
136
|
+
return [newKeyPair, ...results];
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
//#endregion
|
|
5
140
|
export { encryptionKeys, signingKeys };
|