@parsrun/auth 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/README.md +133 -0
- package/dist/adapters/hono.d.ts +9 -0
- package/dist/adapters/hono.js +6 -0
- package/dist/adapters/hono.js.map +1 -0
- package/dist/adapters/index.d.ts +9 -0
- package/dist/adapters/index.js +7 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/authorization-By1Xp8Za.d.ts +213 -0
- package/dist/base-BKyR8rcE.d.ts +646 -0
- package/dist/chunk-42MGHABB.js +263 -0
- package/dist/chunk-42MGHABB.js.map +1 -0
- package/dist/chunk-7GOBAL4G.js +3 -0
- package/dist/chunk-7GOBAL4G.js.map +1 -0
- package/dist/chunk-G5I3T73A.js +152 -0
- package/dist/chunk-G5I3T73A.js.map +1 -0
- package/dist/chunk-IB4WUQDZ.js +410 -0
- package/dist/chunk-IB4WUQDZ.js.map +1 -0
- package/dist/chunk-MOG4Y6I7.js +415 -0
- package/dist/chunk-MOG4Y6I7.js.map +1 -0
- package/dist/chunk-NK4TJV2W.js +295 -0
- package/dist/chunk-NK4TJV2W.js.map +1 -0
- package/dist/chunk-RHNVRCF3.js +838 -0
- package/dist/chunk-RHNVRCF3.js.map +1 -0
- package/dist/chunk-YTCPXJR5.js +570 -0
- package/dist/chunk-YTCPXJR5.js.map +1 -0
- package/dist/cloudflare-kv-L64CZKDK.js +105 -0
- package/dist/cloudflare-kv-L64CZKDK.js.map +1 -0
- package/dist/deno-kv-F55HKKP6.js +111 -0
- package/dist/deno-kv-F55HKKP6.js.map +1 -0
- package/dist/index-C3kz9XqE.d.ts +226 -0
- package/dist/index-DOGcetyD.d.ts +1041 -0
- package/dist/index.d.ts +1579 -0
- package/dist/index.js +4294 -0
- package/dist/index.js.map +1 -0
- package/dist/jwt-manager-CH8H0kmm.d.ts +182 -0
- package/dist/providers/index.d.ts +90 -0
- package/dist/providers/index.js +3 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/otp/index.d.ts +3 -0
- package/dist/providers/otp/index.js +4 -0
- package/dist/providers/otp/index.js.map +1 -0
- package/dist/redis-5TIS6XCA.js +121 -0
- package/dist/redis-5TIS6XCA.js.map +1 -0
- package/dist/security/index.d.ts +301 -0
- package/dist/security/index.js +5 -0
- package/dist/security/index.js.map +1 -0
- package/dist/session/index.d.ts +117 -0
- package/dist/session/index.js +4 -0
- package/dist/session/index.js.map +1 -0
- package/dist/storage/index.d.ts +97 -0
- package/dist/storage/index.js +3 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/types-DSjafxJ4.d.ts +193 -0
- package/package.json +102 -0
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
// src/utils/runtime.ts
|
|
2
|
+
function detectRuntime() {
|
|
3
|
+
if (typeof globalThis !== "undefined" && // @ts-expect-error - Cloudflare specific global
|
|
4
|
+
typeof globalThis.caches !== "undefined" && // @ts-expect-error - Cloudflare specific
|
|
5
|
+
typeof globalThis.WebSocketPair !== "undefined") {
|
|
6
|
+
return "cloudflare";
|
|
7
|
+
}
|
|
8
|
+
if (typeof Deno !== "undefined") {
|
|
9
|
+
return "deno";
|
|
10
|
+
}
|
|
11
|
+
if (typeof Bun !== "undefined") {
|
|
12
|
+
return "bun";
|
|
13
|
+
}
|
|
14
|
+
if (typeof process !== "undefined" && process.versions && process.versions.node) {
|
|
15
|
+
return "node";
|
|
16
|
+
}
|
|
17
|
+
return "unknown";
|
|
18
|
+
}
|
|
19
|
+
function isRuntime(runtime) {
|
|
20
|
+
return detectRuntime() === runtime;
|
|
21
|
+
}
|
|
22
|
+
function isNode() {
|
|
23
|
+
return isRuntime("node");
|
|
24
|
+
}
|
|
25
|
+
function isDeno() {
|
|
26
|
+
return isRuntime("deno");
|
|
27
|
+
}
|
|
28
|
+
function isCloudflare() {
|
|
29
|
+
return isRuntime("cloudflare");
|
|
30
|
+
}
|
|
31
|
+
function isBun() {
|
|
32
|
+
return isRuntime("bun");
|
|
33
|
+
}
|
|
34
|
+
function isEdge() {
|
|
35
|
+
const runtime = detectRuntime();
|
|
36
|
+
return runtime === "cloudflare" || runtime === "deno";
|
|
37
|
+
}
|
|
38
|
+
function getEnv(key) {
|
|
39
|
+
const runtime = detectRuntime();
|
|
40
|
+
switch (runtime) {
|
|
41
|
+
case "deno":
|
|
42
|
+
return Deno.env.get(key);
|
|
43
|
+
case "node":
|
|
44
|
+
case "bun":
|
|
45
|
+
return process.env[key];
|
|
46
|
+
case "cloudflare":
|
|
47
|
+
return void 0;
|
|
48
|
+
default:
|
|
49
|
+
return void 0;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// src/storage/memory.ts
|
|
54
|
+
var MemoryStorage = class {
|
|
55
|
+
cache;
|
|
56
|
+
maxSize;
|
|
57
|
+
prefix;
|
|
58
|
+
constructor(config) {
|
|
59
|
+
this.cache = /* @__PURE__ */ new Map();
|
|
60
|
+
this.maxSize = config?.maxSize ?? 1e4;
|
|
61
|
+
this.prefix = config?.prefix ?? "";
|
|
62
|
+
}
|
|
63
|
+
getKey(key) {
|
|
64
|
+
return this.prefix ? `${this.prefix}:${key}` : key;
|
|
65
|
+
}
|
|
66
|
+
isExpired(entry) {
|
|
67
|
+
if (entry.expiresAt === null) return false;
|
|
68
|
+
return Date.now() > entry.expiresAt;
|
|
69
|
+
}
|
|
70
|
+
cleanup() {
|
|
71
|
+
for (const [key, entry] of this.cache.entries()) {
|
|
72
|
+
if (this.isExpired(entry)) {
|
|
73
|
+
this.cache.delete(key);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
evictOldest() {
|
|
78
|
+
const firstKey = this.cache.keys().next().value;
|
|
79
|
+
if (firstKey !== void 0) {
|
|
80
|
+
this.cache.delete(firstKey);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
async get(key) {
|
|
84
|
+
const fullKey = this.getKey(key);
|
|
85
|
+
const entry = this.cache.get(fullKey);
|
|
86
|
+
if (!entry) return null;
|
|
87
|
+
if (this.isExpired(entry)) {
|
|
88
|
+
this.cache.delete(fullKey);
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
return entry.value;
|
|
92
|
+
}
|
|
93
|
+
async set(key, value, ttl) {
|
|
94
|
+
const fullKey = this.getKey(key);
|
|
95
|
+
if (this.cache.size >= this.maxSize && !this.cache.has(fullKey)) {
|
|
96
|
+
this.cleanup();
|
|
97
|
+
if (this.cache.size >= this.maxSize) {
|
|
98
|
+
this.evictOldest();
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
const expiresAt = ttl ? Date.now() + ttl * 1e3 : null;
|
|
102
|
+
this.cache.set(fullKey, { value, expiresAt });
|
|
103
|
+
}
|
|
104
|
+
async delete(key) {
|
|
105
|
+
const fullKey = this.getKey(key);
|
|
106
|
+
this.cache.delete(fullKey);
|
|
107
|
+
}
|
|
108
|
+
async has(key) {
|
|
109
|
+
const value = await this.get(key);
|
|
110
|
+
return value !== null;
|
|
111
|
+
}
|
|
112
|
+
async getMany(keys) {
|
|
113
|
+
return Promise.all(keys.map((key) => this.get(key)));
|
|
114
|
+
}
|
|
115
|
+
async setMany(entries) {
|
|
116
|
+
await Promise.all(
|
|
117
|
+
entries.map(([key, value, ttl]) => this.set(key, value, ttl))
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
async deleteMany(keys) {
|
|
121
|
+
await Promise.all(keys.map((key) => this.delete(key)));
|
|
122
|
+
}
|
|
123
|
+
async keys(pattern) {
|
|
124
|
+
this.cleanup();
|
|
125
|
+
const allKeys = [];
|
|
126
|
+
const prefixLength = this.prefix ? this.prefix.length + 1 : 0;
|
|
127
|
+
for (const key of this.cache.keys()) {
|
|
128
|
+
const unprefixedKey = prefixLength ? key.slice(prefixLength) : key;
|
|
129
|
+
if (!pattern || this.matchPattern(unprefixedKey, pattern)) {
|
|
130
|
+
allKeys.push(unprefixedKey);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return allKeys;
|
|
134
|
+
}
|
|
135
|
+
matchPattern(key, pattern) {
|
|
136
|
+
const regex = new RegExp(
|
|
137
|
+
"^" + pattern.replace(/\*/g, ".*").replace(/\?/g, ".") + "$"
|
|
138
|
+
);
|
|
139
|
+
return regex.test(key);
|
|
140
|
+
}
|
|
141
|
+
async clear() {
|
|
142
|
+
if (this.prefix) {
|
|
143
|
+
for (const key of this.cache.keys()) {
|
|
144
|
+
if (key.startsWith(this.prefix + ":")) {
|
|
145
|
+
this.cache.delete(key);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
} else {
|
|
149
|
+
this.cache.clear();
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
async close() {
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Get the current size of the cache
|
|
156
|
+
*/
|
|
157
|
+
get size() {
|
|
158
|
+
return this.cache.size;
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
function createMemoryStorage(config) {
|
|
162
|
+
return new MemoryStorage(config);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// src/storage/index.ts
|
|
166
|
+
var storageLoaders = {
|
|
167
|
+
redis: async () => {
|
|
168
|
+
const { createRedisStorage } = await import('./redis-5TIS6XCA.js');
|
|
169
|
+
return {
|
|
170
|
+
create: (config) => createRedisStorage(config.redis)
|
|
171
|
+
};
|
|
172
|
+
},
|
|
173
|
+
"cloudflare-kv": async () => {
|
|
174
|
+
const { createCloudflareKVStorage } = await import('./cloudflare-kv-L64CZKDK.js');
|
|
175
|
+
return {
|
|
176
|
+
create: async (config) => createCloudflareKVStorage(config.cloudflareKv)
|
|
177
|
+
};
|
|
178
|
+
},
|
|
179
|
+
"deno-kv": async () => {
|
|
180
|
+
const { createDenoKVStorage } = await import('./deno-kv-F55HKKP6.js');
|
|
181
|
+
return {
|
|
182
|
+
create: async (config) => createDenoKVStorage(config.denoKv)
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
function getDefaultStorageType(runtime) {
|
|
187
|
+
switch (runtime) {
|
|
188
|
+
case "cloudflare":
|
|
189
|
+
return "cloudflare-kv";
|
|
190
|
+
case "deno":
|
|
191
|
+
return "deno-kv";
|
|
192
|
+
case "node":
|
|
193
|
+
case "bun":
|
|
194
|
+
return "memory";
|
|
195
|
+
default:
|
|
196
|
+
return "memory";
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
async function createStorage(config) {
|
|
200
|
+
if (config?.custom) {
|
|
201
|
+
return config.custom;
|
|
202
|
+
}
|
|
203
|
+
const runtime = detectRuntime();
|
|
204
|
+
const type = config?.type ?? getDefaultStorageType(runtime);
|
|
205
|
+
if (type === "memory") {
|
|
206
|
+
return createMemoryStorage(config?.memory);
|
|
207
|
+
}
|
|
208
|
+
if (type === "cloudflare-kv" && runtime !== "cloudflare") {
|
|
209
|
+
console.warn(
|
|
210
|
+
"[Pars Auth] Cloudflare KV storage is only available in Cloudflare Workers. Falling back to memory storage."
|
|
211
|
+
);
|
|
212
|
+
return createMemoryStorage(config?.memory);
|
|
213
|
+
}
|
|
214
|
+
if (type === "deno-kv" && runtime !== "deno") {
|
|
215
|
+
console.warn(
|
|
216
|
+
"[Pars Auth] Deno KV storage is only available in Deno. Falling back to memory storage."
|
|
217
|
+
);
|
|
218
|
+
return createMemoryStorage(config?.memory);
|
|
219
|
+
}
|
|
220
|
+
if (type === "redis" && !config?.redis) {
|
|
221
|
+
throw new Error(
|
|
222
|
+
"[Pars Auth] Redis storage requires redis configuration (url or client)"
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
if (type === "cloudflare-kv" && !config?.cloudflareKv?.binding) {
|
|
226
|
+
throw new Error(
|
|
227
|
+
"[Pars Auth] Cloudflare KV storage requires cloudflareKv.binding"
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
const loader = storageLoaders[type];
|
|
231
|
+
if (!loader) {
|
|
232
|
+
throw new Error(`[Pars Auth] Unknown storage type: ${type}`);
|
|
233
|
+
}
|
|
234
|
+
const { create } = await loader();
|
|
235
|
+
return await create(config);
|
|
236
|
+
}
|
|
237
|
+
function createStorageSync(config) {
|
|
238
|
+
if (config?.custom) {
|
|
239
|
+
return config.custom;
|
|
240
|
+
}
|
|
241
|
+
if (config?.type && config.type !== "memory") {
|
|
242
|
+
throw new Error(
|
|
243
|
+
`[Pars Auth] createStorageSync only supports memory storage. Use createStorage() for ${config.type}`
|
|
244
|
+
);
|
|
245
|
+
}
|
|
246
|
+
return createMemoryStorage(config?.memory);
|
|
247
|
+
}
|
|
248
|
+
var StorageKeys = {
|
|
249
|
+
/** OTP storage prefix */
|
|
250
|
+
otp: (identifier, type) => `otp:${type}:${identifier}`,
|
|
251
|
+
/** Rate limit storage prefix */
|
|
252
|
+
rateLimit: (key) => `rate:${key}`,
|
|
253
|
+
/** Session blocklist prefix */
|
|
254
|
+
blocklist: (tokenId) => `block:${tokenId}`,
|
|
255
|
+
/** Magic link token prefix */
|
|
256
|
+
magicLink: (token) => `magic:${token}`,
|
|
257
|
+
/** CSRF token prefix */
|
|
258
|
+
csrf: (sessionId) => `csrf:${sessionId}`
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
export { MemoryStorage, StorageKeys, createMemoryStorage, createStorage, createStorageSync, detectRuntime, getEnv, isBun, isCloudflare, isDeno, isEdge, isNode };
|
|
262
|
+
//# sourceMappingURL=chunk-42MGHABB.js.map
|
|
263
|
+
//# sourceMappingURL=chunk-42MGHABB.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/runtime.ts","../src/storage/memory.ts","../src/storage/index.ts"],"names":[],"mappings":";AAUO,SAAS,aAAA,GAAyB;AAEvC,EAAA,IACE,OAAO,UAAA,KAAe,WAAA;AAAA,EAEtB,OAAO,WAAW,MAAA,KAAW,WAAA;AAAA,EAE7B,OAAO,UAAA,CAAW,aAAA,KAAkB,WAAA,EACpC;AACA,IAAA,OAAO,YAAA;AAAA,EACT;AAIA,EAAA,IAAI,OAAO,SAAS,WAAA,EAAa;AAC/B,IAAA,OAAO,MAAA;AAAA,EACT;AAIA,EAAA,IAAI,OAAO,QAAQ,WAAA,EAAa;AAC9B,IAAA,OAAO,KAAA;AAAA,EACT;AAGA,EAAA,IACE,OAAO,OAAA,KAAY,WAAA,IACnB,QAAQ,QAAA,IACR,OAAA,CAAQ,SAAS,IAAA,EACjB;AACA,IAAA,OAAO,MAAA;AAAA,EACT;AAEA,EAAA,OAAO,SAAA;AACT;AAKO,SAAS,UAAU,OAAA,EAA2B;AACnD,EAAA,OAAO,eAAc,KAAM,OAAA;AAC7B;AAKO,SAAS,MAAA,GAAkB;AAChC,EAAA,OAAO,UAAU,MAAM,CAAA;AACzB;AAKO,SAAS,MAAA,GAAkB;AAChC,EAAA,OAAO,UAAU,MAAM,CAAA;AACzB;AAKO,SAAS,YAAA,GAAwB;AACtC,EAAA,OAAO,UAAU,YAAY,CAAA;AAC/B;AAKO,SAAS,KAAA,GAAiB;AAC/B,EAAA,OAAO,UAAU,KAAK,CAAA;AACxB;AAKO,SAAS,MAAA,GAAkB;AAChC,EAAA,MAAM,UAAU,aAAA,EAAc;AAC9B,EAAA,OAAO,OAAA,KAAY,gBAAgB,OAAA,KAAY,MAAA;AACjD;AAKO,SAAS,OAAO,GAAA,EAAiC;AACtD,EAAA,MAAM,UAAU,aAAA,EAAc;AAE9B,EAAA,QAAQ,OAAA;AAAS,IACf,KAAK,MAAA;AAEH,MAAA,OAAO,IAAA,CAAK,GAAA,CAAI,GAAA,CAAI,GAAG,CAAA;AAAA,IACzB,KAAK,MAAA;AAAA,IACL,KAAK,KAAA;AACH,MAAA,OAAO,OAAA,CAAQ,IAAI,GAAG,CAAA;AAAA,IACxB,KAAK,YAAA;AAGH,MAAA,OAAO,MAAA;AAAA,IACT;AACE,MAAA,OAAO,MAAA;AAAA;AAEb;;;AC9FO,IAAM,gBAAN,MAAyC;AAAA,EACtC,KAAA;AAAA,EACS,OAAA;AAAA,EACA,MAAA;AAAA,EAEjB,YAAY,MAAA,EAAuB;AACjC,IAAA,IAAA,CAAK,KAAA,uBAAY,GAAA,EAAI;AACrB,IAAA,IAAA,CAAK,OAAA,GAAU,QAAQ,OAAA,IAAW,GAAA;AAClC,IAAA,IAAA,CAAK,MAAA,GAAS,QAAQ,MAAA,IAAU,EAAA;AAAA,EAClC;AAAA,EAEQ,OAAO,GAAA,EAAqB;AAClC,IAAA,OAAO,KAAK,MAAA,GAAS,CAAA,EAAG,KAAK,MAAM,CAAA,CAAA,EAAI,GAAG,CAAA,CAAA,GAAK,GAAA;AAAA,EACjD;AAAA,EAEQ,UAAU,KAAA,EAAqC;AACrD,IAAA,IAAI,KAAA,CAAM,SAAA,KAAc,IAAA,EAAM,OAAO,KAAA;AACrC,IAAA,OAAO,IAAA,CAAK,GAAA,EAAI,GAAI,KAAA,CAAM,SAAA;AAAA,EAC5B;AAAA,EAEQ,OAAA,GAAgB;AAEtB,IAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,IAAA,CAAK,KAAA,CAAM,SAAQ,EAAG;AAC/C,MAAA,IAAI,IAAA,CAAK,SAAA,CAAU,KAAK,CAAA,EAAG;AACzB,QAAA,IAAA,CAAK,KAAA,CAAM,OAAO,GAAG,CAAA;AAAA,MACvB;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,WAAA,GAAoB;AAE1B,IAAA,MAAM,WAAW,IAAA,CAAK,KAAA,CAAM,IAAA,EAAK,CAAE,MAAK,CAAE,KAAA;AAC1C,IAAA,IAAI,aAAa,MAAA,EAAW;AAC1B,MAAA,IAAA,CAAK,KAAA,CAAM,OAAO,QAAQ,CAAA;AAAA,IAC5B;AAAA,EACF;AAAA,EAEA,MAAM,IAAiB,GAAA,EAAgC;AACrD,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,MAAA,CAAO,GAAG,CAAA;AAC/B,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,OAAO,CAAA;AAEpC,IAAA,IAAI,CAAC,OAAO,OAAO,IAAA;AAEnB,IAAA,IAAI,IAAA,CAAK,SAAA,CAAU,KAAK,CAAA,EAAG;AACzB,MAAA,IAAA,CAAK,KAAA,CAAM,OAAO,OAAO,CAAA;AACzB,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,OAAO,KAAA,CAAM,KAAA;AAAA,EACf;AAAA,EAEA,MAAM,GAAA,CAAiB,GAAA,EAAa,KAAA,EAAU,GAAA,EAA6B;AACzE,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,MAAA,CAAO,GAAG,CAAA;AAG/B,IAAA,IAAI,IAAA,CAAK,KAAA,CAAM,IAAA,IAAQ,IAAA,CAAK,OAAA,IAAW,CAAC,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,OAAO,CAAA,EAAG;AAC/D,MAAA,IAAA,CAAK,OAAA,EAAQ;AACb,MAAA,IAAI,IAAA,CAAK,KAAA,CAAM,IAAA,IAAQ,IAAA,CAAK,OAAA,EAAS;AACnC,QAAA,IAAA,CAAK,WAAA,EAAY;AAAA,MACnB;AAAA,IACF;AAEA,IAAA,MAAM,YAAY,GAAA,GAAM,IAAA,CAAK,GAAA,EAAI,GAAI,MAAM,GAAA,GAAO,IAAA;AAElD,IAAA,IAAA,CAAK,MAAM,GAAA,CAAI,OAAA,EAAS,EAAE,KAAA,EAAO,WAAW,CAAA;AAAA,EAC9C;AAAA,EAEA,MAAM,OAAO,GAAA,EAA4B;AACvC,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,MAAA,CAAO,GAAG,CAAA;AAC/B,IAAA,IAAA,CAAK,KAAA,CAAM,OAAO,OAAO,CAAA;AAAA,EAC3B;AAAA,EAEA,MAAM,IAAI,GAAA,EAA+B;AACvC,IAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,CAAK,GAAA,CAAI,GAAG,CAAA;AAChC,IAAA,OAAO,KAAA,KAAU,IAAA;AAAA,EACnB;AAAA,EAEA,MAAM,QAAqB,IAAA,EAAuC;AAChE,IAAA,OAAO,OAAA,CAAQ,GAAA,CAAI,IAAA,CAAK,GAAA,CAAI,CAAC,QAAQ,IAAA,CAAK,GAAA,CAAO,GAAG,CAAC,CAAC,CAAA;AAAA,EACxD;AAAA,EAEA,MAAM,QACJ,OAAA,EACe;AACf,IAAA,MAAM,OAAA,CAAQ,GAAA;AAAA,MACZ,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAC,GAAA,EAAK,KAAA,EAAO,GAAG,CAAA,KAAM,IAAA,CAAK,GAAA,CAAI,GAAA,EAAK,KAAA,EAAO,GAAG,CAAC;AAAA,KAC9D;AAAA,EACF;AAAA,EAEA,MAAM,WAAW,IAAA,EAA+B;AAC9C,IAAA,MAAM,OAAA,CAAQ,GAAA,CAAI,IAAA,CAAK,GAAA,CAAI,CAAC,QAAQ,IAAA,CAAK,MAAA,CAAO,GAAG,CAAC,CAAC,CAAA;AAAA,EACvD;AAAA,EAEA,MAAM,KAAK,OAAA,EAAqC;AAC9C,IAAA,IAAA,CAAK,OAAA,EAAQ;AAEb,IAAA,MAAM,UAAoB,EAAC;AAC3B,IAAA,MAAM,eAAe,IAAA,CAAK,MAAA,GAAS,IAAA,CAAK,MAAA,CAAO,SAAS,CAAA,GAAI,CAAA;AAE5D,IAAA,KAAA,MAAW,GAAA,IAAO,IAAA,CAAK,KAAA,CAAM,IAAA,EAAK,EAAG;AACnC,MAAA,MAAM,aAAA,GAAgB,YAAA,GAAe,GAAA,CAAI,KAAA,CAAM,YAAY,CAAA,GAAI,GAAA;AAE/D,MAAA,IAAI,CAAC,OAAA,IAAW,IAAA,CAAK,YAAA,CAAa,aAAA,EAAe,OAAO,CAAA,EAAG;AACzD,QAAA,OAAA,CAAQ,KAAK,aAAa,CAAA;AAAA,MAC5B;AAAA,IACF;AAEA,IAAA,OAAO,OAAA;AAAA,EACT;AAAA,EAEQ,YAAA,CAAa,KAAa,OAAA,EAA0B;AAE1D,IAAA,MAAM,QAAQ,IAAI,MAAA;AAAA,MAChB,GAAA,GAAM,QAAQ,OAAA,CAAQ,KAAA,EAAO,IAAI,CAAA,CAAE,OAAA,CAAQ,KAAA,EAAO,GAAG,CAAA,GAAI;AAAA,KAC3D;AACA,IAAA,OAAO,KAAA,CAAM,KAAK,GAAG,CAAA;AAAA,EACvB;AAAA,EAEA,MAAM,KAAA,GAAuB;AAC3B,IAAA,IAAI,KAAK,MAAA,EAAQ;AAEf,MAAA,KAAA,MAAW,GAAA,IAAO,IAAA,CAAK,KAAA,CAAM,IAAA,EAAK,EAAG;AACnC,QAAA,IAAI,GAAA,CAAI,UAAA,CAAW,IAAA,CAAK,MAAA,GAAS,GAAG,CAAA,EAAG;AACrC,UAAA,IAAA,CAAK,KAAA,CAAM,OAAO,GAAG,CAAA;AAAA,QACvB;AAAA,MACF;AAAA,IACF,CAAA,MAAO;AACL,MAAA,IAAA,CAAK,MAAM,KAAA,EAAM;AAAA,IACnB;AAAA,EACF;AAAA,EAEA,MAAM,KAAA,GAAuB;AAAA,EAE7B;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,IAAA,GAAe;AACjB,IAAA,OAAO,KAAK,KAAA,CAAM,IAAA;AAAA,EACpB;AACF;AAKO,SAAS,oBAAoB,MAAA,EAAkC;AACpE,EAAA,OAAO,IAAI,cAAc,MAAM,CAAA;AACjC;;;ACnJA,IAAM,cAAA,GAGF;AAAA,EACF,OAAO,YAAY;AACjB,IAAA,MAAM,EAAE,kBAAA,EAAmB,GAAI,MAAM,OAAO,qBAAY,CAAA;AACxD,IAAA,OAAO;AAAA,MACL,MAAA,EAAQ,CAAC,MAAA,KAAW,kBAAA,CAAmB,OAAO,KAAM;AAAA,KACtD;AAAA,EACF,CAAA;AAAA,EACA,iBAAiB,YAAY;AAC3B,IAAA,MAAM,EAAE,yBAAA,EAA0B,GAAI,MAAM,OAAO,6BAAoB,CAAA;AACvE,IAAA,OAAO;AAAA,MACL,MAAA,EAAQ,OAAO,MAAA,KAAW,yBAAA,CAA0B,OAAO,YAAa;AAAA,KAC1E;AAAA,EACF,CAAA;AAAA,EACA,WAAW,YAAY;AACrB,IAAA,MAAM,EAAE,mBAAA,EAAoB,GAAI,MAAM,OAAO,uBAAc,CAAA;AAC3D,IAAA,OAAO;AAAA,MACL,MAAA,EAAQ,OAAO,MAAA,KAAW,mBAAA,CAAoB,OAAO,MAAM;AAAA,KAC7D;AAAA,EACF;AACF,CAAA;AAKA,SAAS,sBAAsB,OAAA,EAA+B;AAC5D,EAAA,QAAQ,OAAA;AAAS,IACf,KAAK,YAAA;AACH,MAAA,OAAO,eAAA;AAAA,IACT,KAAK,MAAA;AACH,MAAA,OAAO,SAAA;AAAA,IACT,KAAK,MAAA;AAAA,IACL,KAAK,KAAA;AAEH,MAAA,OAAO,QAAA;AAAA,IACT;AACE,MAAA,OAAO,QAAA;AAAA;AAEb;AA8BA,eAAsB,cAAc,MAAA,EAA4C;AAE9E,EAAA,IAAI,QAAQ,MAAA,EAAQ;AAClB,IAAA,OAAO,MAAA,CAAO,MAAA;AAAA,EAChB;AAEA,EAAA,MAAM,UAAU,aAAA,EAAc;AAC9B,EAAA,MAAM,IAAA,GAAO,MAAA,EAAQ,IAAA,IAAQ,qBAAA,CAAsB,OAAO,CAAA;AAG1D,EAAA,IAAI,SAAS,QAAA,EAAU;AACrB,IAAA,OAAO,mBAAA,CAAoB,QAAQ,MAAM,CAAA;AAAA,EAC3C;AAGA,EAAA,IAAI,IAAA,KAAS,eAAA,IAAmB,OAAA,KAAY,YAAA,EAAc;AACxD,IAAA,OAAA,CAAQ,IAAA;AAAA,MACN;AAAA,KACF;AACA,IAAA,OAAO,mBAAA,CAAoB,QAAQ,MAAM,CAAA;AAAA,EAC3C;AAEA,EAAA,IAAI,IAAA,KAAS,SAAA,IAAa,OAAA,KAAY,MAAA,EAAQ;AAC5C,IAAA,OAAA,CAAQ,IAAA;AAAA,MACN;AAAA,KACF;AACA,IAAA,OAAO,mBAAA,CAAoB,QAAQ,MAAM,CAAA;AAAA,EAC3C;AAGA,EAAA,IAAI,IAAA,KAAS,OAAA,IAAW,CAAC,MAAA,EAAQ,KAAA,EAAO;AACtC,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AAEA,EAAA,IAAI,IAAA,KAAS,eAAA,IAAmB,CAAC,MAAA,EAAQ,cAAc,OAAA,EAAS;AAC9D,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AAGA,EAAA,MAAM,MAAA,GAAS,eAAe,IAAmC,CAAA;AACjE,EAAA,IAAI,CAAC,MAAA,EAAQ;AACX,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,kCAAA,EAAqC,IAAI,CAAA,CAAE,CAAA;AAAA,EAC7D;AAEA,EAAA,MAAM,EAAE,MAAA,EAAO,GAAI,MAAM,MAAA,EAAO;AAChC,EAAA,OAAO,MAAM,OAAO,MAAO,CAAA;AAC7B;AAMO,SAAS,kBAAkB,MAAA,EAAmC;AACnE,EAAA,IAAI,QAAQ,MAAA,EAAQ;AAClB,IAAA,OAAO,MAAA,CAAO,MAAA;AAAA,EAChB;AAEA,EAAA,IAAI,MAAA,EAAQ,IAAA,IAAQ,MAAA,CAAO,IAAA,KAAS,QAAA,EAAU;AAC5C,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,oFAAA,EAAuF,OAAO,IAAI,CAAA;AAAA,KACpG;AAAA,EACF;AAEA,EAAA,OAAO,mBAAA,CAAoB,QAAQ,MAAM,CAAA;AAC3C;AAKO,IAAM,WAAA,GAAc;AAAA;AAAA,EAEzB,KAAK,CAAC,UAAA,EAAoB,SAAiB,CAAA,IAAA,EAAO,IAAI,IAAI,UAAU,CAAA,CAAA;AAAA;AAAA,EAEpE,SAAA,EAAW,CAAC,GAAA,KAAgB,CAAA,KAAA,EAAQ,GAAG,CAAA,CAAA;AAAA;AAAA,EAEvC,SAAA,EAAW,CAAC,OAAA,KAAoB,CAAA,MAAA,EAAS,OAAO,CAAA,CAAA;AAAA;AAAA,EAEhD,SAAA,EAAW,CAAC,KAAA,KAAkB,CAAA,MAAA,EAAS,KAAK,CAAA,CAAA;AAAA;AAAA,EAE5C,IAAA,EAAM,CAAC,SAAA,KAAsB,CAAA,KAAA,EAAQ,SAAS,CAAA;AAChD","file":"chunk-42MGHABB.js","sourcesContent":["/**\n * Runtime detection utilities for multi-runtime support\n * Supports: Node.js, Deno, Cloudflare Workers, Bun\n */\n\nexport type Runtime = 'node' | 'deno' | 'cloudflare' | 'bun' | 'unknown';\n\n/**\n * Detect the current JavaScript runtime environment\n */\nexport function detectRuntime(): Runtime {\n // Cloudflare Workers\n if (\n typeof globalThis !== 'undefined' &&\n // @ts-expect-error - Cloudflare specific global\n typeof globalThis.caches !== 'undefined' &&\n // @ts-expect-error - Cloudflare specific\n typeof globalThis.WebSocketPair !== 'undefined'\n ) {\n return 'cloudflare';\n }\n\n // Deno\n // @ts-expect-error - Deno specific global\n if (typeof Deno !== 'undefined') {\n return 'deno';\n }\n\n // Bun\n // @ts-expect-error - Bun specific global\n if (typeof Bun !== 'undefined') {\n return 'bun';\n }\n\n // Node.js\n if (\n typeof process !== 'undefined' &&\n process.versions &&\n process.versions.node\n ) {\n return 'node';\n }\n\n return 'unknown';\n}\n\n/**\n * Check if running in a specific runtime\n */\nexport function isRuntime(runtime: Runtime): boolean {\n return detectRuntime() === runtime;\n}\n\n/**\n * Check if running in Node.js\n */\nexport function isNode(): boolean {\n return isRuntime('node');\n}\n\n/**\n * Check if running in Deno\n */\nexport function isDeno(): boolean {\n return isRuntime('deno');\n}\n\n/**\n * Check if running in Cloudflare Workers\n */\nexport function isCloudflare(): boolean {\n return isRuntime('cloudflare');\n}\n\n/**\n * Check if running in Bun\n */\nexport function isBun(): boolean {\n return isRuntime('bun');\n}\n\n/**\n * Check if running in an edge runtime (CF Workers, Deno Deploy, etc.)\n */\nexport function isEdge(): boolean {\n const runtime = detectRuntime();\n return runtime === 'cloudflare' || runtime === 'deno';\n}\n\n/**\n * Get environment variable across runtimes\n */\nexport function getEnv(key: string): string | undefined {\n const runtime = detectRuntime();\n\n switch (runtime) {\n case 'deno':\n // @ts-expect-error - Deno specific\n return Deno.env.get(key);\n case 'node':\n case 'bun':\n return process.env[key];\n case 'cloudflare':\n // In CF Workers, env is passed to the handler\n // This is a fallback for global env\n return undefined;\n default:\n return undefined;\n }\n}\n","/**\n * In-memory KV Storage adapter\n * Suitable for development, testing, and single-instance deployments\n */\n\nimport type { KVStorage, MemoryConfig } from './types.js';\n\ninterface CacheEntry<T> {\n value: T;\n expiresAt: number | null;\n}\n\n/**\n * In-memory storage with TTL support and LRU eviction\n */\nexport class MemoryStorage implements KVStorage {\n private cache: Map<string, CacheEntry<unknown>>;\n private readonly maxSize: number;\n private readonly prefix: string;\n\n constructor(config?: MemoryConfig) {\n this.cache = new Map();\n this.maxSize = config?.maxSize ?? 10000;\n this.prefix = config?.prefix ?? '';\n }\n\n private getKey(key: string): string {\n return this.prefix ? `${this.prefix}:${key}` : key;\n }\n\n private isExpired(entry: CacheEntry<unknown>): boolean {\n if (entry.expiresAt === null) return false;\n return Date.now() > entry.expiresAt;\n }\n\n private cleanup(): void {\n // Remove expired entries\n for (const [key, entry] of this.cache.entries()) {\n if (this.isExpired(entry)) {\n this.cache.delete(key);\n }\n }\n }\n\n private evictOldest(): void {\n // Simple FIFO eviction (Map maintains insertion order)\n const firstKey = this.cache.keys().next().value;\n if (firstKey !== undefined) {\n this.cache.delete(firstKey);\n }\n }\n\n async get<T = unknown>(key: string): Promise<T | null> {\n const fullKey = this.getKey(key);\n const entry = this.cache.get(fullKey) as CacheEntry<T> | undefined;\n\n if (!entry) return null;\n\n if (this.isExpired(entry)) {\n this.cache.delete(fullKey);\n return null;\n }\n\n return entry.value;\n }\n\n async set<T = unknown>(key: string, value: T, ttl?: number): Promise<void> {\n const fullKey = this.getKey(key);\n\n // Evict if at capacity\n if (this.cache.size >= this.maxSize && !this.cache.has(fullKey)) {\n this.cleanup();\n if (this.cache.size >= this.maxSize) {\n this.evictOldest();\n }\n }\n\n const expiresAt = ttl ? Date.now() + ttl * 1000 : null;\n\n this.cache.set(fullKey, { value, expiresAt });\n }\n\n async delete(key: string): Promise<void> {\n const fullKey = this.getKey(key);\n this.cache.delete(fullKey);\n }\n\n async has(key: string): Promise<boolean> {\n const value = await this.get(key);\n return value !== null;\n }\n\n async getMany<T = unknown>(keys: string[]): Promise<(T | null)[]> {\n return Promise.all(keys.map((key) => this.get<T>(key)));\n }\n\n async setMany<T = unknown>(\n entries: Array<[key: string, value: T, ttl?: number]>\n ): Promise<void> {\n await Promise.all(\n entries.map(([key, value, ttl]) => this.set(key, value, ttl))\n );\n }\n\n async deleteMany(keys: string[]): Promise<void> {\n await Promise.all(keys.map((key) => this.delete(key)));\n }\n\n async keys(pattern?: string): Promise<string[]> {\n this.cleanup();\n\n const allKeys: string[] = [];\n const prefixLength = this.prefix ? this.prefix.length + 1 : 0;\n\n for (const key of this.cache.keys()) {\n const unprefixedKey = prefixLength ? key.slice(prefixLength) : key;\n\n if (!pattern || this.matchPattern(unprefixedKey, pattern)) {\n allKeys.push(unprefixedKey);\n }\n }\n\n return allKeys;\n }\n\n private matchPattern(key: string, pattern: string): boolean {\n // Simple glob pattern matching (* = any characters)\n const regex = new RegExp(\n '^' + pattern.replace(/\\*/g, '.*').replace(/\\?/g, '.') + '$'\n );\n return regex.test(key);\n }\n\n async clear(): Promise<void> {\n if (this.prefix) {\n // Only clear keys with our prefix\n for (const key of this.cache.keys()) {\n if (key.startsWith(this.prefix + ':')) {\n this.cache.delete(key);\n }\n }\n } else {\n this.cache.clear();\n }\n }\n\n async close(): Promise<void> {\n // No-op for memory storage\n }\n\n /**\n * Get the current size of the cache\n */\n get size(): number {\n return this.cache.size;\n }\n}\n\n/**\n * Create a new memory storage instance\n */\nexport function createMemoryStorage(config?: MemoryConfig): KVStorage {\n return new MemoryStorage(config);\n}\n","/**\n * Multi-runtime Storage Factory\n * Auto-detects runtime and creates appropriate storage adapter\n */\n\nimport { detectRuntime, type Runtime } from '../utils/runtime.js';\nimport type { KVStorage, StorageConfig, StorageType } from './types.js';\nimport { createMemoryStorage } from './memory.js';\n\n// Re-export types\nexport * from './types.js';\nexport { MemoryStorage, createMemoryStorage } from './memory.js';\n\n/**\n * Lazy-loaded storage adapters to avoid bundling unused code\n */\nconst storageLoaders: Record<\n Exclude<StorageType, 'memory' | 'custom'>,\n () => Promise<{ create: (config: StorageConfig) => Promise<KVStorage> }>\n> = {\n redis: async () => {\n const { createRedisStorage } = await import('./redis.js');\n return {\n create: (config) => createRedisStorage(config.redis!),\n };\n },\n 'cloudflare-kv': async () => {\n const { createCloudflareKVStorage } = await import('./cloudflare-kv.js');\n return {\n create: async (config) => createCloudflareKVStorage(config.cloudflareKv!),\n };\n },\n 'deno-kv': async () => {\n const { createDenoKVStorage } = await import('./deno-kv.js');\n return {\n create: async (config) => createDenoKVStorage(config.denoKv),\n };\n },\n};\n\n/**\n * Map runtime to default storage type\n */\nfunction getDefaultStorageType(runtime: Runtime): StorageType {\n switch (runtime) {\n case 'cloudflare':\n return 'cloudflare-kv';\n case 'deno':\n return 'deno-kv';\n case 'node':\n case 'bun':\n // Default to memory for Node/Bun, user should configure Redis for production\n return 'memory';\n default:\n return 'memory';\n }\n}\n\n/**\n * Create a storage adapter based on configuration\n * Auto-detects runtime if type is not specified\n *\n * @example\n * ```ts\n * // Auto-detect (uses Deno KV on Deno, CF KV on Workers, Memory otherwise)\n * const storage = await createStorage();\n *\n * // Explicit Redis\n * const storage = await createStorage({\n * type: 'redis',\n * redis: { url: 'redis://localhost:6379' }\n * });\n *\n * // Cloudflare KV\n * const storage = await createStorage({\n * type: 'cloudflare-kv',\n * cloudflareKv: { binding: env.MY_KV }\n * });\n *\n * // Custom adapter\n * const storage = await createStorage({\n * type: 'custom',\n * custom: myCustomAdapter\n * });\n * ```\n */\nexport async function createStorage(config?: StorageConfig): Promise<KVStorage> {\n // Custom adapter takes precedence\n if (config?.custom) {\n return config.custom;\n }\n\n const runtime = detectRuntime();\n const type = config?.type ?? getDefaultStorageType(runtime);\n\n // Memory storage (sync)\n if (type === 'memory') {\n return createMemoryStorage(config?.memory);\n }\n\n // Validate runtime compatibility\n if (type === 'cloudflare-kv' && runtime !== 'cloudflare') {\n console.warn(\n '[Pars Auth] Cloudflare KV storage is only available in Cloudflare Workers. Falling back to memory storage.'\n );\n return createMemoryStorage(config?.memory);\n }\n\n if (type === 'deno-kv' && runtime !== 'deno') {\n console.warn(\n '[Pars Auth] Deno KV storage is only available in Deno. Falling back to memory storage.'\n );\n return createMemoryStorage(config?.memory);\n }\n\n // Validate config presence\n if (type === 'redis' && !config?.redis) {\n throw new Error(\n '[Pars Auth] Redis storage requires redis configuration (url or client)'\n );\n }\n\n if (type === 'cloudflare-kv' && !config?.cloudflareKv?.binding) {\n throw new Error(\n '[Pars Auth] Cloudflare KV storage requires cloudflareKv.binding'\n );\n }\n\n // Load and create the storage adapter\n const loader = storageLoaders[type as keyof typeof storageLoaders];\n if (!loader) {\n throw new Error(`[Pars Auth] Unknown storage type: ${type}`);\n }\n\n const { create } = await loader();\n return await create(config!);\n}\n\n/**\n * Create storage synchronously (only for memory storage)\n * Use createStorage() for other adapters\n */\nexport function createStorageSync(config?: StorageConfig): KVStorage {\n if (config?.custom) {\n return config.custom;\n }\n\n if (config?.type && config.type !== 'memory') {\n throw new Error(\n `[Pars Auth] createStorageSync only supports memory storage. Use createStorage() for ${config.type}`\n );\n }\n\n return createMemoryStorage(config?.memory);\n}\n\n/**\n * Storage key prefixes for different purposes\n */\nexport const StorageKeys = {\n /** OTP storage prefix */\n otp: (identifier: string, type: string) => `otp:${type}:${identifier}`,\n /** Rate limit storage prefix */\n rateLimit: (key: string) => `rate:${key}`,\n /** Session blocklist prefix */\n blocklist: (tokenId: string) => `block:${tokenId}`,\n /** Magic link token prefix */\n magicLink: (token: string) => `magic:${token}`,\n /** CSRF token prefix */\n csrf: (sessionId: string) => `csrf:${sessionId}`,\n} as const;\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-7GOBAL4G.js"}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
// src/providers/base.ts
|
|
2
|
+
var BaseProvider = class {
|
|
3
|
+
config;
|
|
4
|
+
_enabled = false;
|
|
5
|
+
get enabled() {
|
|
6
|
+
return this._enabled;
|
|
7
|
+
}
|
|
8
|
+
async initialize(config) {
|
|
9
|
+
this.config = config;
|
|
10
|
+
}
|
|
11
|
+
getInfo() {
|
|
12
|
+
return {
|
|
13
|
+
name: this.name,
|
|
14
|
+
type: this.type,
|
|
15
|
+
enabled: this.enabled
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
// src/providers/index.ts
|
|
21
|
+
var ProviderRegistry = class {
|
|
22
|
+
providers = /* @__PURE__ */ new Map();
|
|
23
|
+
/**
|
|
24
|
+
* Register a provider
|
|
25
|
+
*/
|
|
26
|
+
register(provider) {
|
|
27
|
+
if (this.providers.has(provider.name)) {
|
|
28
|
+
console.warn(
|
|
29
|
+
`[Pars Auth] Provider "${provider.name}" is already registered. Overwriting.`
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
this.providers.set(provider.name, provider);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Unregister a provider
|
|
36
|
+
*/
|
|
37
|
+
unregister(name) {
|
|
38
|
+
return this.providers.delete(name);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Get a provider by name
|
|
42
|
+
*/
|
|
43
|
+
get(name) {
|
|
44
|
+
return this.providers.get(name);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Get a provider by name (throws if not found)
|
|
48
|
+
*/
|
|
49
|
+
getOrThrow(name) {
|
|
50
|
+
const provider = this.providers.get(name);
|
|
51
|
+
if (!provider) {
|
|
52
|
+
throw new Error(`[Pars Auth] Provider "${name}" not found`);
|
|
53
|
+
}
|
|
54
|
+
return provider;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Check if a provider is registered
|
|
58
|
+
*/
|
|
59
|
+
has(name) {
|
|
60
|
+
return this.providers.has(name);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Get all providers of a specific type
|
|
64
|
+
*/
|
|
65
|
+
getByType(type) {
|
|
66
|
+
return Array.from(this.providers.values()).filter((p) => p.type === type);
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Get all enabled providers
|
|
70
|
+
*/
|
|
71
|
+
getEnabled() {
|
|
72
|
+
return Array.from(this.providers.values()).filter((p) => p.enabled);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Get all enabled providers of a specific type
|
|
76
|
+
*/
|
|
77
|
+
getEnabledByType(type) {
|
|
78
|
+
return this.getEnabled().filter((p) => p.type === type);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Get all registered providers
|
|
82
|
+
*/
|
|
83
|
+
getAll() {
|
|
84
|
+
return Array.from(this.providers.values());
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Get provider names
|
|
88
|
+
*/
|
|
89
|
+
getNames() {
|
|
90
|
+
return Array.from(this.providers.keys());
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Get provider info for all providers
|
|
94
|
+
*/
|
|
95
|
+
getInfo() {
|
|
96
|
+
return Array.from(this.providers.values()).map((p) => p.getInfo());
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Get OAuth providers
|
|
100
|
+
*/
|
|
101
|
+
getOAuthProviders() {
|
|
102
|
+
return this.getByType("oauth");
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Get 2FA providers
|
|
106
|
+
*/
|
|
107
|
+
getTwoFactorProviders() {
|
|
108
|
+
return [
|
|
109
|
+
...this.getByType("totp"),
|
|
110
|
+
...this.getByType("webauthn")
|
|
111
|
+
];
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Check if a provider type is enabled
|
|
115
|
+
*/
|
|
116
|
+
isTypeEnabled(type) {
|
|
117
|
+
return this.getEnabledByType(type).length > 0;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Get the primary authentication provider
|
|
121
|
+
* Returns the first enabled provider in order: otp > magic-link > oauth > password
|
|
122
|
+
*/
|
|
123
|
+
getPrimary() {
|
|
124
|
+
const priority = ["otp", "magic-link", "oauth", "password"];
|
|
125
|
+
for (const type of priority) {
|
|
126
|
+
const enabled = this.getEnabledByType(type);
|
|
127
|
+
if (enabled.length > 0) {
|
|
128
|
+
return enabled[0];
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return void 0;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Clear all providers
|
|
135
|
+
*/
|
|
136
|
+
clear() {
|
|
137
|
+
this.providers.clear();
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Get provider count
|
|
141
|
+
*/
|
|
142
|
+
get size() {
|
|
143
|
+
return this.providers.size;
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
function createProviderRegistry() {
|
|
147
|
+
return new ProviderRegistry();
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export { BaseProvider, ProviderRegistry, createProviderRegistry };
|
|
151
|
+
//# sourceMappingURL=chunk-G5I3T73A.js.map
|
|
152
|
+
//# sourceMappingURL=chunk-G5I3T73A.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/providers/base.ts","../src/providers/index.ts"],"names":[],"mappings":"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","file":"chunk-G5I3T73A.js","sourcesContent":["/**\n * Base provider types and interfaces\n * All auth providers must implement these interfaces\n */\n\nimport type { ParsAuthConfig, AdapterUser, AdapterSession } from '../config.js';\n\n/**\n * Provider types\n */\nexport type ProviderType =\n | 'otp' // Email/SMS OTP\n | 'magic-link' // Email magic links\n | 'oauth' // OAuth providers (Google, GitHub, etc.)\n | 'totp' // 2FA TOTP (Google Authenticator)\n | 'webauthn' // WebAuthn/Passkeys\n | 'password'; // Password (disabled by default)\n\n/**\n * Provider metadata\n */\nexport interface ProviderInfo {\n /** Provider unique name */\n name: string;\n /** Provider type */\n type: ProviderType;\n /** Whether the provider is enabled */\n enabled: boolean;\n /** Human-readable display name */\n displayName?: string;\n /** Provider icon URL */\n icon?: string;\n}\n\n/**\n * Authentication input (varies by provider)\n */\nexport interface AuthInput {\n /** User identifier (email, phone, username) */\n identifier?: string;\n /** Credential (OTP code, password, OAuth code, etc.) */\n credential?: string;\n /** Tenant ID for multi-tenant apps */\n tenantId?: string;\n /** Provider-specific data */\n data?: Record<string, unknown>;\n}\n\n/**\n * Authentication result\n */\nexport interface AuthResult {\n /** Whether authentication was successful */\n success: boolean;\n /** Authenticated user (if successful) */\n user?: AdapterUser;\n /** Session (if created) */\n session?: AdapterSession;\n /** Whether this is a new user */\n isNewUser?: boolean;\n /** Whether 2FA is required */\n requiresTwoFactor?: boolean;\n /** 2FA challenge data */\n twoFactorChallenge?: {\n type: 'totp' | 'webauthn' | 'sms';\n challengeId?: string;\n };\n /** Error message (if failed) */\n error?: string;\n /** Error code (if failed) */\n errorCode?: string;\n}\n\n/**\n * Verification input\n */\nexport interface VerifyInput {\n /** Verification target (email, phone) */\n identifier: string;\n /** Verification type */\n type: 'email' | 'sms';\n /** Verification code or token */\n code: string;\n /** Tenant ID */\n tenantId?: string;\n}\n\n/**\n * Verification result\n */\nexport interface VerifyResult {\n /** Whether verification was successful */\n success: boolean;\n /** Remaining attempts (if failed) */\n attemptsLeft?: number;\n /** Error message */\n error?: string;\n}\n\n/**\n * Base auth provider interface\n * All providers must implement this interface\n */\nexport interface AuthProvider {\n /** Provider unique name (e.g., 'email-otp', 'google', 'password') */\n readonly name: string;\n\n /** Provider type */\n readonly type: ProviderType;\n\n /** Whether the provider is currently enabled */\n readonly enabled: boolean;\n\n /**\n * Initialize the provider with config\n * Called once during auth system setup\n */\n initialize?(config: ParsAuthConfig): Promise<void>;\n\n /**\n * Authenticate a user\n * This is the main authentication entry point\n */\n authenticate(input: AuthInput): Promise<AuthResult>;\n\n /**\n * Verify a code/token (optional)\n * Used by OTP, magic link, etc.\n */\n verify?(input: VerifyInput): Promise<VerifyResult>;\n\n /**\n * Get provider info for display\n */\n getInfo(): ProviderInfo;\n}\n\n/**\n * Two-factor auth provider interface\n * Extends base provider for 2FA capabilities\n */\nexport interface TwoFactorProvider extends AuthProvider {\n /** Provider type is always 'totp' or 'webauthn' for 2FA */\n readonly type: 'totp' | 'webauthn';\n\n /**\n * Setup 2FA for a user\n * Returns setup data (QR code, backup codes, etc.)\n */\n setup(userId: string): Promise<TwoFactorSetupResult>;\n\n /**\n * Verify 2FA and complete setup\n */\n verifySetup(userId: string, code: string): Promise<boolean>;\n\n /**\n * Verify 2FA during login\n */\n verifyLogin(userId: string, code: string): Promise<boolean>;\n\n /**\n * Disable 2FA for a user\n */\n disable(userId: string): Promise<void>;\n}\n\n/**\n * 2FA setup result\n */\nexport interface TwoFactorSetupResult {\n /** Secret key (for TOTP) */\n secret?: string;\n /** QR code data URL */\n qrCode?: string;\n /** Backup codes */\n backupCodes?: string[];\n /** WebAuthn challenge */\n challenge?: string;\n}\n\n/**\n * OAuth provider interface\n * Extends base provider for OAuth flows\n */\nexport interface OAuthProvider extends AuthProvider {\n /** Provider type is always 'oauth' */\n readonly type: 'oauth';\n\n /**\n * Get OAuth authorization URL\n */\n getAuthorizationUrl(state: string, codeVerifier?: string): Promise<string>;\n\n /**\n * Exchange authorization code for tokens\n */\n exchangeCode(\n code: string,\n codeVerifier?: string\n ): Promise<{\n accessToken: string;\n refreshToken?: string;\n expiresIn?: number;\n idToken?: string;\n }>;\n\n /**\n * Get user info from OAuth provider\n */\n getUserInfo(accessToken: string): Promise<OAuthUserInfo>;\n}\n\n/**\n * OAuth user info\n */\nexport interface OAuthUserInfo {\n /** Provider-specific user ID */\n id: string;\n /** User email */\n email?: string;\n /** Whether email is verified */\n emailVerified?: boolean;\n /** User name */\n name?: string;\n /** Avatar URL */\n avatar?: string;\n /** Raw provider data */\n raw?: Record<string, unknown>;\n}\n\n/**\n * Abstract base class for providers\n * Provides common functionality\n */\nexport abstract class BaseProvider implements AuthProvider {\n abstract readonly name: string;\n abstract readonly type: ProviderType;\n\n protected config?: ParsAuthConfig;\n protected _enabled: boolean = false;\n\n get enabled(): boolean {\n return this._enabled;\n }\n\n async initialize(config: ParsAuthConfig): Promise<void> {\n this.config = config;\n }\n\n abstract authenticate(input: AuthInput): Promise<AuthResult>;\n\n getInfo(): ProviderInfo {\n return {\n name: this.name,\n type: this.type,\n enabled: this.enabled,\n };\n }\n}\n","/**\n * Provider Registry\n * Manages authentication providers\n */\n\nimport type {\n AuthProvider,\n ProviderType,\n ProviderInfo,\n OAuthProvider,\n TwoFactorProvider,\n} from './base.js';\n\n// Re-export base types\nexport * from './base.js';\n\n/**\n * Provider registry for managing auth providers\n */\nexport class ProviderRegistry {\n private providers: Map<string, AuthProvider> = new Map();\n\n /**\n * Register a provider\n */\n register(provider: AuthProvider): void {\n if (this.providers.has(provider.name)) {\n console.warn(\n `[Pars Auth] Provider \"${provider.name}\" is already registered. Overwriting.`\n );\n }\n this.providers.set(provider.name, provider);\n }\n\n /**\n * Unregister a provider\n */\n unregister(name: string): boolean {\n return this.providers.delete(name);\n }\n\n /**\n * Get a provider by name\n */\n get(name: string): AuthProvider | undefined {\n return this.providers.get(name);\n }\n\n /**\n * Get a provider by name (throws if not found)\n */\n getOrThrow(name: string): AuthProvider {\n const provider = this.providers.get(name);\n if (!provider) {\n throw new Error(`[Pars Auth] Provider \"${name}\" not found`);\n }\n return provider;\n }\n\n /**\n * Check if a provider is registered\n */\n has(name: string): boolean {\n return this.providers.has(name);\n }\n\n /**\n * Get all providers of a specific type\n */\n getByType(type: ProviderType): AuthProvider[] {\n return Array.from(this.providers.values()).filter((p) => p.type === type);\n }\n\n /**\n * Get all enabled providers\n */\n getEnabled(): AuthProvider[] {\n return Array.from(this.providers.values()).filter((p) => p.enabled);\n }\n\n /**\n * Get all enabled providers of a specific type\n */\n getEnabledByType(type: ProviderType): AuthProvider[] {\n return this.getEnabled().filter((p) => p.type === type);\n }\n\n /**\n * Get all registered providers\n */\n getAll(): AuthProvider[] {\n return Array.from(this.providers.values());\n }\n\n /**\n * Get provider names\n */\n getNames(): string[] {\n return Array.from(this.providers.keys());\n }\n\n /**\n * Get provider info for all providers\n */\n getInfo(): ProviderInfo[] {\n return Array.from(this.providers.values()).map((p) => p.getInfo());\n }\n\n /**\n * Get OAuth providers\n */\n getOAuthProviders(): OAuthProvider[] {\n return this.getByType('oauth') as OAuthProvider[];\n }\n\n /**\n * Get 2FA providers\n */\n getTwoFactorProviders(): TwoFactorProvider[] {\n return [\n ...this.getByType('totp'),\n ...this.getByType('webauthn'),\n ] as TwoFactorProvider[];\n }\n\n /**\n * Check if a provider type is enabled\n */\n isTypeEnabled(type: ProviderType): boolean {\n return this.getEnabledByType(type).length > 0;\n }\n\n /**\n * Get the primary authentication provider\n * Returns the first enabled provider in order: otp > magic-link > oauth > password\n */\n getPrimary(): AuthProvider | undefined {\n const priority: ProviderType[] = ['otp', 'magic-link', 'oauth', 'password'];\n\n for (const type of priority) {\n const enabled = this.getEnabledByType(type);\n if (enabled.length > 0) {\n return enabled[0];\n }\n }\n\n return undefined;\n }\n\n /**\n * Clear all providers\n */\n clear(): void {\n this.providers.clear();\n }\n\n /**\n * Get provider count\n */\n get size(): number {\n return this.providers.size;\n }\n}\n\n/**\n * Create a new provider registry\n */\nexport function createProviderRegistry(): ProviderRegistry {\n return new ProviderRegistry();\n}\n"]}
|