@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
|
@@ -1,227 +0,0 @@
|
|
|
1
|
-
import { StorageAdapter } from "./storage-CxKerLlc.js";
|
|
2
|
-
import { Router } from "@draftlab/auth-router";
|
|
3
|
-
import { RouterContext } from "@draftlab/auth-router/types";
|
|
4
|
-
|
|
5
|
-
//#region src/provider/provider.d.ts
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* OAuth provider system for Draft Auth.
|
|
9
|
-
* Defines the interfaces and utilities for implementing authentication providers
|
|
10
|
-
* that integrate with various OAuth 2.0 services.
|
|
11
|
-
*
|
|
12
|
-
* ## Creating a Provider
|
|
13
|
-
*
|
|
14
|
-
* ```ts
|
|
15
|
-
* export const MyProvider = (config: MyConfig): Provider<MyUserData> => ({
|
|
16
|
-
* type: "my-provider",
|
|
17
|
-
*
|
|
18
|
-
* init(routes, ctx) {
|
|
19
|
-
* routes.get("/authorize", async (c) => {
|
|
20
|
-
* // Redirect to provider's auth URL
|
|
21
|
-
* return c.redirect(authUrl)
|
|
22
|
-
* })
|
|
23
|
-
*
|
|
24
|
-
* routes.get("/callback", async (c) => {
|
|
25
|
-
* // Handle callback and extract user data
|
|
26
|
-
* const userData = await processCallback(c)
|
|
27
|
-
* return await ctx.success(c, userData)
|
|
28
|
-
* })
|
|
29
|
-
* }
|
|
30
|
-
* })
|
|
31
|
-
* ```
|
|
32
|
-
*
|
|
33
|
-
* ## Using Providers
|
|
34
|
-
*
|
|
35
|
-
* ```ts
|
|
36
|
-
* export default issuer({
|
|
37
|
-
* providers: {
|
|
38
|
-
* github: GithubProvider({ ... }),
|
|
39
|
-
* google: GoogleProvider({ ... })
|
|
40
|
-
* }
|
|
41
|
-
* })
|
|
42
|
-
* ```
|
|
43
|
-
*/
|
|
44
|
-
/**
|
|
45
|
-
* Router instance used for provider route definitions.
|
|
46
|
-
* Providers use this to register their authorization and callback endpoints.
|
|
47
|
-
*/
|
|
48
|
-
type ProviderRoute = Router;
|
|
49
|
-
/**
|
|
50
|
-
* Authentication provider interface that handles OAuth flows.
|
|
51
|
-
* Each provider implements authentication with a specific service (GitHub, Google, etc.).
|
|
52
|
-
*
|
|
53
|
-
* @template Properties - Type of user data returned by successful authentication
|
|
54
|
-
*/
|
|
55
|
-
interface Provider<Properties = Record<string, unknown>> {
|
|
56
|
-
/**
|
|
57
|
-
* Unique identifier for this provider type.
|
|
58
|
-
* Used in URLs and provider selection UI.
|
|
59
|
-
*
|
|
60
|
-
* @example "github", "google", "steam"
|
|
61
|
-
*/
|
|
62
|
-
readonly type: string;
|
|
63
|
-
/**
|
|
64
|
-
* Initializes the provider by registering required routes.
|
|
65
|
-
* Called during issuer setup to configure authorization and callback endpoints.
|
|
66
|
-
*
|
|
67
|
-
* @param route - Router instance for registering provider endpoints
|
|
68
|
-
* @param options - Provider utilities and configuration
|
|
69
|
-
*
|
|
70
|
-
* @example
|
|
71
|
-
* ```ts
|
|
72
|
-
* init(routes, ctx) {
|
|
73
|
-
* routes.get("/authorize", async (c) => {
|
|
74
|
-
* // Redirect to OAuth provider
|
|
75
|
-
* return c.redirect(buildAuthUrl())
|
|
76
|
-
* })
|
|
77
|
-
*
|
|
78
|
-
* routes.get("/callback", async (c) => {
|
|
79
|
-
* // Process callback and return user data
|
|
80
|
-
* const userData = await handleCallback(c)
|
|
81
|
-
* return await ctx.success(c, userData)
|
|
82
|
-
* })
|
|
83
|
-
* }
|
|
84
|
-
* ```
|
|
85
|
-
*/
|
|
86
|
-
init: (route: ProviderRoute, options: ProviderOptions<Properties>) => void;
|
|
87
|
-
}
|
|
88
|
-
/**
|
|
89
|
-
* Utilities and callbacks provided to providers during initialization.
|
|
90
|
-
* Contains methods for state management, user flow completion, and storage access.
|
|
91
|
-
*
|
|
92
|
-
* @template Properties - Type of user data handled by the provider
|
|
93
|
-
*/
|
|
94
|
-
interface ProviderOptions<Properties> {
|
|
95
|
-
/**
|
|
96
|
-
* Name of the provider instance as configured in the issuer.
|
|
97
|
-
* Corresponds to the key used in the providers object.
|
|
98
|
-
*/
|
|
99
|
-
readonly name: string;
|
|
100
|
-
/**
|
|
101
|
-
* Completes the authentication flow with user data.
|
|
102
|
-
* Called when the provider successfully authenticates a user.
|
|
103
|
-
*
|
|
104
|
-
* @param ctx - Router request context
|
|
105
|
-
* @param properties - User data extracted from the provider
|
|
106
|
-
* @param opts - Optional utilities for session management
|
|
107
|
-
* @returns Response that completes the OAuth flow
|
|
108
|
-
*
|
|
109
|
-
* @example
|
|
110
|
-
* ```ts
|
|
111
|
-
* const userData = { userId: "123", email: "user@example.com" }
|
|
112
|
-
* return await ctx.success(c, userData)
|
|
113
|
-
* ```
|
|
114
|
-
*/
|
|
115
|
-
success: (ctx: RouterContext, properties: Properties, opts?: {
|
|
116
|
-
/** Function to invalidate existing user sessions */
|
|
117
|
-
readonly invalidate?: (subject: string) => Promise<void>;
|
|
118
|
-
}) => Promise<Response>;
|
|
119
|
-
/**
|
|
120
|
-
* Forwards a response through the provider context.
|
|
121
|
-
* Used for redirects and custom responses within the OAuth flow.
|
|
122
|
-
*
|
|
123
|
-
* @param ctx - Router request context
|
|
124
|
-
* @param response - Response to forward
|
|
125
|
-
* @returns Forwarded response
|
|
126
|
-
*/
|
|
127
|
-
forward: (ctx: RouterContext, response: Response) => Response;
|
|
128
|
-
/**
|
|
129
|
-
* Stores a temporary value with expiration for the current session.
|
|
130
|
-
* Useful for storing OAuth state, PKCE verifiers, and other temporary data.
|
|
131
|
-
*
|
|
132
|
-
* @param ctx - Router request context
|
|
133
|
-
* @param key - Storage key identifier
|
|
134
|
-
* @param maxAge - TTL in seconds
|
|
135
|
-
* @param value - Value to store
|
|
136
|
-
*
|
|
137
|
-
* @example
|
|
138
|
-
* ```ts
|
|
139
|
-
* // Store OAuth state for 10 minutes
|
|
140
|
-
* await ctx.set(c, "oauth_state", 600, { state, redirectUri })
|
|
141
|
-
* ```
|
|
142
|
-
*/
|
|
143
|
-
set: <T>(ctx: RouterContext, key: string, maxAge: number, value: T) => Promise<void>;
|
|
144
|
-
/**
|
|
145
|
-
* Retrieves a previously stored temporary value.
|
|
146
|
-
*
|
|
147
|
-
* @param ctx - Router request context
|
|
148
|
-
* @param key - Storage key identifier
|
|
149
|
-
* @returns Promise resolving to the stored value or undefined if not found/expired
|
|
150
|
-
*
|
|
151
|
-
* @example
|
|
152
|
-
* ```ts
|
|
153
|
-
* const oauthState = await ctx.get<OAuthState>(c, "oauth_state")
|
|
154
|
-
* if (!oauthState) {
|
|
155
|
-
* throw new Error("OAuth state expired")
|
|
156
|
-
* }
|
|
157
|
-
* ```
|
|
158
|
-
*/
|
|
159
|
-
get: <T>(ctx: RouterContext, key: string) => Promise<T | undefined>;
|
|
160
|
-
/**
|
|
161
|
-
* Removes a stored temporary value.
|
|
162
|
-
*
|
|
163
|
-
* @param ctx - Router request context
|
|
164
|
-
* @param key - Storage key identifier
|
|
165
|
-
*
|
|
166
|
-
* @example
|
|
167
|
-
* ```ts
|
|
168
|
-
* // Clean up OAuth state after use
|
|
169
|
-
* await ctx.unset(c, "oauth_state")
|
|
170
|
-
* ```
|
|
171
|
-
*/
|
|
172
|
-
unset: (ctx: RouterContext, key: string) => Promise<void>;
|
|
173
|
-
/**
|
|
174
|
-
* Invalidates all sessions for a given subject (user).
|
|
175
|
-
* Forces logout across all devices and applications.
|
|
176
|
-
*
|
|
177
|
-
* @param subject - Subject identifier to invalidate
|
|
178
|
-
*
|
|
179
|
-
* @example
|
|
180
|
-
* ```ts
|
|
181
|
-
* // Force logout on password change
|
|
182
|
-
* await ctx.invalidate(userId)
|
|
183
|
-
* ```
|
|
184
|
-
*/
|
|
185
|
-
invalidate: (subject: string) => Promise<void>;
|
|
186
|
-
/**
|
|
187
|
-
* Storage adapter for persistent data operations.
|
|
188
|
-
* Provides access to the configured storage backend.
|
|
189
|
-
*/
|
|
190
|
-
readonly storage: StorageAdapter;
|
|
191
|
-
}
|
|
192
|
-
/**
|
|
193
|
-
* Base error class for provider-related errors.
|
|
194
|
-
* Extend this class to create specific provider error types.
|
|
195
|
-
*
|
|
196
|
-
* @example
|
|
197
|
-
* ```ts
|
|
198
|
-
* export class GitHubApiError extends ProviderError {
|
|
199
|
-
* constructor(message: string, public readonly statusCode: number) {
|
|
200
|
-
* super(message)
|
|
201
|
-
* }
|
|
202
|
-
* }
|
|
203
|
-
* ```
|
|
204
|
-
*/
|
|
205
|
-
declare class ProviderError extends Error {
|
|
206
|
-
constructor(message: string);
|
|
207
|
-
}
|
|
208
|
-
/**
|
|
209
|
-
* Error thrown when a provider encounters an unknown or unexpected error.
|
|
210
|
-
* Used as a fallback for unhandled error conditions.
|
|
211
|
-
*
|
|
212
|
-
* @example
|
|
213
|
-
* ```ts
|
|
214
|
-
* catch (error) {
|
|
215
|
-
* if (error instanceof SomeSpecificError) {
|
|
216
|
-
* // Handle specific error
|
|
217
|
-
* } else {
|
|
218
|
-
* throw new ProviderUnknownError(`Unexpected error: ${error}`)
|
|
219
|
-
* }
|
|
220
|
-
* }
|
|
221
|
-
* ```
|
|
222
|
-
*/
|
|
223
|
-
declare class ProviderUnknownError extends ProviderError {
|
|
224
|
-
constructor(message?: string);
|
|
225
|
-
}
|
|
226
|
-
//#endregion
|
|
227
|
-
export { Provider, ProviderError, ProviderOptions, ProviderRoute, ProviderUnknownError };
|
package/dist/random-SXMYlaVr.js
DELETED
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import { timingSafeEqual } from "node:crypto";
|
|
2
|
-
|
|
3
|
-
//#region src/random.ts
|
|
4
|
-
/**
|
|
5
|
-
* Cryptographic utilities for secure random generation and comparison operations.
|
|
6
|
-
* These functions are designed to prevent timing attacks and provide unbiased randomness.
|
|
7
|
-
*/
|
|
8
|
-
/**
|
|
9
|
-
* Generates a cryptographically secure token with enhanced entropy.
|
|
10
|
-
* Uses Web Crypto API and provides 256 bits of entropy
|
|
11
|
-
*
|
|
12
|
-
* @param length - Length of random data in bytes (default: 32 for 256-bit security)
|
|
13
|
-
* @returns Base64url-encoded secure token
|
|
14
|
-
*
|
|
15
|
-
* @example
|
|
16
|
-
* ```ts
|
|
17
|
-
* const authCode = generateSecureToken()
|
|
18
|
-
* // Returns: "7B8kJ9mN3pQ2rS5tU8vW0xY1zA3bC6dE9fG2hI5jK8lM" (example)
|
|
19
|
-
*
|
|
20
|
-
* const refreshToken = generateSecureToken(24) // 192-bit token
|
|
21
|
-
* // Returns: "4A7bC9dF2gH5iJ8kL1mN4pQ7rS0tU" (example)
|
|
22
|
-
* ```
|
|
23
|
-
*/
|
|
24
|
-
const generateSecureToken = (length = 32) => {
|
|
25
|
-
if (length <= 0 || !Number.isInteger(length)) throw new RangeError("Token length must be a positive integer");
|
|
26
|
-
const randomBytes$1 = new Uint8Array(length);
|
|
27
|
-
crypto.getRandomValues(randomBytes$1);
|
|
28
|
-
const base64 = btoa(String.fromCharCode.apply(null, Array.from(randomBytes$1)));
|
|
29
|
-
return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
|
|
30
|
-
};
|
|
31
|
-
/**
|
|
32
|
-
* Generates a cryptographically secure string of random digits without modulo bias.
|
|
33
|
-
* Uses rejection sampling to ensure each digit (0-9) has an equal probability of being selected.
|
|
34
|
-
*
|
|
35
|
-
* @param length - Number of digits to generate (must be positive)
|
|
36
|
-
* @returns String containing exactly the specified number of random digits
|
|
37
|
-
*
|
|
38
|
-
* @example
|
|
39
|
-
* ```ts
|
|
40
|
-
* const pinCode = generateUnbiasedDigits(6)
|
|
41
|
-
* // Returns: "492847" (example - actual result is random)
|
|
42
|
-
*
|
|
43
|
-
* const shortCode = generateUnbiasedDigits(4)
|
|
44
|
-
* // Returns: "7291" (example - actual result is random)
|
|
45
|
-
* ```
|
|
46
|
-
*
|
|
47
|
-
* @throws {RangeError} If length is not a positive number
|
|
48
|
-
*/
|
|
49
|
-
const generateUnbiasedDigits = (length) => {
|
|
50
|
-
if (length <= 0 || !Number.isInteger(length)) throw new RangeError("Length must be a positive integer");
|
|
51
|
-
const result = [];
|
|
52
|
-
while (result.length < length) {
|
|
53
|
-
const buffer = crypto.getRandomValues(new Uint8Array(length * 2));
|
|
54
|
-
for (const byte of buffer) if (byte < 250 && result.length < length) result.push(byte % 10);
|
|
55
|
-
}
|
|
56
|
-
return result.join("");
|
|
57
|
-
};
|
|
58
|
-
/**
|
|
59
|
-
* Performs a timing-safe comparison of two strings to prevent timing attacks.
|
|
60
|
-
* Always takes the same amount of time regardless of where the strings differ,
|
|
61
|
-
* making it safe for comparing sensitive values like tokens or passwords.
|
|
62
|
-
*
|
|
63
|
-
* @param a - First string to compare
|
|
64
|
-
* @param b - Second string to compare
|
|
65
|
-
* @returns True if strings are identical, false otherwise
|
|
66
|
-
*
|
|
67
|
-
* @example
|
|
68
|
-
* ```ts
|
|
69
|
-
* // Safe for comparing sensitive values
|
|
70
|
-
* const isValidToken = timingSafeCompare(userToken, expectedToken)
|
|
71
|
-
*
|
|
72
|
-
* // Safe for password verification
|
|
73
|
-
* const isValidPassword = timingSafeCompare(hashedInput, storedHash)
|
|
74
|
-
*
|
|
75
|
-
* // Returns false for different types or lengths
|
|
76
|
-
* timingSafeCompare("abc", 123 as any) // false
|
|
77
|
-
* timingSafeCompare("abc", "abcd") // false
|
|
78
|
-
* ```
|
|
79
|
-
*/
|
|
80
|
-
const timingSafeCompare = (a, b) => {
|
|
81
|
-
if (typeof a !== "string" || typeof b !== "string") return false;
|
|
82
|
-
if (a.length !== b.length) return false;
|
|
83
|
-
return timingSafeEqual(Buffer.from(a), Buffer.from(b));
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
//#endregion
|
|
87
|
-
export { generateSecureToken, generateUnbiasedDigits, timingSafeCompare };
|
package/dist/select-BjySLL8I.js
DELETED
|
@@ -1,280 +0,0 @@
|
|
|
1
|
-
import { Layout } from "./base-DRutbxgL.js";
|
|
2
|
-
import { ICON_GITHUB, ICON_GOOGLE } from "./icon-Ci5uqGB_.js";
|
|
3
|
-
|
|
4
|
-
//#region src/ui/select.ts
|
|
5
|
-
/**
|
|
6
|
-
* Default copy text used throughout the select UI.
|
|
7
|
-
* These values are used when no custom copy is provided.
|
|
8
|
-
*/
|
|
9
|
-
const DEFAULT_COPY = { button_provider: "Continue with" };
|
|
10
|
-
/**
|
|
11
|
-
* Default display names for all known provider types.
|
|
12
|
-
* These provide consistent naming across the application and serve as fallbacks
|
|
13
|
-
* when no custom display name is configured.
|
|
14
|
-
*/
|
|
15
|
-
const DEFAULT_DISPLAY = {
|
|
16
|
-
steam: "Steam",
|
|
17
|
-
twitch: "Twitch",
|
|
18
|
-
google: "Google",
|
|
19
|
-
github: "GitHub",
|
|
20
|
-
apple: "Apple",
|
|
21
|
-
code: "Code",
|
|
22
|
-
x: "X",
|
|
23
|
-
facebook: "Facebook",
|
|
24
|
-
microsoft: "Microsoft",
|
|
25
|
-
slack: "Slack",
|
|
26
|
-
password: "Password"
|
|
27
|
-
};
|
|
28
|
-
/**
|
|
29
|
-
* Comprehensive icon mapping for all supported authentication providers.
|
|
30
|
-
* Each icon is an optimized SVG component with proper accessibility attributes.
|
|
31
|
-
*
|
|
32
|
-
* Icons are designed to:
|
|
33
|
-
* - Scale properly at different sizes
|
|
34
|
-
* - Inherit text color for theming
|
|
35
|
-
* - Include proper ARIA attributes
|
|
36
|
-
* - Work with screen readers
|
|
37
|
-
*/
|
|
38
|
-
const ICON = {
|
|
39
|
-
steam: `
|
|
40
|
-
<svg
|
|
41
|
-
aria-hidden="true"
|
|
42
|
-
class="bi bi-steam"
|
|
43
|
-
fill="currentColor"
|
|
44
|
-
height="16"
|
|
45
|
-
viewBox="0 0 16 16"
|
|
46
|
-
width="16"
|
|
47
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
48
|
-
>
|
|
49
|
-
<path d="M.329 10.333A8.01 8.01 0 0 0 7.99 16C12.414 16 16 12.418 16 8s-3.586-8-8.009-8A8.006 8.006 0 0 0 0 7.468l.003.006 4.304 1.769A2.2 2.2 0 0 1 5.62 8.88l1.96-2.844-.001-.04a3.046 3.046 0 0 1 3.042-3.043 3.046 3.046 0 0 1 3.042 3.043 3.047 3.047 0 0 1-3.111 3.044l-2.804 2a2.223 2.223 0 0 1-3.075 2.11 2.22 2.22 0 0 1-1.312-1.568L.33 10.333Z" />
|
|
50
|
-
<path d="M4.868 12.683a1.715 1.715 0 0 0 1.318-3.165 1.7 1.7 0 0 0-1.263-.02l1.023.424a1.261 1.261 0 1 1-.97 2.33l-.99-.41a1.7 1.7 0 0 0 .882.84Zm3.726-6.687a2.03 2.03 0 0 0 2.027 2.029 2.03 2.03 0 0 0 2.027-2.029 2.03 2.03 0 0 0-2.027-2.027 2.03 2.03 0 0 0-2.027 2.027m2.03-1.527a1.524 1.524 0 1 1-.002 3.048 1.524 1.524 0 0 1 .002-3.048" />
|
|
51
|
-
</svg>
|
|
52
|
-
`,
|
|
53
|
-
code: `
|
|
54
|
-
<svg
|
|
55
|
-
aria-hidden="true"
|
|
56
|
-
data-name="Layer 1"
|
|
57
|
-
fill="currentColor"
|
|
58
|
-
viewBox="0 0 52 52"
|
|
59
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
60
|
-
>
|
|
61
|
-
<path
|
|
62
|
-
d="M8.55,36.91A6.55,6.55,0,1,1,2,43.45,6.54,6.54,0,0,1,8.55,36.91Zm17.45,0a6.55,6.55,0,1,1-6.55,6.54A6.55,6.55,0,0,1,26,36.91Zm17.45,0a6.55,6.55,0,1,1-6.54,6.54A6.54,6.54,0,0,1,43.45,36.91ZM8.55,19.45A6.55,6.55,0,1,1,2,26,6.55,6.55,0,0,1,8.55,19.45Zm17.45,0A6.55,6.55,0,1,1,19.45,26,6.56,6.56,0,0,1,26,19.45Zm17.45,0A6.55,6.55,0,1,1,36.91,26,6.55,6.55,0,0,1,43.45,19.45ZM8.55,2A6.55,6.55,0,1,1,2,8.55,6.54,6.54,0,0,1,8.55,2ZM26,2a6.55,6.55,0,1,1-6.55,6.55A6.55,6.55,0,0,1,26,2ZM43.45,2a6.55,6.55,0,1,1-6.54,6.55A6.55,6.55,0,0,1,43.45,2Z"
|
|
63
|
-
fill-rule="evenodd"
|
|
64
|
-
/>
|
|
65
|
-
</svg>
|
|
66
|
-
`,
|
|
67
|
-
password: `
|
|
68
|
-
<svg
|
|
69
|
-
aria-hidden="true"
|
|
70
|
-
fill="currentColor"
|
|
71
|
-
viewBox="0 0 24 24"
|
|
72
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
73
|
-
>
|
|
74
|
-
<path
|
|
75
|
-
clip-rule="evenodd"
|
|
76
|
-
d="M12 1.5a5.25 5.25 0 0 0-5.25 5.25v3a3 3 0 0 0-3 3v6.75a3 3 0 0 0 3 3h10.5a3 3 0 0 0 3-3v-6.75a3 3 0 0 0-3-3v-3c0-2.9-2.35-5.25-5.25-5.25Zm3.75 8.25v-3a3.75 3.75 0 1 0-7.5 0v3h7.5Z"
|
|
77
|
-
fill-rule="evenodd"
|
|
78
|
-
/>
|
|
79
|
-
</svg>
|
|
80
|
-
`,
|
|
81
|
-
twitch: `
|
|
82
|
-
<svg
|
|
83
|
-
aria-hidden="true"
|
|
84
|
-
role="img"
|
|
85
|
-
viewBox="0 0 448 512"
|
|
86
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
87
|
-
>
|
|
88
|
-
<path
|
|
89
|
-
d="M40.1 32L10 108.9v314.3h107V480h60.2l56.8-56.8h87l117-117V32H40.1zm357.8 254.1L331 353H224l-56.8 56.8V353H76.9V72.1h321v214zM331 149v116.9h-40.1V149H331zm-107 0v116.9h-40.1V149H224z"
|
|
90
|
-
fill="currentColor"
|
|
91
|
-
/>
|
|
92
|
-
</svg>
|
|
93
|
-
`,
|
|
94
|
-
google: ICON_GOOGLE,
|
|
95
|
-
github: ICON_GITHUB,
|
|
96
|
-
apple: `
|
|
97
|
-
<svg
|
|
98
|
-
aria-hidden="true"
|
|
99
|
-
role="img"
|
|
100
|
-
viewBox="0 0 814 1000"
|
|
101
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
102
|
-
>
|
|
103
|
-
<path
|
|
104
|
-
d="M788.1 340.9c-5.8 4.5-108.2 62.2-108.2 190.5 0 148.4 130.3 200.9 134.2 202.2-.6 3.2-20.7 71.9-68.7 141.9-42.8 61.6-87.5 123.1-155.5 123.1s-85.5-39.5-164-39.5c-76.5 0-103.7 40.8-165.9 40.8s-105.6-57-155.5-127C46.7 790.7 0 663 0 541.8c0-194.4 126.4-297.5 250.8-297.5 66.1 0 121.2 43.4 162.7 43.4 39.5 0 101.1-46 176.3-46 28.5 0 130.9 2.6 198.3 99.2zm-234-181.5c31.1-36.9 53.1-88.1 53.1-139.3 0-7.1-.6-14.3-1.9-20.1-50.6 1.9-110.8 33.7-147.1 75.8-28.5 32.4-55.1 83.6-55.1 135.5 0 7.8 1.3 15.6 1.9 18.1 3.2.6 8.4 1.3 13.6 1.3 45.4 0 102.5-30.4 135.5-71.3z "
|
|
105
|
-
fill="currentColor"
|
|
106
|
-
/>
|
|
107
|
-
</svg>
|
|
108
|
-
`,
|
|
109
|
-
x: `
|
|
110
|
-
<svg
|
|
111
|
-
aria-hidden="true"
|
|
112
|
-
role="img"
|
|
113
|
-
viewBox="0 0 1200 1227"
|
|
114
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
115
|
-
>
|
|
116
|
-
<path
|
|
117
|
-
d="M714.163 519.284 1160.89 0h-105.86L667.137 450.887 357.328 0H0l468.492 681.821L0 1226.37h105.866l409.625-476.152 327.181 476.152H1200L714.137 519.284h.026ZM569.165 687.828l-47.468-67.894-377.686-540.24h162.604l304.797 435.991 47.468 67.894 396.2 566.721H892.476L569.165 687.854v-.026Z"
|
|
118
|
-
fill="currentColor"
|
|
119
|
-
/>
|
|
120
|
-
</svg>
|
|
121
|
-
`,
|
|
122
|
-
microsoft: `
|
|
123
|
-
<svg
|
|
124
|
-
aria-hidden="true"
|
|
125
|
-
preserveAspectRatio="xMidYMid"
|
|
126
|
-
role="img"
|
|
127
|
-
viewBox="0 0 256 256"
|
|
128
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
129
|
-
>
|
|
130
|
-
<path d="M121.666 121.666H0V0h121.666z" fill="#F1511B" />
|
|
131
|
-
<path d="M256 121.666H134.335V0H256z" fill="#80CC28" />
|
|
132
|
-
<path d="M121.663 256.002H0V134.336h121.663z" fill="#00ADEF" />
|
|
133
|
-
<path d="M256 256.002H134.335V134.336H256z" fill="#FBBC09" />
|
|
134
|
-
</svg>
|
|
135
|
-
`,
|
|
136
|
-
facebook: `
|
|
137
|
-
<svg
|
|
138
|
-
aria-hidden="true"
|
|
139
|
-
fill="url(#a)"
|
|
140
|
-
role="img"
|
|
141
|
-
viewBox="0 0 36 36"
|
|
142
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
143
|
-
>
|
|
144
|
-
<defs>
|
|
145
|
-
<linearGradient id="a" x1="50%" x2="50%" y1="97.078%" y2="0%">
|
|
146
|
-
<stop offset="0%" stop-color="#0062E0" />
|
|
147
|
-
<stop offset="100%" stop-color="#19AFFF" />
|
|
148
|
-
</linearGradient>
|
|
149
|
-
</defs>
|
|
150
|
-
<path d="M15 35.8C6.5 34.3 0 26.9 0 18 0 8.1 8.1 0 18 0s18 8.1 18 18c0 8.9-6.5 16.3-15 17.8l-1-.8h-4l-1 .8z" />
|
|
151
|
-
<path
|
|
152
|
-
d="m25 23 .8-5H21v-3.5c0-1.4.5-2.5 2.7-2.5H26V7.4c-1.3-.2-2.7-.4-4-.4-4.1 0-7 2.5-7 7v4h-4.5v5H15v12.7c1 .2 2 .3 3 .3s2-.1 3-.3V23h4z"
|
|
153
|
-
fill="#FFF"
|
|
154
|
-
/>
|
|
155
|
-
</svg>
|
|
156
|
-
`,
|
|
157
|
-
slack: `
|
|
158
|
-
<svg
|
|
159
|
-
aria-hidden="true"
|
|
160
|
-
enable-background="new 0 0 2447.6 2452.5"
|
|
161
|
-
role="img"
|
|
162
|
-
viewBox="0 0 2447.6 2452.5"
|
|
163
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
164
|
-
>
|
|
165
|
-
<g clip-rule="evenodd" fill-rule="evenodd">
|
|
166
|
-
<path
|
|
167
|
-
d="m897.4 0c-135.3.1-244.8 109.9-244.7 245.2-.1 135.3 109.5 245.1 244.8 245.2h244.8v-245.1c.1-135.3-109.5-245.1-244.9-245.3.1 0 .1 0 0 0m0 654h-652.6c-135.3.1-244.9 109.9-244.8 245.2-.2 135.3 109.4 245.1 244.7 245.3h652.7c135.3-.1 244.9-109.9 244.8-245.2.1-135.4-109.5-245.2-244.8-245.3z"
|
|
168
|
-
fill="#36c5f0"
|
|
169
|
-
/>
|
|
170
|
-
<path
|
|
171
|
-
d="m2447.6 899.2c.1-135.3-109.5-245.1-244.8-245.2-135.3.1-244.9 109.9-244.8 245.2v245.3h244.8c135.3-.1 244.9-109.9 244.8-245.3zm-652.7 0v-654c.1-135.2-109.4-245-244.7-245.2-135.3.1-244.9 109.9-244.8 245.2v654c-.2 135.3 109.4 245.1 244.7 245.3 135.3-.1 244.9-109.9 244.8-245.3z"
|
|
172
|
-
fill="#2eb67d"
|
|
173
|
-
/>
|
|
174
|
-
<path
|
|
175
|
-
d="m1550.1 2452.5c135.3-.1 244.9-109.9 244.8-245.2.1-135.3-109.5-245.1-244.8-245.2h-244.8v245.2c-.1 135.2 109.5 245 244.8 245.2zm0-654.1h652.7c135.3-.1 244.9-109.9 244.8-245.2.2-135.3-109.4-245.1-244.7-245.3h-652.7c-135.3.1-244.9 109.9-244.8 245.2-.1 135.4 109.4 245.2 244.7 245.3z"
|
|
176
|
-
fill="#ecb22e"
|
|
177
|
-
/>
|
|
178
|
-
<path
|
|
179
|
-
d="m0 1553.2c-.1 135.3 109.5 245.1 244.8 245.2 135.3-.1 244.9-109.9 244.8-245.2v-245.2h-244.8c-135.3.1-244.9 109.9-244.8 245.2zm652.7 0v654c-.2 135.3 109.4 245.1 244.7 245.3 135.3-.1 244.9-109.9 244.8-245.2v-653.9c.2-135.3-109.4-245.1-244.7-245.3-135.4 0-244.9 109.8-244.8 245.1 0 0 0 .1 0 0"
|
|
180
|
-
fill="#e01e5a"
|
|
181
|
-
/>
|
|
182
|
-
</g>
|
|
183
|
-
</svg>
|
|
184
|
-
`
|
|
185
|
-
};
|
|
186
|
-
/**
|
|
187
|
-
* Creates a provider selection UI component for OAuth authentication.
|
|
188
|
-
*
|
|
189
|
-
* This component generates a complete authentication provider selection interface that:
|
|
190
|
-
* - Displays available OAuth providers as clickable buttons
|
|
191
|
-
* - Includes appropriate icons for recognized providers
|
|
192
|
-
* - Supports custom theming and internationalization
|
|
193
|
-
* - Provides accessible markup with proper ARIA attributes
|
|
194
|
-
* - Handles provider visibility and custom display names
|
|
195
|
-
*
|
|
196
|
-
* @param props - Configuration options for customizing the select UI
|
|
197
|
-
* @returns An async function that generates the HTML response for the selection interface
|
|
198
|
-
*
|
|
199
|
-
* @example
|
|
200
|
-
* ```ts
|
|
201
|
-
* // Basic usage with defaults
|
|
202
|
-
* const selectUI = Select()
|
|
203
|
-
*
|
|
204
|
-
* // Customized with provider configuration
|
|
205
|
-
* const selectUI = Select({
|
|
206
|
-
* copy: {
|
|
207
|
-
* button_provider: "Sign in with"
|
|
208
|
-
* },
|
|
209
|
-
* displays: {
|
|
210
|
-
* github: "GitHub Account",
|
|
211
|
-
* code: "Email Code"
|
|
212
|
-
* },
|
|
213
|
-
* providers: {
|
|
214
|
-
* facebook: { hide: true },
|
|
215
|
-
* google: { display: "Google Workspace" }
|
|
216
|
-
* }
|
|
217
|
-
* })
|
|
218
|
-
*
|
|
219
|
-
* // Use in issuer configuration
|
|
220
|
-
* export default issuer({
|
|
221
|
-
* select: selectUI,
|
|
222
|
-
* // ... other configuration
|
|
223
|
-
* })
|
|
224
|
-
* ```
|
|
225
|
-
*
|
|
226
|
-
* ## Provider Resolution Logic
|
|
227
|
-
*
|
|
228
|
-
* Display names are resolved in the following priority order:
|
|
229
|
-
* 1. Provider-specific `display` property
|
|
230
|
-
* 2. Global `displays` type override
|
|
231
|
-
* 3. Default display name from `DEFAULT_DISPLAY`
|
|
232
|
-
* 4. Provider type string as final fallback
|
|
233
|
-
*
|
|
234
|
-
* ## Accessibility Features
|
|
235
|
-
*
|
|
236
|
-
* The generated UI includes:
|
|
237
|
-
* - Semantic HTML structure
|
|
238
|
-
* - Proper button roles and keyboard navigation
|
|
239
|
-
* - Icon accessibility with `aria-hidden="true"`
|
|
240
|
-
* - Screen reader friendly provider names
|
|
241
|
-
*/
|
|
242
|
-
const Select = (props) => {
|
|
243
|
-
return async (providers, _req) => {
|
|
244
|
-
const copy = {
|
|
245
|
-
...DEFAULT_COPY,
|
|
246
|
-
...props?.copy
|
|
247
|
-
};
|
|
248
|
-
const displays = {
|
|
249
|
-
...DEFAULT_DISPLAY,
|
|
250
|
-
...props?.displays
|
|
251
|
-
};
|
|
252
|
-
const providerButtons = Object.entries(providers).map(([providerKey, providerType]) => {
|
|
253
|
-
const providerConfig = props?.providers?.[providerKey];
|
|
254
|
-
if (providerConfig?.hide) return "";
|
|
255
|
-
const displayName = providerConfig?.display || displays[providerType] || providerType;
|
|
256
|
-
const icon = ICON[providerKey];
|
|
257
|
-
return `
|
|
258
|
-
<a
|
|
259
|
-
aria-label="${copy.button_provider} ${displayName}"
|
|
260
|
-
data-color="ghost"
|
|
261
|
-
data-component="button"
|
|
262
|
-
href="./${providerKey}/authorize"
|
|
263
|
-
>
|
|
264
|
-
${icon ? `<i data-slot="icon">${icon}</i>` : ""}
|
|
265
|
-
${copy.button_provider} ${displayName}
|
|
266
|
-
</a>
|
|
267
|
-
`;
|
|
268
|
-
}).filter((button) => button !== "").join("");
|
|
269
|
-
const formContent = `
|
|
270
|
-
<div data-component="form">
|
|
271
|
-
${providerButtons}
|
|
272
|
-
</div>
|
|
273
|
-
`;
|
|
274
|
-
const html = Layout({ children: formContent });
|
|
275
|
-
return new Response(html, { headers: { "Content-Type": "text/html" } });
|
|
276
|
-
};
|
|
277
|
-
};
|
|
278
|
-
|
|
279
|
-
//#endregion
|
|
280
|
-
export { Select };
|
package/dist/storage-BEaqEPNQ.js
DELETED
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
//#region src/storage/storage.ts
|
|
2
|
-
/**
|
|
3
|
-
* ASCII unit separator character used to join key segments.
|
|
4
|
-
* Using a control character ensures it won't conflict with user data.
|
|
5
|
-
*/
|
|
6
|
-
const SEPARATOR = String.fromCharCode(31);
|
|
7
|
-
/**
|
|
8
|
-
* Joins an array of key segments into a single string using the separator.
|
|
9
|
-
*
|
|
10
|
-
* @param key - Array of key segments to join
|
|
11
|
-
* @returns Single string representing the full key path
|
|
12
|
-
*
|
|
13
|
-
* @example
|
|
14
|
-
* ```ts
|
|
15
|
-
* joinKey(['user', 'session', '123'])
|
|
16
|
-
* // Returns: "user\x1fsession\x1f123"
|
|
17
|
-
* ```
|
|
18
|
-
*/
|
|
19
|
-
const joinKey = (key) => {
|
|
20
|
-
return key.join(SEPARATOR);
|
|
21
|
-
};
|
|
22
|
-
/**
|
|
23
|
-
* Splits a joined key string back into its component segments.
|
|
24
|
-
*
|
|
25
|
-
* @param key - Joined key string to split
|
|
26
|
-
* @returns Array of individual key segments
|
|
27
|
-
*
|
|
28
|
-
* @example
|
|
29
|
-
* ```ts
|
|
30
|
-
* splitKey("user\x1fsession\x1f123")
|
|
31
|
-
* // Returns: ['user', 'session', '123']
|
|
32
|
-
* ```
|
|
33
|
-
*/
|
|
34
|
-
const splitKey = (key) => {
|
|
35
|
-
return key.split(SEPARATOR);
|
|
36
|
-
};
|
|
37
|
-
/**
|
|
38
|
-
* High-level storage operations with key encoding and type safety.
|
|
39
|
-
* Provides a convenient interface over storage adapters with additional features
|
|
40
|
-
* like TTL conversion and key sanitization.
|
|
41
|
-
*/
|
|
42
|
-
const Storage = {
|
|
43
|
-
encode: (key) => {
|
|
44
|
-
return key.map((segment) => segment.replaceAll(SEPARATOR, ""));
|
|
45
|
-
},
|
|
46
|
-
get: (adapter, key) => {
|
|
47
|
-
return adapter.get(Storage.encode(key));
|
|
48
|
-
},
|
|
49
|
-
set: (adapter, key, value, ttlSeconds) => {
|
|
50
|
-
const expiry = ttlSeconds ? new Date(Date.now() + ttlSeconds * 1e3) : void 0;
|
|
51
|
-
return adapter.set(Storage.encode(key), value, expiry);
|
|
52
|
-
},
|
|
53
|
-
remove: (adapter, key) => {
|
|
54
|
-
return adapter.remove(Storage.encode(key));
|
|
55
|
-
},
|
|
56
|
-
scan: (adapter, prefix) => {
|
|
57
|
-
return adapter.scan(Storage.encode(prefix));
|
|
58
|
-
}
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
//#endregion
|
|
62
|
-
export { Storage, joinKey, splitKey };
|