binoauth 0.0.11 → 0.0.13
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 +359 -165
- package/dist/core/src/admin/client.d.ts +203 -0
- package/dist/core/src/admin/client.d.ts.map +1 -0
- package/dist/core/src/admin/client.js +391 -0
- package/dist/core/src/admin/client.js.map +1 -0
- package/dist/core/src/admin/index.d.ts +6 -0
- package/dist/core/src/admin/index.d.ts.map +1 -0
- package/dist/core/src/admin/index.js +5 -0
- package/dist/core/src/admin/index.js.map +1 -0
- package/dist/core/src/admin/types.d.ts +412 -0
- package/dist/core/src/admin/types.d.ts.map +1 -0
- package/dist/core/src/admin/types.js +5 -0
- package/dist/core/src/admin/types.js.map +1 -0
- package/dist/core/src/auth/client.d.ts +330 -0
- package/dist/core/src/auth/client.d.ts.map +1 -0
- package/dist/core/src/auth/client.js +408 -0
- package/dist/core/src/auth/client.js.map +1 -0
- package/dist/core/src/auth/error.d.ts +113 -0
- package/dist/core/src/auth/error.d.ts.map +1 -0
- package/dist/core/src/auth/error.js +257 -0
- package/dist/core/src/auth/error.js.map +1 -0
- package/dist/core/src/auth/flows/base-flow.d.ts +98 -0
- package/dist/core/src/auth/flows/base-flow.d.ts.map +1 -0
- package/dist/core/src/auth/flows/base-flow.js +182 -0
- package/dist/core/src/auth/flows/base-flow.js.map +1 -0
- package/dist/core/src/auth/flows/magic-link.d.ts +175 -0
- package/dist/core/src/auth/flows/magic-link.d.ts.map +1 -0
- package/dist/core/src/auth/flows/magic-link.js +228 -0
- package/dist/core/src/auth/flows/magic-link.js.map +1 -0
- package/dist/core/src/auth/flows/mfa.d.ts +81 -0
- package/dist/core/src/auth/flows/mfa.d.ts.map +1 -0
- package/dist/core/src/auth/flows/mfa.js +103 -0
- package/dist/core/src/auth/flows/mfa.js.map +1 -0
- package/dist/core/src/auth/flows/otp.d.ts +172 -0
- package/dist/core/src/auth/flows/otp.d.ts.map +1 -0
- package/dist/core/src/auth/flows/otp.js +222 -0
- package/dist/core/src/auth/flows/otp.js.map +1 -0
- package/dist/core/src/auth/flows/password.d.ts +242 -0
- package/dist/core/src/auth/flows/password.d.ts.map +1 -0
- package/dist/core/src/auth/flows/password.js +344 -0
- package/dist/core/src/auth/flows/password.js.map +1 -0
- package/dist/core/src/auth/flows/social.d.ts +209 -0
- package/dist/core/src/auth/flows/social.d.ts.map +1 -0
- package/dist/core/src/auth/flows/social.js +284 -0
- package/dist/core/src/auth/flows/social.js.map +1 -0
- package/dist/core/src/auth/index.d.ts +19 -0
- package/dist/core/src/auth/index.d.ts.map +1 -0
- package/dist/core/src/auth/index.js +32 -0
- package/dist/core/src/auth/index.js.map +1 -0
- package/dist/core/src/auth/types.d.ts +151 -0
- package/dist/core/src/auth/types.d.ts.map +1 -0
- package/dist/core/src/auth/types.js +7 -0
- package/dist/core/src/auth/types.js.map +1 -0
- package/dist/core/src/index.d.ts +53 -49
- package/dist/core/src/index.d.ts.map +1 -1
- package/dist/core/src/index.js +61 -343
- package/dist/core/src/index.js.map +1 -1
- package/dist/core/src/oauth/client.d.ts +322 -0
- package/dist/core/src/oauth/client.d.ts.map +1 -0
- package/dist/core/src/oauth/client.js +491 -0
- package/dist/core/src/oauth/client.js.map +1 -0
- package/dist/core/src/oauth/error.d.ts +18 -0
- package/dist/core/src/oauth/error.d.ts.map +1 -0
- package/dist/core/src/oauth/error.js +24 -0
- package/dist/core/src/oauth/error.js.map +1 -0
- package/dist/core/src/oauth/flows/authorization-code.d.ts +122 -0
- package/dist/core/src/oauth/flows/authorization-code.d.ts.map +1 -0
- package/dist/core/src/oauth/flows/authorization-code.js +278 -0
- package/dist/core/src/oauth/flows/authorization-code.js.map +1 -0
- package/dist/core/src/oauth/flows/base-flow.d.ts +17 -0
- package/dist/core/src/oauth/flows/base-flow.d.ts.map +1 -0
- package/dist/core/src/oauth/flows/base-flow.js +107 -0
- package/dist/core/src/oauth/flows/base-flow.js.map +1 -0
- package/dist/core/src/oauth/flows/client-credentials.d.ts +72 -0
- package/dist/core/src/oauth/flows/client-credentials.d.ts.map +1 -0
- package/dist/core/src/oauth/flows/client-credentials.js +100 -0
- package/dist/core/src/oauth/flows/client-credentials.js.map +1 -0
- package/dist/core/src/oauth/flows/device-code.d.ts +108 -0
- package/dist/core/src/oauth/flows/device-code.d.ts.map +1 -0
- package/dist/core/src/oauth/flows/device-code.js +193 -0
- package/dist/core/src/oauth/flows/device-code.js.map +1 -0
- package/dist/core/src/oauth/flows/refresh-token.d.ts +59 -0
- package/dist/core/src/oauth/flows/refresh-token.d.ts.map +1 -0
- package/dist/core/src/oauth/flows/refresh-token.js +105 -0
- package/dist/core/src/oauth/flows/refresh-token.js.map +1 -0
- package/dist/core/src/oauth/index.d.ts +12 -0
- package/dist/core/src/oauth/index.d.ts.map +1 -0
- package/dist/core/src/oauth/index.js +11 -0
- package/dist/core/src/oauth/index.js.map +1 -0
- package/dist/core/src/oauth/storage/encryption.d.ts +12 -0
- package/dist/core/src/oauth/storage/encryption.d.ts.map +1 -0
- package/dist/core/src/oauth/storage/encryption.js +76 -0
- package/dist/core/src/oauth/storage/encryption.js.map +1 -0
- package/dist/core/src/oauth/storage/index.d.ts +201 -0
- package/dist/core/src/oauth/storage/index.d.ts.map +1 -0
- package/dist/core/src/oauth/storage/index.js +322 -0
- package/dist/core/src/oauth/storage/index.js.map +1 -0
- package/dist/core/src/oauth/storage/strategies.d.ts +34 -0
- package/dist/core/src/oauth/storage/strategies.d.ts.map +1 -0
- package/dist/core/src/oauth/storage/strategies.js +100 -0
- package/dist/core/src/oauth/storage/strategies.js.map +1 -0
- package/dist/core/src/oauth/types.d.ts +261 -0
- package/dist/core/src/oauth/types.d.ts.map +1 -0
- package/dist/core/src/oauth/types.js +39 -0
- package/dist/core/src/oauth/types.js.map +1 -0
- package/dist/core/src/oauth/utils.d.ts +56 -0
- package/dist/core/src/oauth/utils.d.ts.map +1 -0
- package/dist/core/src/oauth/utils.js +140 -0
- package/dist/core/src/oauth/utils.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
@@ -0,0 +1,261 @@
|
|
1
|
+
/**
|
2
|
+
* User information returned from the userinfo endpoint
|
3
|
+
*
|
4
|
+
* Contains standard OpenID Connect user claims along with BinoAuth-specific fields.
|
5
|
+
*
|
6
|
+
* @example
|
7
|
+
* ```typescript
|
8
|
+
* const userInfo = await client.getUserInfo();
|
9
|
+
* console.log(`Welcome, ${userInfo.name}!`);
|
10
|
+
* console.log(`Email: ${userInfo.email} (verified: ${userInfo.email_verified})`);
|
11
|
+
* ```
|
12
|
+
*/
|
13
|
+
export interface User {
|
14
|
+
sub: string;
|
15
|
+
username: string;
|
16
|
+
email: string;
|
17
|
+
name?: string;
|
18
|
+
email_verified?: boolean;
|
19
|
+
picture?: string;
|
20
|
+
given_name?: string;
|
21
|
+
family_name?: string;
|
22
|
+
}
|
23
|
+
/**
|
24
|
+
* Simplified BinoAuth configuration using issuer URL
|
25
|
+
*
|
26
|
+
* This is the recommended configuration approach that automatically constructs
|
27
|
+
* all necessary OAuth endpoints from the issuer URL.
|
28
|
+
*
|
29
|
+
* @example
|
30
|
+
* ```typescript
|
31
|
+
* const config: BinoAuthConfig = {
|
32
|
+
* issuer: 'https://auth.binoauth.com',
|
33
|
+
* clientId: 'your_client_id',
|
34
|
+
* redirectUri: 'https://yourapp.com/auth/callback',
|
35
|
+
* scope: 'openid profile email read:users', // optional
|
36
|
+
* clientSecret: 'your_secret' // only for server-side apps
|
37
|
+
* };
|
38
|
+
*
|
39
|
+
* const client = new BinoAuthOAuth(config, storageConfig);
|
40
|
+
* ```
|
41
|
+
*/
|
42
|
+
export interface BinoAuthConfig {
|
43
|
+
/** BinoAuth server URL (e.g., 'https://auth.binoauth.com') */
|
44
|
+
issuer: string;
|
45
|
+
/** Your application's client ID */
|
46
|
+
clientId: string;
|
47
|
+
/** Callback URL after authentication */
|
48
|
+
redirectUri: string;
|
49
|
+
/** OAuth scopes (defaults to 'openid profile email') */
|
50
|
+
scope?: string;
|
51
|
+
/** Client secret (only for confidential clients) */
|
52
|
+
clientSecret?: string;
|
53
|
+
}
|
54
|
+
/**
|
55
|
+
* Full OAuth configuration with explicit endpoints
|
56
|
+
*
|
57
|
+
* Use this when you need fine-grained control over OAuth endpoints
|
58
|
+
* or when integrating with non-BinoAuth providers.
|
59
|
+
*
|
60
|
+
* @example
|
61
|
+
* ```typescript
|
62
|
+
* const config: AuthConfig = {
|
63
|
+
* clientId: 'your_client_id',
|
64
|
+
* authorizeEndpoint: 'https://auth.binoauth.com/api/v1/oauth/authorize',
|
65
|
+
* tokenEndpoint: 'https://auth.binoauth.com/api/v1/oauth/token',
|
66
|
+
* userInfoEndpoint: 'https://auth.binoauth.com/api/v1/oauth/userinfo',
|
67
|
+
* logoutEndpoint: 'https://auth.binoauth.com/api/v1/oauth/logout',
|
68
|
+
* revokeEndpoint: 'https://auth.binoauth.com/api/v1/oauth/revoke',
|
69
|
+
* redirectUri: 'https://yourapp.com/callback',
|
70
|
+
* scope: 'openid profile email',
|
71
|
+
* logoutPage: 'https://auth.binoauth.com/auth/logout'
|
72
|
+
* };
|
73
|
+
* ```
|
74
|
+
*/
|
75
|
+
export interface AuthConfig {
|
76
|
+
/** Your application's client ID */
|
77
|
+
clientId: string;
|
78
|
+
/** OAuth authorization endpoint URL */
|
79
|
+
authorizeEndpoint: string;
|
80
|
+
/** User information endpoint URL */
|
81
|
+
userInfoEndpoint: string;
|
82
|
+
/** Token exchange endpoint URL */
|
83
|
+
tokenEndpoint: string;
|
84
|
+
/** Logout endpoint URL */
|
85
|
+
logoutEndpoint: string;
|
86
|
+
/** Token revocation endpoint URL */
|
87
|
+
revokeEndpoint: string;
|
88
|
+
/** Callback URL after authentication */
|
89
|
+
redirectUri: string;
|
90
|
+
/** OAuth scopes */
|
91
|
+
scope: string;
|
92
|
+
/** Logout page URL */
|
93
|
+
logoutPage: string;
|
94
|
+
}
|
95
|
+
/**
|
96
|
+
* Creates full AuthConfig from simplified BinoAuthConfig
|
97
|
+
*
|
98
|
+
* Automatically constructs all OAuth endpoints from the issuer URL.
|
99
|
+
* This is used internally when you provide a BinoAuthConfig to the client.
|
100
|
+
*
|
101
|
+
* @param config - Simplified BinoAuth configuration
|
102
|
+
* @returns Full OAuth configuration with all endpoints
|
103
|
+
*
|
104
|
+
* @example
|
105
|
+
* ```typescript
|
106
|
+
* const binoConfig = {
|
107
|
+
* issuer: 'https://auth.binoauth.com',
|
108
|
+
* clientId: 'your_client_id',
|
109
|
+
* redirectUri: 'https://yourapp.com/callback'
|
110
|
+
* };
|
111
|
+
*
|
112
|
+
* const fullConfig = createAuthConfigFromIssuer(binoConfig);
|
113
|
+
* // Result includes all constructed endpoints:
|
114
|
+
* // authorizeEndpoint: 'https://auth.binoauth.com/api/v1/oauth/authorize'
|
115
|
+
* // tokenEndpoint: 'https://auth.binoauth.com/api/v1/oauth/token'
|
116
|
+
* // etc.
|
117
|
+
* ```
|
118
|
+
*/
|
119
|
+
export declare function createAuthConfigFromIssuer(config: BinoAuthConfig): AuthConfig;
|
120
|
+
/**
|
121
|
+
* OAuth token response from the authorization server
|
122
|
+
*
|
123
|
+
* @example
|
124
|
+
* ```typescript
|
125
|
+
* // Example token response:
|
126
|
+
* {
|
127
|
+
* access_token: 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...',
|
128
|
+
* refresh_token: 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...',
|
129
|
+
* id_token: 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...',
|
130
|
+
* expires_in: 3600,
|
131
|
+
* token_type: 'Bearer'
|
132
|
+
* }
|
133
|
+
* ```
|
134
|
+
*/
|
135
|
+
export interface TokenResponse {
|
136
|
+
access_token: string;
|
137
|
+
refresh_token?: string;
|
138
|
+
id_token?: string;
|
139
|
+
expires_in: number;
|
140
|
+
token_type: string;
|
141
|
+
}
|
142
|
+
/**
|
143
|
+
* Individual token with expiration information
|
144
|
+
*
|
145
|
+
* @example
|
146
|
+
* ```typescript
|
147
|
+
* const accessToken: Token = {
|
148
|
+
* value: 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...',
|
149
|
+
* expiresAt: Date.now() + 3600000 // 1 hour from now
|
150
|
+
* };
|
151
|
+
* ```
|
152
|
+
*/
|
153
|
+
export interface Token {
|
154
|
+
value: string;
|
155
|
+
expiresAt?: number;
|
156
|
+
}
|
157
|
+
/**
|
158
|
+
* Collection of OAuth tokens and temporary auth state
|
159
|
+
*
|
160
|
+
* Used internally by TokenStorage to manage all authentication tokens
|
161
|
+
* and temporary state (like PKCE verifiers and CSRF state).
|
162
|
+
*
|
163
|
+
* @example
|
164
|
+
* ```typescript
|
165
|
+
* const tokenSet: TokenSet = {
|
166
|
+
* accessToken: { value: 'access_token_jwt', expiresAt: 1234567890 },
|
167
|
+
* refreshToken: { value: 'refresh_token_jwt', expiresAt: 1234567890 },
|
168
|
+
* idToken: { value: 'id_token_jwt' }
|
169
|
+
* };
|
170
|
+
*
|
171
|
+
* await storage.setTokens(tokenSet);
|
172
|
+
* ```
|
173
|
+
*/
|
174
|
+
export interface TokenSet {
|
175
|
+
accessToken?: Token;
|
176
|
+
refreshToken?: Token;
|
177
|
+
idToken?: Token;
|
178
|
+
state?: Token;
|
179
|
+
verifier?: Token;
|
180
|
+
}
|
181
|
+
/**
|
182
|
+
* Configuration for token storage
|
183
|
+
*
|
184
|
+
* Controls how and where OAuth tokens are stored, with encryption support.
|
185
|
+
*
|
186
|
+
* @example
|
187
|
+
* ```typescript
|
188
|
+
* const storageConfig: StorageConfig = {
|
189
|
+
* prefix: 'myapp_auth', // Storage key prefix
|
190
|
+
* clientId: 'your_client_id',
|
191
|
+
* storage: 'localStorage', // or 'sessionStorage' or 'memory'
|
192
|
+
* encryptionKey: 'your-32-char-encryption-key-here!',
|
193
|
+
* secure: true // Enable additional security measures
|
194
|
+
* };
|
195
|
+
* ```
|
196
|
+
*/
|
197
|
+
export interface StorageConfig {
|
198
|
+
prefix?: string;
|
199
|
+
clientId?: string;
|
200
|
+
storage?: "memory" | "localStorage" | "sessionStorage";
|
201
|
+
encryptionKey: string;
|
202
|
+
secure?: boolean;
|
203
|
+
}
|
204
|
+
/**
|
205
|
+
* Storage strategy interface for custom storage implementations
|
206
|
+
*
|
207
|
+
* Implement this interface to create custom storage backends.
|
208
|
+
*
|
209
|
+
* @example
|
210
|
+
* ```typescript
|
211
|
+
* class CustomStorageStrategy implements StorageStrategy {
|
212
|
+
* getItem(key: string): string | null {
|
213
|
+
* // Your custom storage logic
|
214
|
+
* return customStorage.get(key);
|
215
|
+
* }
|
216
|
+
*
|
217
|
+
* setItem(key: string, value: string): void {
|
218
|
+
* customStorage.set(key, value);
|
219
|
+
* }
|
220
|
+
*
|
221
|
+
* removeItem(key: string): void {
|
222
|
+
* customStorage.delete(key);
|
223
|
+
* }
|
224
|
+
*
|
225
|
+
* clear(): void {
|
226
|
+
* customStorage.clear();
|
227
|
+
* }
|
228
|
+
* }
|
229
|
+
* ```
|
230
|
+
*/
|
231
|
+
export interface StorageStrategy {
|
232
|
+
getItem(key: string): string | null;
|
233
|
+
setItem(key: string, value: string): void;
|
234
|
+
removeItem(key: string): void;
|
235
|
+
clear(): void;
|
236
|
+
}
|
237
|
+
/**
|
238
|
+
* Response from device authorization request
|
239
|
+
*
|
240
|
+
* Contains the codes and URLs needed for device authorization flow.
|
241
|
+
*
|
242
|
+
* @example
|
243
|
+
* ```typescript
|
244
|
+
* const deviceAuth = await client.requestDeviceCode();
|
245
|
+
* console.log(`Visit: ${deviceAuth.verification_uri}`);
|
246
|
+
* console.log(`Enter code: ${deviceAuth.user_code}`);
|
247
|
+
* console.log(`Code expires in ${deviceAuth.expires_in} seconds`);
|
248
|
+
*
|
249
|
+
* // Poll every deviceAuth.interval seconds
|
250
|
+
* const pollInterval = deviceAuth.interval * 1000;
|
251
|
+
* ```
|
252
|
+
*/
|
253
|
+
export interface DeviceCodeResponse {
|
254
|
+
device_code: string;
|
255
|
+
user_code: string;
|
256
|
+
verification_uri: string;
|
257
|
+
verification_uri_complete?: string;
|
258
|
+
expires_in: number;
|
259
|
+
interval?: number;
|
260
|
+
}
|
261
|
+
//# sourceMappingURL=types.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/oauth/types.ts"],"names":[],"mappings":"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"}
|
@@ -0,0 +1,39 @@
|
|
1
|
+
/**
|
2
|
+
* Creates full AuthConfig from simplified BinoAuthConfig
|
3
|
+
*
|
4
|
+
* Automatically constructs all OAuth endpoints from the issuer URL.
|
5
|
+
* This is used internally when you provide a BinoAuthConfig to the client.
|
6
|
+
*
|
7
|
+
* @param config - Simplified BinoAuth configuration
|
8
|
+
* @returns Full OAuth configuration with all endpoints
|
9
|
+
*
|
10
|
+
* @example
|
11
|
+
* ```typescript
|
12
|
+
* const binoConfig = {
|
13
|
+
* issuer: 'https://auth.binoauth.com',
|
14
|
+
* clientId: 'your_client_id',
|
15
|
+
* redirectUri: 'https://yourapp.com/callback'
|
16
|
+
* };
|
17
|
+
*
|
18
|
+
* const fullConfig = createAuthConfigFromIssuer(binoConfig);
|
19
|
+
* // Result includes all constructed endpoints:
|
20
|
+
* // authorizeEndpoint: 'https://auth.binoauth.com/api/v1/oauth/authorize'
|
21
|
+
* // tokenEndpoint: 'https://auth.binoauth.com/api/v1/oauth/token'
|
22
|
+
* // etc.
|
23
|
+
* ```
|
24
|
+
*/
|
25
|
+
export function createAuthConfigFromIssuer(config) {
|
26
|
+
const issuer = config.issuer.endsWith('/') ? config.issuer.slice(0, -1) : config.issuer;
|
27
|
+
return {
|
28
|
+
clientId: config.clientId,
|
29
|
+
authorizeEndpoint: `${issuer}/api/v1/oauth/authorize`,
|
30
|
+
tokenEndpoint: `${issuer}/api/v1/oauth/token`,
|
31
|
+
userInfoEndpoint: `${issuer}/api/v1/oauth/userinfo`,
|
32
|
+
logoutEndpoint: `${issuer}/api/v1/oauth/logout`,
|
33
|
+
revokeEndpoint: `${issuer}/api/v1/oauth/revoke`,
|
34
|
+
redirectUri: config.redirectUri,
|
35
|
+
scope: config.scope || 'openid profile email',
|
36
|
+
logoutPage: `${issuer}/auth/logout`,
|
37
|
+
};
|
38
|
+
}
|
39
|
+
//# sourceMappingURL=types.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/oauth/types.ts"],"names":[],"mappings":"AAiGA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,UAAU,0BAA0B,CAAC,MAAsB;IAC/D,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC;IAExF,OAAO;QACL,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,iBAAiB,EAAE,GAAG,MAAM,yBAAyB;QACrD,aAAa,EAAE,GAAG,MAAM,qBAAqB;QAC7C,gBAAgB,EAAE,GAAG,MAAM,wBAAwB;QACnD,cAAc,EAAE,GAAG,MAAM,sBAAsB;QAC/C,cAAc,EAAE,GAAG,MAAM,sBAAsB;QAC/C,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,sBAAsB;QAC7C,UAAU,EAAE,GAAG,MAAM,cAAc;KACpC,CAAC;AACJ,CAAC"}
|
@@ -0,0 +1,56 @@
|
|
1
|
+
/**
|
2
|
+
* Generates a cryptographically secure random string
|
3
|
+
* @param length - The length of the string to generate
|
4
|
+
* @returns A random string
|
5
|
+
*/
|
6
|
+
export declare function generateSecureRandom(length: number): string;
|
7
|
+
/**
|
8
|
+
* Generates a PKCE code verifier
|
9
|
+
* @returns A code verifier string
|
10
|
+
*/
|
11
|
+
export declare function generateCodeVerifier(): string;
|
12
|
+
/**
|
13
|
+
* Generates a PKCE code challenge from a verifier
|
14
|
+
* @param verifier - The code verifier
|
15
|
+
* @returns A code challenge string
|
16
|
+
*/
|
17
|
+
export declare function generateCodeChallenge(verifier: string): Promise<string>;
|
18
|
+
/**
|
19
|
+
* Generates a PKCE code verifier and challenge pair
|
20
|
+
* @returns An object containing verifier and challenge
|
21
|
+
*/
|
22
|
+
export declare function generatePKCEPair(): Promise<{
|
23
|
+
verifier: string;
|
24
|
+
challenge: string;
|
25
|
+
}>;
|
26
|
+
/**
|
27
|
+
* Generates a secure state parameter for OAuth flow
|
28
|
+
* @returns A state string
|
29
|
+
*/
|
30
|
+
export declare function generateState(): string;
|
31
|
+
/**
|
32
|
+
* Validates a state parameter against the stored state
|
33
|
+
* @param receivedState - The state received from the authorization server
|
34
|
+
* @param storedState - The state stored locally
|
35
|
+
* @returns True if states match, false otherwise
|
36
|
+
*/
|
37
|
+
export declare function validateState(receivedState: string, storedState: string): boolean;
|
38
|
+
/**
|
39
|
+
* Checks if a token is a JWT
|
40
|
+
* @param token - The token to check
|
41
|
+
* @returns True if the token is a JWT, false otherwise
|
42
|
+
*/
|
43
|
+
export declare function isJWT(token: string): boolean;
|
44
|
+
/**
|
45
|
+
* Decodes a JWT payload (without verification)
|
46
|
+
* @param token - The JWT token
|
47
|
+
* @returns The decoded payload
|
48
|
+
*/
|
49
|
+
export declare function decodeJWT(token: string): any;
|
50
|
+
/**
|
51
|
+
* Checks if a JWT token is expired
|
52
|
+
* @param token - The JWT token
|
53
|
+
* @returns True if the token is expired, false otherwise
|
54
|
+
*/
|
55
|
+
export declare function isTokenExpired(token: string): boolean;
|
56
|
+
//# sourceMappingURL=utils.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../../src/oauth/utils.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAmB3D;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAE7C;AAED;;;;GAIG;AACH,wBAAsB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAiB7E;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,CAKzF;AAED;;;GAGG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,aAAa,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAgBjF;AAED;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAO5C;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,CAa5C;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAarD"}
|
@@ -0,0 +1,140 @@
|
|
1
|
+
import { AuthError, ErrorCode } from "./error";
|
2
|
+
/**
|
3
|
+
* Generates a cryptographically secure random string
|
4
|
+
* @param length - The length of the string to generate
|
5
|
+
* @returns A random string
|
6
|
+
*/
|
7
|
+
export function generateSecureRandom(length) {
|
8
|
+
const charset = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~';
|
9
|
+
let result = '';
|
10
|
+
if (typeof crypto !== 'undefined' && crypto.getRandomValues) {
|
11
|
+
const randomValues = new Uint8Array(length);
|
12
|
+
crypto.getRandomValues(randomValues);
|
13
|
+
for (let i = 0; i < length; i++) {
|
14
|
+
result += charset[randomValues[i] % charset.length];
|
15
|
+
}
|
16
|
+
}
|
17
|
+
else {
|
18
|
+
// Fallback for environments without crypto API
|
19
|
+
for (let i = 0; i < length; i++) {
|
20
|
+
result += charset[Math.floor(Math.random() * charset.length)];
|
21
|
+
}
|
22
|
+
}
|
23
|
+
return result;
|
24
|
+
}
|
25
|
+
/**
|
26
|
+
* Generates a PKCE code verifier
|
27
|
+
* @returns A code verifier string
|
28
|
+
*/
|
29
|
+
export function generateCodeVerifier() {
|
30
|
+
return generateSecureRandom(128);
|
31
|
+
}
|
32
|
+
/**
|
33
|
+
* Generates a PKCE code challenge from a verifier
|
34
|
+
* @param verifier - The code verifier
|
35
|
+
* @returns A code challenge string
|
36
|
+
*/
|
37
|
+
export async function generateCodeChallenge(verifier) {
|
38
|
+
if (typeof crypto !== 'undefined' && crypto.subtle) {
|
39
|
+
const encoder = new TextEncoder();
|
40
|
+
const data = encoder.encode(verifier);
|
41
|
+
const digest = await crypto.subtle.digest('SHA-256', data);
|
42
|
+
// Convert ArrayBuffer to base64url
|
43
|
+
const base64String = btoa(String.fromCharCode(...new Uint8Array(digest)));
|
44
|
+
return base64String
|
45
|
+
.replace(/\+/g, '-')
|
46
|
+
.replace(/\//g, '_')
|
47
|
+
.replace(/=/g, '');
|
48
|
+
}
|
49
|
+
else {
|
50
|
+
// Fallback: use plain verifier (not recommended for production)
|
51
|
+
console.warn('WebCrypto not available, using plain code verifier');
|
52
|
+
return verifier;
|
53
|
+
}
|
54
|
+
}
|
55
|
+
/**
|
56
|
+
* Generates a PKCE code verifier and challenge pair
|
57
|
+
* @returns An object containing verifier and challenge
|
58
|
+
*/
|
59
|
+
export async function generatePKCEPair() {
|
60
|
+
const verifier = generateCodeVerifier();
|
61
|
+
const challenge = await generateCodeChallenge(verifier);
|
62
|
+
return { verifier, challenge };
|
63
|
+
}
|
64
|
+
/**
|
65
|
+
* Generates a secure state parameter for OAuth flow
|
66
|
+
* @returns A state string
|
67
|
+
*/
|
68
|
+
export function generateState() {
|
69
|
+
return generateSecureRandom(32);
|
70
|
+
}
|
71
|
+
/**
|
72
|
+
* Validates a state parameter against the stored state
|
73
|
+
* @param receivedState - The state received from the authorization server
|
74
|
+
* @param storedState - The state stored locally
|
75
|
+
* @returns True if states match, false otherwise
|
76
|
+
*/
|
77
|
+
export function validateState(receivedState, storedState) {
|
78
|
+
if (!receivedState || !storedState) {
|
79
|
+
return false;
|
80
|
+
}
|
81
|
+
// Use constant-time comparison to prevent timing attacks
|
82
|
+
if (receivedState.length !== storedState.length) {
|
83
|
+
return false;
|
84
|
+
}
|
85
|
+
let result = 0;
|
86
|
+
for (let i = 0; i < receivedState.length; i++) {
|
87
|
+
result |= receivedState.charCodeAt(i) ^ storedState.charCodeAt(i);
|
88
|
+
}
|
89
|
+
return result === 0;
|
90
|
+
}
|
91
|
+
/**
|
92
|
+
* Checks if a token is a JWT
|
93
|
+
* @param token - The token to check
|
94
|
+
* @returns True if the token is a JWT, false otherwise
|
95
|
+
*/
|
96
|
+
export function isJWT(token) {
|
97
|
+
if (!token || typeof token !== 'string') {
|
98
|
+
return false;
|
99
|
+
}
|
100
|
+
const parts = token.split('.');
|
101
|
+
return parts.length === 3;
|
102
|
+
}
|
103
|
+
/**
|
104
|
+
* Decodes a JWT payload (without verification)
|
105
|
+
* @param token - The JWT token
|
106
|
+
* @returns The decoded payload
|
107
|
+
*/
|
108
|
+
export function decodeJWT(token) {
|
109
|
+
if (!isJWT(token)) {
|
110
|
+
throw new AuthError('Invalid JWT token', ErrorCode.InvalidToken);
|
111
|
+
}
|
112
|
+
try {
|
113
|
+
const parts = token.split('.');
|
114
|
+
const payload = parts[1];
|
115
|
+
const decoded = atob(payload.replace(/-/g, '+').replace(/_/g, '/'));
|
116
|
+
return JSON.parse(decoded);
|
117
|
+
}
|
118
|
+
catch (error) {
|
119
|
+
throw new AuthError('Failed to decode JWT', ErrorCode.InvalidToken);
|
120
|
+
}
|
121
|
+
}
|
122
|
+
/**
|
123
|
+
* Checks if a JWT token is expired
|
124
|
+
* @param token - The JWT token
|
125
|
+
* @returns True if the token is expired, false otherwise
|
126
|
+
*/
|
127
|
+
export function isTokenExpired(token) {
|
128
|
+
if (!isJWT(token)) {
|
129
|
+
return true;
|
130
|
+
}
|
131
|
+
try {
|
132
|
+
const payload = decodeJWT(token);
|
133
|
+
const now = Math.floor(Date.now() / 1000);
|
134
|
+
return payload.exp && payload.exp < now;
|
135
|
+
}
|
136
|
+
catch {
|
137
|
+
return true;
|
138
|
+
}
|
139
|
+
}
|
140
|
+
//# sourceMappingURL=utils.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../../src/oauth/utils.ts"],"names":[],"mappings":"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"}
|