@happyvertical/auth 0.74.8
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/AGENT.md +33 -0
- package/LICENSE +7 -0
- package/README.md +73 -0
- package/dist/chunks/cognito-dmypylFX.js +128 -0
- package/dist/chunks/cognito-dmypylFX.js.map +1 -0
- package/dist/chunks/decode_jwt-D2OK1b8a.js +1395 -0
- package/dist/chunks/decode_jwt-D2OK1b8a.js.map +1 -0
- package/dist/chunks/github-NSZp5tVm.js +413 -0
- package/dist/chunks/github-NSZp5tVm.js.map +1 -0
- package/dist/chunks/google-HXk2ctYR.js +483 -0
- package/dist/chunks/google-HXk2ctYR.js.map +1 -0
- package/dist/chunks/index-BpsMhFXS.js +151 -0
- package/dist/chunks/index-BpsMhFXS.js.map +1 -0
- package/dist/chunks/kanidm-hkw-YPVF.js +747 -0
- package/dist/chunks/kanidm-hkw-YPVF.js.map +1 -0
- package/dist/chunks/keycloak-t6JEUeOz.js +871 -0
- package/dist/chunks/keycloak-t6JEUeOz.js.map +1 -0
- package/dist/cli/claude-context.d.ts +3 -0
- package/dist/cli/claude-context.d.ts.map +1 -0
- package/dist/cli/claude-context.js +21 -0
- package/dist/cli/claude-context.js.map +1 -0
- package/dist/index.d.ts +65 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +499 -0
- package/dist/index.js.map +1 -0
- package/dist/shared/errors.d.ts +227 -0
- package/dist/shared/errors.d.ts.map +1 -0
- package/dist/shared/factory.d.ts +85 -0
- package/dist/shared/factory.d.ts.map +1 -0
- package/dist/shared/providers/cognito.d.ts +38 -0
- package/dist/shared/providers/cognito.d.ts.map +1 -0
- package/dist/shared/providers/github.d.ts +65 -0
- package/dist/shared/providers/github.d.ts.map +1 -0
- package/dist/shared/providers/google.d.ts +58 -0
- package/dist/shared/providers/google.d.ts.map +1 -0
- package/dist/shared/providers/kanidm.d.ts +78 -0
- package/dist/shared/providers/kanidm.d.ts.map +1 -0
- package/dist/shared/providers/keycloak.d.ts +67 -0
- package/dist/shared/providers/keycloak.d.ts.map +1 -0
- package/dist/shared/providers/nostr/index.d.ts +47 -0
- package/dist/shared/providers/nostr/index.d.ts.map +1 -0
- package/dist/shared/types.d.ts +812 -0
- package/dist/shared/types.d.ts.map +1 -0
- package/metadata.json +32 -0
- package/package.json +60 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,499 @@
|
|
|
1
|
+
import { loadEnvConfig, ValidationError } from "@happyvertical/utils";
|
|
2
|
+
var AuthErrorCode = /* @__PURE__ */ ((AuthErrorCode2) => {
|
|
3
|
+
AuthErrorCode2["INVALID_CREDENTIALS"] = "INVALID_CREDENTIALS";
|
|
4
|
+
AuthErrorCode2["INVALID_TOKEN"] = "INVALID_TOKEN";
|
|
5
|
+
AuthErrorCode2["TOKEN_EXPIRED"] = "TOKEN_EXPIRED";
|
|
6
|
+
AuthErrorCode2["INVALID_REFRESH_TOKEN"] = "INVALID_REFRESH_TOKEN";
|
|
7
|
+
AuthErrorCode2["SESSION_EXPIRED"] = "SESSION_EXPIRED";
|
|
8
|
+
AuthErrorCode2["MFA_REQUIRED"] = "MFA_REQUIRED";
|
|
9
|
+
AuthErrorCode2["INVALID_MFA_CODE"] = "INVALID_MFA_CODE";
|
|
10
|
+
AuthErrorCode2["ACCESS_DENIED"] = "ACCESS_DENIED";
|
|
11
|
+
AuthErrorCode2["INSUFFICIENT_SCOPE"] = "INSUFFICIENT_SCOPE";
|
|
12
|
+
AuthErrorCode2["INVALID_ROLE"] = "INVALID_ROLE";
|
|
13
|
+
AuthErrorCode2["USER_NOT_FOUND"] = "USER_NOT_FOUND";
|
|
14
|
+
AuthErrorCode2["USER_ALREADY_EXISTS"] = "USER_ALREADY_EXISTS";
|
|
15
|
+
AuthErrorCode2["USER_DISABLED"] = "USER_DISABLED";
|
|
16
|
+
AuthErrorCode2["PROVIDER_ERROR"] = "PROVIDER_ERROR";
|
|
17
|
+
AuthErrorCode2["CONFIGURATION_ERROR"] = "CONFIGURATION_ERROR";
|
|
18
|
+
AuthErrorCode2["NETWORK_ERROR"] = "NETWORK_ERROR";
|
|
19
|
+
AuthErrorCode2["INVALID_STATE"] = "INVALID_STATE";
|
|
20
|
+
AuthErrorCode2["INVALID_NONCE"] = "INVALID_NONCE";
|
|
21
|
+
AuthErrorCode2["INVALID_GRANT"] = "INVALID_GRANT";
|
|
22
|
+
AuthErrorCode2["INVALID_CLIENT"] = "INVALID_CLIENT";
|
|
23
|
+
AuthErrorCode2["INVALID_REDIRECT_URI"] = "INVALID_REDIRECT_URI";
|
|
24
|
+
AuthErrorCode2["INVALID_SIGNATURE"] = "INVALID_SIGNATURE";
|
|
25
|
+
AuthErrorCode2["RELAY_ERROR"] = "RELAY_ERROR";
|
|
26
|
+
AuthErrorCode2["CHALLENGE_EXPIRED"] = "CHALLENGE_EXPIRED";
|
|
27
|
+
AuthErrorCode2["EXTENSION_NOT_FOUND"] = "EXTENSION_NOT_FOUND";
|
|
28
|
+
AuthErrorCode2["INVALID_KEY"] = "INVALID_KEY";
|
|
29
|
+
AuthErrorCode2["NOT_IMPLEMENTED"] = "NOT_IMPLEMENTED";
|
|
30
|
+
AuthErrorCode2["UNKNOWN_ERROR"] = "UNKNOWN_ERROR";
|
|
31
|
+
return AuthErrorCode2;
|
|
32
|
+
})(AuthErrorCode || {});
|
|
33
|
+
class AuthError extends Error {
|
|
34
|
+
code;
|
|
35
|
+
provider;
|
|
36
|
+
context;
|
|
37
|
+
constructor(message, code, provider, context) {
|
|
38
|
+
super(message);
|
|
39
|
+
this.name = "AuthError";
|
|
40
|
+
this.code = code;
|
|
41
|
+
this.provider = provider;
|
|
42
|
+
this.context = context;
|
|
43
|
+
if (Error.captureStackTrace) {
|
|
44
|
+
Error.captureStackTrace(this, AuthError);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Convert error to JSON for logging/serialization.
|
|
49
|
+
*/
|
|
50
|
+
toJSON() {
|
|
51
|
+
return {
|
|
52
|
+
name: this.name,
|
|
53
|
+
message: this.message,
|
|
54
|
+
code: this.code,
|
|
55
|
+
provider: this.provider,
|
|
56
|
+
context: this.context,
|
|
57
|
+
stack: this.stack
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
class InvalidCredentialsError extends AuthError {
|
|
62
|
+
constructor(provider, context) {
|
|
63
|
+
super(
|
|
64
|
+
"Invalid credentials",
|
|
65
|
+
"INVALID_CREDENTIALS",
|
|
66
|
+
provider,
|
|
67
|
+
context
|
|
68
|
+
);
|
|
69
|
+
this.name = "InvalidCredentialsError";
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
class InvalidTokenError extends AuthError {
|
|
73
|
+
constructor(message, provider, context) {
|
|
74
|
+
super(
|
|
75
|
+
message || "Invalid token",
|
|
76
|
+
"INVALID_TOKEN",
|
|
77
|
+
provider,
|
|
78
|
+
context
|
|
79
|
+
);
|
|
80
|
+
this.name = "InvalidTokenError";
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
class TokenExpiredError extends AuthError {
|
|
84
|
+
expiredAt;
|
|
85
|
+
constructor(provider, expiredAt, context) {
|
|
86
|
+
super("Token has expired", "TOKEN_EXPIRED", provider, context);
|
|
87
|
+
this.name = "TokenExpiredError";
|
|
88
|
+
this.expiredAt = expiredAt;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
class InvalidRefreshTokenError extends AuthError {
|
|
92
|
+
constructor(provider, context) {
|
|
93
|
+
super(
|
|
94
|
+
"Invalid or expired refresh token",
|
|
95
|
+
"INVALID_REFRESH_TOKEN",
|
|
96
|
+
provider,
|
|
97
|
+
context
|
|
98
|
+
);
|
|
99
|
+
this.name = "InvalidRefreshTokenError";
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
class SessionExpiredError extends AuthError {
|
|
103
|
+
constructor(provider, context) {
|
|
104
|
+
super(
|
|
105
|
+
"Session has expired",
|
|
106
|
+
"SESSION_EXPIRED",
|
|
107
|
+
provider,
|
|
108
|
+
context
|
|
109
|
+
);
|
|
110
|
+
this.name = "SessionExpiredError";
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
class MfaRequiredError extends AuthError {
|
|
114
|
+
mfaMethods;
|
|
115
|
+
constructor(provider, mfaMethods, context) {
|
|
116
|
+
super(
|
|
117
|
+
"Multi-factor authentication required",
|
|
118
|
+
"MFA_REQUIRED",
|
|
119
|
+
provider,
|
|
120
|
+
context
|
|
121
|
+
);
|
|
122
|
+
this.name = "MfaRequiredError";
|
|
123
|
+
this.mfaMethods = mfaMethods;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
class InvalidMfaCodeError extends AuthError {
|
|
127
|
+
constructor(provider, context) {
|
|
128
|
+
super(
|
|
129
|
+
"Invalid MFA code",
|
|
130
|
+
"INVALID_MFA_CODE",
|
|
131
|
+
provider,
|
|
132
|
+
context
|
|
133
|
+
);
|
|
134
|
+
this.name = "InvalidMfaCodeError";
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
class AccessDeniedError extends AuthError {
|
|
138
|
+
constructor(message, provider, context) {
|
|
139
|
+
super(
|
|
140
|
+
message || "Access denied",
|
|
141
|
+
"ACCESS_DENIED",
|
|
142
|
+
provider,
|
|
143
|
+
context
|
|
144
|
+
);
|
|
145
|
+
this.name = "AccessDeniedError";
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
class InsufficientScopeError extends AuthError {
|
|
149
|
+
requiredScopes;
|
|
150
|
+
grantedScopes;
|
|
151
|
+
constructor(requiredScopes, grantedScopes, provider, context) {
|
|
152
|
+
super(
|
|
153
|
+
`Insufficient scope. Required: ${requiredScopes?.join(", ") || "unknown"}`,
|
|
154
|
+
"INSUFFICIENT_SCOPE",
|
|
155
|
+
provider,
|
|
156
|
+
context
|
|
157
|
+
);
|
|
158
|
+
this.name = "InsufficientScopeError";
|
|
159
|
+
this.requiredScopes = requiredScopes;
|
|
160
|
+
this.grantedScopes = grantedScopes;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
class UserNotFoundError extends AuthError {
|
|
164
|
+
userId;
|
|
165
|
+
constructor(userId, provider, context) {
|
|
166
|
+
super(
|
|
167
|
+
userId ? `User not found: ${userId}` : "User not found",
|
|
168
|
+
"USER_NOT_FOUND",
|
|
169
|
+
provider,
|
|
170
|
+
context
|
|
171
|
+
);
|
|
172
|
+
this.name = "UserNotFoundError";
|
|
173
|
+
this.userId = userId;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
class UserAlreadyExistsError extends AuthError {
|
|
177
|
+
constructor(identifier, provider, context) {
|
|
178
|
+
super(
|
|
179
|
+
identifier ? `User already exists: ${identifier}` : "User already exists",
|
|
180
|
+
"USER_ALREADY_EXISTS",
|
|
181
|
+
provider,
|
|
182
|
+
context
|
|
183
|
+
);
|
|
184
|
+
this.name = "UserAlreadyExistsError";
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
class UserDisabledError extends AuthError {
|
|
188
|
+
constructor(userId, provider, context) {
|
|
189
|
+
super(
|
|
190
|
+
userId ? `User is disabled: ${userId}` : "User is disabled",
|
|
191
|
+
"USER_DISABLED",
|
|
192
|
+
provider,
|
|
193
|
+
context
|
|
194
|
+
);
|
|
195
|
+
this.name = "UserDisabledError";
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
class ProviderError extends AuthError {
|
|
199
|
+
originalError;
|
|
200
|
+
constructor(message, provider, originalError, context) {
|
|
201
|
+
super(message, "PROVIDER_ERROR", provider, context);
|
|
202
|
+
this.name = "ProviderError";
|
|
203
|
+
this.originalError = originalError;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
class ConfigurationError extends AuthError {
|
|
207
|
+
constructor(message, provider, context) {
|
|
208
|
+
super(message, "CONFIGURATION_ERROR", provider, context);
|
|
209
|
+
this.name = "ConfigurationError";
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
class NetworkError extends AuthError {
|
|
213
|
+
originalError;
|
|
214
|
+
constructor(message, provider, originalError, context) {
|
|
215
|
+
super(
|
|
216
|
+
message || "Network error",
|
|
217
|
+
"NETWORK_ERROR",
|
|
218
|
+
provider,
|
|
219
|
+
context
|
|
220
|
+
);
|
|
221
|
+
this.name = "NetworkError";
|
|
222
|
+
this.originalError = originalError;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
class InvalidStateError extends AuthError {
|
|
226
|
+
constructor(provider, context) {
|
|
227
|
+
super(
|
|
228
|
+
"Invalid or mismatched state parameter",
|
|
229
|
+
"INVALID_STATE",
|
|
230
|
+
provider,
|
|
231
|
+
context
|
|
232
|
+
);
|
|
233
|
+
this.name = "InvalidStateError";
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
class InvalidNonceError extends AuthError {
|
|
237
|
+
constructor(provider, context) {
|
|
238
|
+
super(
|
|
239
|
+
"Invalid or mismatched nonce",
|
|
240
|
+
"INVALID_NONCE",
|
|
241
|
+
provider,
|
|
242
|
+
context
|
|
243
|
+
);
|
|
244
|
+
this.name = "InvalidNonceError";
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
class InvalidGrantError extends AuthError {
|
|
248
|
+
constructor(message, provider, context) {
|
|
249
|
+
super(
|
|
250
|
+
message || "Invalid grant",
|
|
251
|
+
"INVALID_GRANT",
|
|
252
|
+
provider,
|
|
253
|
+
context
|
|
254
|
+
);
|
|
255
|
+
this.name = "InvalidGrantError";
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
class InvalidClientError extends AuthError {
|
|
259
|
+
constructor(provider, context) {
|
|
260
|
+
super(
|
|
261
|
+
"Invalid client credentials",
|
|
262
|
+
"INVALID_CLIENT",
|
|
263
|
+
provider,
|
|
264
|
+
context
|
|
265
|
+
);
|
|
266
|
+
this.name = "InvalidClientError";
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
class InvalidRedirectUriError extends AuthError {
|
|
270
|
+
constructor(provider, context) {
|
|
271
|
+
super(
|
|
272
|
+
"Invalid or mismatched redirect URI",
|
|
273
|
+
"INVALID_REDIRECT_URI",
|
|
274
|
+
provider,
|
|
275
|
+
context
|
|
276
|
+
);
|
|
277
|
+
this.name = "InvalidRedirectUriError";
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
class InvalidSignatureError extends AuthError {
|
|
281
|
+
constructor(message, context) {
|
|
282
|
+
super(
|
|
283
|
+
message || "Invalid event signature",
|
|
284
|
+
"INVALID_SIGNATURE",
|
|
285
|
+
"nostr",
|
|
286
|
+
context
|
|
287
|
+
);
|
|
288
|
+
this.name = "InvalidSignatureError";
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
class RelayError extends AuthError {
|
|
292
|
+
relayUrl;
|
|
293
|
+
originalError;
|
|
294
|
+
constructor(message, relayUrl, originalError, context) {
|
|
295
|
+
super(message, "RELAY_ERROR", "nostr", {
|
|
296
|
+
...context,
|
|
297
|
+
relayUrl
|
|
298
|
+
});
|
|
299
|
+
this.name = "RelayError";
|
|
300
|
+
this.relayUrl = relayUrl;
|
|
301
|
+
this.originalError = originalError;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
class ChallengeExpiredError extends AuthError {
|
|
305
|
+
constructor(context) {
|
|
306
|
+
super(
|
|
307
|
+
"Authentication challenge has expired",
|
|
308
|
+
"CHALLENGE_EXPIRED",
|
|
309
|
+
"nostr",
|
|
310
|
+
context
|
|
311
|
+
);
|
|
312
|
+
this.name = "ChallengeExpiredError";
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
class ExtensionNotFoundError extends AuthError {
|
|
316
|
+
constructor(context) {
|
|
317
|
+
super(
|
|
318
|
+
"NIP-07 browser extension not found. Install nos2x, Alby, or similar.",
|
|
319
|
+
"EXTENSION_NOT_FOUND",
|
|
320
|
+
"nostr",
|
|
321
|
+
context
|
|
322
|
+
);
|
|
323
|
+
this.name = "ExtensionNotFoundError";
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
class InvalidKeyError extends AuthError {
|
|
327
|
+
constructor(message, context) {
|
|
328
|
+
super(
|
|
329
|
+
message || "Invalid key format",
|
|
330
|
+
"INVALID_KEY",
|
|
331
|
+
"nostr",
|
|
332
|
+
context
|
|
333
|
+
);
|
|
334
|
+
this.name = "InvalidKeyError";
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
class NotImplementedError extends AuthError {
|
|
338
|
+
operation;
|
|
339
|
+
constructor(operation, provider, context) {
|
|
340
|
+
super(
|
|
341
|
+
`Operation '${operation}' is not supported by this provider`,
|
|
342
|
+
"NOT_IMPLEMENTED",
|
|
343
|
+
provider,
|
|
344
|
+
context
|
|
345
|
+
);
|
|
346
|
+
this.name = "NotImplementedError";
|
|
347
|
+
this.operation = operation;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
function isAuthError(error) {
|
|
351
|
+
return error instanceof AuthError;
|
|
352
|
+
}
|
|
353
|
+
function hasErrorCode(error, code) {
|
|
354
|
+
return isAuthError(error) && error.code === code;
|
|
355
|
+
}
|
|
356
|
+
function isKeycloakOptions(options) {
|
|
357
|
+
return options.type === "keycloak";
|
|
358
|
+
}
|
|
359
|
+
function isCognitoOptions(options) {
|
|
360
|
+
return options.type === "cognito";
|
|
361
|
+
}
|
|
362
|
+
function isNostrOptions(options) {
|
|
363
|
+
return options.type === "nostr";
|
|
364
|
+
}
|
|
365
|
+
function isKanidmOptions(options) {
|
|
366
|
+
return options.type === "kanidm";
|
|
367
|
+
}
|
|
368
|
+
function isGoogleOptions(options) {
|
|
369
|
+
return options.type === "google";
|
|
370
|
+
}
|
|
371
|
+
function isGitHubOptions(options) {
|
|
372
|
+
return options.type === "github";
|
|
373
|
+
}
|
|
374
|
+
async function getAuth(options) {
|
|
375
|
+
const configuredOptions = loadEnvConfig(
|
|
376
|
+
options,
|
|
377
|
+
{
|
|
378
|
+
packageName: "auth",
|
|
379
|
+
schema: {
|
|
380
|
+
type: "string",
|
|
381
|
+
serverUrl: "string",
|
|
382
|
+
realm: "string",
|
|
383
|
+
clientId: "string",
|
|
384
|
+
clientSecret: "string",
|
|
385
|
+
redirectUri: "string",
|
|
386
|
+
scopes: "string",
|
|
387
|
+
// Will be comma-separated
|
|
388
|
+
region: "string",
|
|
389
|
+
userPoolId: "string",
|
|
390
|
+
domain: "string",
|
|
391
|
+
relays: "string",
|
|
392
|
+
// Will be comma-separated
|
|
393
|
+
privateKey: "string",
|
|
394
|
+
challengeExpiration: "number",
|
|
395
|
+
relayTimeout: "number",
|
|
396
|
+
timeout: "number",
|
|
397
|
+
maxRetries: "number",
|
|
398
|
+
// Kanidm-specific
|
|
399
|
+
adminUsername: "string",
|
|
400
|
+
adminPassword: "string"
|
|
401
|
+
},
|
|
402
|
+
transform: {
|
|
403
|
+
// Transform comma-separated strings to arrays
|
|
404
|
+
relays: (value) => value.split(",").map((r) => r.trim()).filter(Boolean),
|
|
405
|
+
scopes: (value) => value.split(",").map((s) => s.trim()).filter(Boolean)
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
);
|
|
409
|
+
options = configuredOptions;
|
|
410
|
+
if (isKeycloakOptions(options)) {
|
|
411
|
+
const { KeycloakProvider } = await import("./chunks/keycloak-t6JEUeOz.js");
|
|
412
|
+
return new KeycloakProvider(options);
|
|
413
|
+
}
|
|
414
|
+
if (isCognitoOptions(options)) {
|
|
415
|
+
const { CognitoProvider } = await import("./chunks/cognito-dmypylFX.js");
|
|
416
|
+
return new CognitoProvider(options);
|
|
417
|
+
}
|
|
418
|
+
if (isNostrOptions(options)) {
|
|
419
|
+
const { NostrProvider } = await import("./chunks/index-BpsMhFXS.js");
|
|
420
|
+
return new NostrProvider(options);
|
|
421
|
+
}
|
|
422
|
+
if (isKanidmOptions(options)) {
|
|
423
|
+
const { KanidmProvider } = await import("./chunks/kanidm-hkw-YPVF.js");
|
|
424
|
+
return new KanidmProvider(options);
|
|
425
|
+
}
|
|
426
|
+
if (isGoogleOptions(options)) {
|
|
427
|
+
const { GoogleProvider } = await import("./chunks/google-HXk2ctYR.js");
|
|
428
|
+
return new GoogleProvider(options);
|
|
429
|
+
}
|
|
430
|
+
if (isGitHubOptions(options)) {
|
|
431
|
+
const { GitHubProvider } = await import("./chunks/github-NSZp5tVm.js");
|
|
432
|
+
return new GitHubProvider(options);
|
|
433
|
+
}
|
|
434
|
+
throw new ValidationError("Unsupported auth provider type", {
|
|
435
|
+
supportedTypes: [
|
|
436
|
+
"keycloak",
|
|
437
|
+
"cognito",
|
|
438
|
+
"nostr",
|
|
439
|
+
"kanidm",
|
|
440
|
+
"google",
|
|
441
|
+
"github"
|
|
442
|
+
],
|
|
443
|
+
providedType: options.type
|
|
444
|
+
});
|
|
445
|
+
}
|
|
446
|
+
async function getAuthAuto(options) {
|
|
447
|
+
if (options.serverUrl && options.realm) {
|
|
448
|
+
return getAuth({ ...options, type: "keycloak" });
|
|
449
|
+
}
|
|
450
|
+
if (options.region && options.userPoolId) {
|
|
451
|
+
return getAuth({ ...options, type: "cognito" });
|
|
452
|
+
}
|
|
453
|
+
if (options.relays && Array.isArray(options.relays) && options.relays.length > 0) {
|
|
454
|
+
return getAuth({ ...options, type: "nostr" });
|
|
455
|
+
}
|
|
456
|
+
throw new ValidationError(
|
|
457
|
+
"Could not auto-detect auth provider from options",
|
|
458
|
+
{
|
|
459
|
+
hint: 'Please specify a "type" field or provide provider-specific configuration',
|
|
460
|
+
supportedTypes: ["keycloak", "cognito", "nostr"],
|
|
461
|
+
providedOptions: Object.keys(options)
|
|
462
|
+
}
|
|
463
|
+
);
|
|
464
|
+
}
|
|
465
|
+
export {
|
|
466
|
+
AccessDeniedError,
|
|
467
|
+
AuthError,
|
|
468
|
+
AuthErrorCode,
|
|
469
|
+
ChallengeExpiredError,
|
|
470
|
+
ConfigurationError,
|
|
471
|
+
ExtensionNotFoundError,
|
|
472
|
+
InsufficientScopeError,
|
|
473
|
+
InvalidClientError,
|
|
474
|
+
InvalidCredentialsError,
|
|
475
|
+
InvalidGrantError,
|
|
476
|
+
InvalidKeyError,
|
|
477
|
+
InvalidMfaCodeError,
|
|
478
|
+
InvalidNonceError,
|
|
479
|
+
InvalidRedirectUriError,
|
|
480
|
+
InvalidRefreshTokenError,
|
|
481
|
+
InvalidSignatureError,
|
|
482
|
+
InvalidStateError,
|
|
483
|
+
InvalidTokenError,
|
|
484
|
+
MfaRequiredError,
|
|
485
|
+
NetworkError,
|
|
486
|
+
NotImplementedError,
|
|
487
|
+
ProviderError,
|
|
488
|
+
RelayError,
|
|
489
|
+
SessionExpiredError,
|
|
490
|
+
TokenExpiredError,
|
|
491
|
+
UserAlreadyExistsError,
|
|
492
|
+
UserDisabledError,
|
|
493
|
+
UserNotFoundError,
|
|
494
|
+
getAuth,
|
|
495
|
+
getAuthAuto,
|
|
496
|
+
hasErrorCode,
|
|
497
|
+
isAuthError
|
|
498
|
+
};
|
|
499
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/shared/errors.ts","../src/shared/factory.ts"],"sourcesContent":["/**\n * @happyvertical/auth - Error Classes\n *\n * Standardized authentication error types for consistent error handling\n * across all providers (Keycloak, Cognito, Nostr).\n */\n\n/**\n * Authentication error codes.\n */\nexport enum AuthErrorCode {\n // Authentication errors\n INVALID_CREDENTIALS = 'INVALID_CREDENTIALS',\n INVALID_TOKEN = 'INVALID_TOKEN',\n TOKEN_EXPIRED = 'TOKEN_EXPIRED',\n INVALID_REFRESH_TOKEN = 'INVALID_REFRESH_TOKEN',\n SESSION_EXPIRED = 'SESSION_EXPIRED',\n MFA_REQUIRED = 'MFA_REQUIRED',\n INVALID_MFA_CODE = 'INVALID_MFA_CODE',\n\n // Authorization errors\n ACCESS_DENIED = 'ACCESS_DENIED',\n INSUFFICIENT_SCOPE = 'INSUFFICIENT_SCOPE',\n INVALID_ROLE = 'INVALID_ROLE',\n\n // User management errors\n USER_NOT_FOUND = 'USER_NOT_FOUND',\n USER_ALREADY_EXISTS = 'USER_ALREADY_EXISTS',\n USER_DISABLED = 'USER_DISABLED',\n\n // Provider errors\n PROVIDER_ERROR = 'PROVIDER_ERROR',\n CONFIGURATION_ERROR = 'CONFIGURATION_ERROR',\n NETWORK_ERROR = 'NETWORK_ERROR',\n\n // OAuth/OIDC errors\n INVALID_STATE = 'INVALID_STATE',\n INVALID_NONCE = 'INVALID_NONCE',\n INVALID_GRANT = 'INVALID_GRANT',\n INVALID_CLIENT = 'INVALID_CLIENT',\n INVALID_REDIRECT_URI = 'INVALID_REDIRECT_URI',\n\n // Nostr-specific errors\n INVALID_SIGNATURE = 'INVALID_SIGNATURE',\n RELAY_ERROR = 'RELAY_ERROR',\n CHALLENGE_EXPIRED = 'CHALLENGE_EXPIRED',\n EXTENSION_NOT_FOUND = 'EXTENSION_NOT_FOUND',\n INVALID_KEY = 'INVALID_KEY',\n\n // General\n NOT_IMPLEMENTED = 'NOT_IMPLEMENTED',\n UNKNOWN_ERROR = 'UNKNOWN_ERROR',\n}\n\n/**\n * Base authentication error class.\n */\nexport class AuthError extends Error {\n public readonly code: AuthErrorCode;\n public readonly provider?: string;\n public readonly context?: Record<string, unknown>;\n\n constructor(\n message: string,\n code: AuthErrorCode,\n provider?: string,\n context?: Record<string, unknown>,\n ) {\n super(message);\n this.name = 'AuthError';\n this.code = code;\n this.provider = provider;\n this.context = context;\n\n // Maintains proper stack trace for where our error was thrown (only available on V8)\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, AuthError);\n }\n }\n\n /**\n * Convert error to JSON for logging/serialization.\n */\n toJSON(): Record<string, unknown> {\n return {\n name: this.name,\n message: this.message,\n code: this.code,\n provider: this.provider,\n context: this.context,\n stack: this.stack,\n };\n }\n}\n\n// =============================================================================\n// AUTHENTICATION ERRORS\n// =============================================================================\n\n/**\n * Invalid credentials error.\n */\nexport class InvalidCredentialsError extends AuthError {\n constructor(provider?: string, context?: Record<string, unknown>) {\n super(\n 'Invalid credentials',\n AuthErrorCode.INVALID_CREDENTIALS,\n provider,\n context,\n );\n this.name = 'InvalidCredentialsError';\n }\n}\n\n/**\n * Invalid token error.\n */\nexport class InvalidTokenError extends AuthError {\n constructor(\n message?: string,\n provider?: string,\n context?: Record<string, unknown>,\n ) {\n super(\n message || 'Invalid token',\n AuthErrorCode.INVALID_TOKEN,\n provider,\n context,\n );\n this.name = 'InvalidTokenError';\n }\n}\n\n/**\n * Token expired error.\n */\nexport class TokenExpiredError extends AuthError {\n public readonly expiredAt?: Date;\n\n constructor(\n provider?: string,\n expiredAt?: Date,\n context?: Record<string, unknown>,\n ) {\n super('Token has expired', AuthErrorCode.TOKEN_EXPIRED, provider, context);\n this.name = 'TokenExpiredError';\n this.expiredAt = expiredAt;\n }\n}\n\n/**\n * Invalid refresh token error.\n */\nexport class InvalidRefreshTokenError extends AuthError {\n constructor(provider?: string, context?: Record<string, unknown>) {\n super(\n 'Invalid or expired refresh token',\n AuthErrorCode.INVALID_REFRESH_TOKEN,\n provider,\n context,\n );\n this.name = 'InvalidRefreshTokenError';\n }\n}\n\n/**\n * Session expired error.\n */\nexport class SessionExpiredError extends AuthError {\n constructor(provider?: string, context?: Record<string, unknown>) {\n super(\n 'Session has expired',\n AuthErrorCode.SESSION_EXPIRED,\n provider,\n context,\n );\n this.name = 'SessionExpiredError';\n }\n}\n\n/**\n * MFA required error.\n */\nexport class MfaRequiredError extends AuthError {\n public readonly mfaMethods?: string[];\n\n constructor(\n provider?: string,\n mfaMethods?: string[],\n context?: Record<string, unknown>,\n ) {\n super(\n 'Multi-factor authentication required',\n AuthErrorCode.MFA_REQUIRED,\n provider,\n context,\n );\n this.name = 'MfaRequiredError';\n this.mfaMethods = mfaMethods;\n }\n}\n\n/**\n * Invalid MFA code error.\n */\nexport class InvalidMfaCodeError extends AuthError {\n constructor(provider?: string, context?: Record<string, unknown>) {\n super(\n 'Invalid MFA code',\n AuthErrorCode.INVALID_MFA_CODE,\n provider,\n context,\n );\n this.name = 'InvalidMfaCodeError';\n }\n}\n\n// =============================================================================\n// AUTHORIZATION ERRORS\n// =============================================================================\n\n/**\n * Access denied error.\n */\nexport class AccessDeniedError extends AuthError {\n constructor(\n message?: string,\n provider?: string,\n context?: Record<string, unknown>,\n ) {\n super(\n message || 'Access denied',\n AuthErrorCode.ACCESS_DENIED,\n provider,\n context,\n );\n this.name = 'AccessDeniedError';\n }\n}\n\n/**\n * Insufficient scope error.\n */\nexport class InsufficientScopeError extends AuthError {\n public readonly requiredScopes?: string[];\n public readonly grantedScopes?: string[];\n\n constructor(\n requiredScopes?: string[],\n grantedScopes?: string[],\n provider?: string,\n context?: Record<string, unknown>,\n ) {\n super(\n `Insufficient scope. Required: ${requiredScopes?.join(', ') || 'unknown'}`,\n AuthErrorCode.INSUFFICIENT_SCOPE,\n provider,\n context,\n );\n this.name = 'InsufficientScopeError';\n this.requiredScopes = requiredScopes;\n this.grantedScopes = grantedScopes;\n }\n}\n\n// =============================================================================\n// USER MANAGEMENT ERRORS\n// =============================================================================\n\n/**\n * User not found error.\n */\nexport class UserNotFoundError extends AuthError {\n public readonly userId?: string;\n\n constructor(\n userId?: string,\n provider?: string,\n context?: Record<string, unknown>,\n ) {\n super(\n userId ? `User not found: ${userId}` : 'User not found',\n AuthErrorCode.USER_NOT_FOUND,\n provider,\n context,\n );\n this.name = 'UserNotFoundError';\n this.userId = userId;\n }\n}\n\n/**\n * User already exists error.\n */\nexport class UserAlreadyExistsError extends AuthError {\n constructor(\n identifier?: string,\n provider?: string,\n context?: Record<string, unknown>,\n ) {\n super(\n identifier ? `User already exists: ${identifier}` : 'User already exists',\n AuthErrorCode.USER_ALREADY_EXISTS,\n provider,\n context,\n );\n this.name = 'UserAlreadyExistsError';\n }\n}\n\n/**\n * User disabled error.\n */\nexport class UserDisabledError extends AuthError {\n constructor(\n userId?: string,\n provider?: string,\n context?: Record<string, unknown>,\n ) {\n super(\n userId ? `User is disabled: ${userId}` : 'User is disabled',\n AuthErrorCode.USER_DISABLED,\n provider,\n context,\n );\n this.name = 'UserDisabledError';\n }\n}\n\n// =============================================================================\n// PROVIDER ERRORS\n// =============================================================================\n\n/**\n * Provider error.\n */\nexport class ProviderError extends AuthError {\n public readonly originalError?: Error;\n\n constructor(\n message: string,\n provider?: string,\n originalError?: Error,\n context?: Record<string, unknown>,\n ) {\n super(message, AuthErrorCode.PROVIDER_ERROR, provider, context);\n this.name = 'ProviderError';\n this.originalError = originalError;\n }\n}\n\n/**\n * Configuration error.\n */\nexport class ConfigurationError extends AuthError {\n constructor(\n message: string,\n provider?: string,\n context?: Record<string, unknown>,\n ) {\n super(message, AuthErrorCode.CONFIGURATION_ERROR, provider, context);\n this.name = 'ConfigurationError';\n }\n}\n\n/**\n * Network error.\n */\nexport class NetworkError extends AuthError {\n public readonly originalError?: Error;\n\n constructor(\n message?: string,\n provider?: string,\n originalError?: Error,\n context?: Record<string, unknown>,\n ) {\n super(\n message || 'Network error',\n AuthErrorCode.NETWORK_ERROR,\n provider,\n context,\n );\n this.name = 'NetworkError';\n this.originalError = originalError;\n }\n}\n\n// =============================================================================\n// OAUTH/OIDC ERRORS\n// =============================================================================\n\n/**\n * Invalid state error.\n */\nexport class InvalidStateError extends AuthError {\n constructor(provider?: string, context?: Record<string, unknown>) {\n super(\n 'Invalid or mismatched state parameter',\n AuthErrorCode.INVALID_STATE,\n provider,\n context,\n );\n this.name = 'InvalidStateError';\n }\n}\n\n/**\n * Invalid nonce error.\n */\nexport class InvalidNonceError extends AuthError {\n constructor(provider?: string, context?: Record<string, unknown>) {\n super(\n 'Invalid or mismatched nonce',\n AuthErrorCode.INVALID_NONCE,\n provider,\n context,\n );\n this.name = 'InvalidNonceError';\n }\n}\n\n/**\n * Invalid grant error.\n */\nexport class InvalidGrantError extends AuthError {\n constructor(\n message?: string,\n provider?: string,\n context?: Record<string, unknown>,\n ) {\n super(\n message || 'Invalid grant',\n AuthErrorCode.INVALID_GRANT,\n provider,\n context,\n );\n this.name = 'InvalidGrantError';\n }\n}\n\n/**\n * Invalid client error.\n */\nexport class InvalidClientError extends AuthError {\n constructor(provider?: string, context?: Record<string, unknown>) {\n super(\n 'Invalid client credentials',\n AuthErrorCode.INVALID_CLIENT,\n provider,\n context,\n );\n this.name = 'InvalidClientError';\n }\n}\n\n/**\n * Invalid redirect URI error.\n */\nexport class InvalidRedirectUriError extends AuthError {\n constructor(provider?: string, context?: Record<string, unknown>) {\n super(\n 'Invalid or mismatched redirect URI',\n AuthErrorCode.INVALID_REDIRECT_URI,\n provider,\n context,\n );\n this.name = 'InvalidRedirectUriError';\n }\n}\n\n// =============================================================================\n// NOSTR-SPECIFIC ERRORS\n// =============================================================================\n\n/**\n * Invalid signature error.\n */\nexport class InvalidSignatureError extends AuthError {\n constructor(message?: string, context?: Record<string, unknown>) {\n super(\n message || 'Invalid event signature',\n AuthErrorCode.INVALID_SIGNATURE,\n 'nostr',\n context,\n );\n this.name = 'InvalidSignatureError';\n }\n}\n\n/**\n * Relay error.\n */\nexport class RelayError extends AuthError {\n public readonly relayUrl?: string;\n public readonly originalError?: Error;\n\n constructor(\n message: string,\n relayUrl?: string,\n originalError?: Error,\n context?: Record<string, unknown>,\n ) {\n super(message, AuthErrorCode.RELAY_ERROR, 'nostr', {\n ...context,\n relayUrl,\n });\n this.name = 'RelayError';\n this.relayUrl = relayUrl;\n this.originalError = originalError;\n }\n}\n\n/**\n * Challenge expired error.\n */\nexport class ChallengeExpiredError extends AuthError {\n constructor(context?: Record<string, unknown>) {\n super(\n 'Authentication challenge has expired',\n AuthErrorCode.CHALLENGE_EXPIRED,\n 'nostr',\n context,\n );\n this.name = 'ChallengeExpiredError';\n }\n}\n\n/**\n * NIP-07 extension not found error.\n */\nexport class ExtensionNotFoundError extends AuthError {\n constructor(context?: Record<string, unknown>) {\n super(\n 'NIP-07 browser extension not found. Install nos2x, Alby, or similar.',\n AuthErrorCode.EXTENSION_NOT_FOUND,\n 'nostr',\n context,\n );\n this.name = 'ExtensionNotFoundError';\n }\n}\n\n/**\n * Invalid key error.\n */\nexport class InvalidKeyError extends AuthError {\n constructor(message?: string, context?: Record<string, unknown>) {\n super(\n message || 'Invalid key format',\n AuthErrorCode.INVALID_KEY,\n 'nostr',\n context,\n );\n this.name = 'InvalidKeyError';\n }\n}\n\n// =============================================================================\n// GENERAL ERRORS\n// =============================================================================\n\n/**\n * Not implemented error.\n */\nexport class NotImplementedError extends AuthError {\n public readonly operation: string;\n\n constructor(\n operation: string,\n provider?: string,\n context?: Record<string, unknown>,\n ) {\n super(\n `Operation '${operation}' is not supported by this provider`,\n AuthErrorCode.NOT_IMPLEMENTED,\n provider,\n context,\n );\n this.name = 'NotImplementedError';\n this.operation = operation;\n }\n}\n\n/**\n * Check if an error is an AuthError.\n */\nexport function isAuthError(error: unknown): error is AuthError {\n return error instanceof AuthError;\n}\n\n/**\n * Check if an error has a specific error code.\n */\nexport function hasErrorCode(error: unknown, code: AuthErrorCode): boolean {\n return isAuthError(error) && error.code === code;\n}\n","/**\n * @happyvertical/auth - Factory Functions\n *\n * Creates authentication provider instances based on configuration.\n * Supports Keycloak, AWS Cognito, and Nostr providers.\n */\n\nimport { loadEnvConfig, ValidationError } from '@happyvertical/utils';\n\nimport type {\n AuthInterface,\n CognitoOptions,\n GetAuthOptions,\n GitHubOptions,\n GoogleOptions,\n KanidmOptions,\n KeycloakOptions,\n NostrOptions,\n} from './types';\n\n// =============================================================================\n// TYPE GUARDS\n// =============================================================================\n\n/**\n * Checks if the options are for Keycloak provider.\n */\nfunction isKeycloakOptions(\n options: GetAuthOptions,\n): options is KeycloakOptions {\n return options.type === 'keycloak';\n}\n\n/**\n * Checks if the options are for Cognito provider.\n */\nfunction isCognitoOptions(options: GetAuthOptions): options is CognitoOptions {\n return options.type === 'cognito';\n}\n\n/**\n * Checks if the options are for Nostr provider.\n */\nfunction isNostrOptions(options: GetAuthOptions): options is NostrOptions {\n return options.type === 'nostr';\n}\n\n/**\n * Checks if the options are for Kanidm provider.\n */\nfunction isKanidmOptions(options: GetAuthOptions): options is KanidmOptions {\n return options.type === 'kanidm';\n}\n\n/**\n * Checks if the options are for Google provider.\n */\nfunction isGoogleOptions(options: GetAuthOptions): options is GoogleOptions {\n return options.type === 'google';\n}\n\n/**\n * Checks if the options are for GitHub provider.\n */\nfunction isGitHubOptions(options: GetAuthOptions): options is GitHubOptions {\n return options.type === 'github';\n}\n\n// =============================================================================\n// FACTORY FUNCTION\n// =============================================================================\n\n/**\n * Creates an authentication provider instance based on the provided options.\n *\n * Supports environment variable configuration using the pattern:\n * - HAVE_AUTH_TYPE → provider type ('keycloak' | 'cognito' | 'nostr')\n * - HAVE_AUTH_SERVER_URL → serverUrl (Keycloak)\n * - HAVE_AUTH_REALM → realm (Keycloak)\n * - HAVE_AUTH_CLIENT_ID → clientId\n * - HAVE_AUTH_CLIENT_SECRET → clientSecret\n * - HAVE_AUTH_REDIRECT_URI → redirectUri\n * - HAVE_AUTH_REGION → region (Cognito)\n * - HAVE_AUTH_USER_POOL_ID → userPoolId (Cognito)\n * - HAVE_AUTH_DOMAIN → domain (Cognito)\n * - HAVE_AUTH_RELAYS → relays (Nostr, comma-separated)\n * - HAVE_AUTH_TIMEOUT → timeout (number)\n * - HAVE_AUTH_MAX_RETRIES → maxRetries (number)\n *\n * User-provided options always take precedence over environment variables.\n *\n * @param options - Configuration options for the auth provider\n * @returns Promise resolving to an AuthInterface implementation\n * @throws {ValidationError} When the provider type is unsupported or invalid\n *\n * @example\n * ```typescript\n * // Create Keycloak client\n * const auth = await getAuth({\n * type: 'keycloak',\n * serverUrl: 'https://auth.example.com',\n * realm: 'my-realm',\n * clientId: 'my-app'\n * });\n *\n * // Create Cognito client\n * const auth = await getAuth({\n * type: 'cognito',\n * region: 'us-east-1',\n * userPoolId: 'us-east-1_xxx',\n * clientId: 'xxx'\n * });\n *\n * // Create Nostr client\n * const auth = await getAuth({\n * type: 'nostr',\n * relays: ['wss://relay.damus.io', 'wss://nos.lol']\n * });\n *\n * // Use environment variables\n * // Set: HAVE_AUTH_TYPE=keycloak, HAVE_AUTH_SERVER_URL=..., etc.\n * const auth = await getAuth({} as GetAuthOptions);\n * ```\n */\nexport async function getAuth(options: GetAuthOptions): Promise<AuthInterface> {\n // Load environment variables with user options taking precedence\n const configuredOptions = loadEnvConfig(\n options as unknown as Record<string, unknown>,\n {\n packageName: 'auth',\n schema: {\n type: 'string',\n serverUrl: 'string',\n realm: 'string',\n clientId: 'string',\n clientSecret: 'string',\n redirectUri: 'string',\n scopes: 'string', // Will be comma-separated\n region: 'string',\n userPoolId: 'string',\n domain: 'string',\n relays: 'string', // Will be comma-separated\n privateKey: 'string',\n challengeExpiration: 'number',\n relayTimeout: 'number',\n timeout: 'number',\n maxRetries: 'number',\n // Kanidm-specific\n adminUsername: 'string',\n adminPassword: 'string',\n },\n transform: {\n // Transform comma-separated strings to arrays\n relays: (value: string) =>\n value\n .split(',')\n .map((r) => r.trim())\n .filter(Boolean),\n scopes: (value: string) =>\n value\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean),\n },\n },\n ) as unknown as GetAuthOptions;\n options = configuredOptions;\n\n if (isKeycloakOptions(options)) {\n const { KeycloakProvider } = await import('./providers/keycloak.js');\n return new KeycloakProvider(options);\n }\n\n if (isCognitoOptions(options)) {\n const { CognitoProvider } = await import('./providers/cognito.js');\n return new CognitoProvider(options);\n }\n\n if (isNostrOptions(options)) {\n const { NostrProvider } = await import('./providers/nostr/index.js');\n return new NostrProvider(options);\n }\n\n if (isKanidmOptions(options)) {\n const { KanidmProvider } = await import('./providers/kanidm.js');\n return new KanidmProvider(options);\n }\n\n if (isGoogleOptions(options)) {\n const { GoogleProvider } = await import('./providers/google.js');\n return new GoogleProvider(options);\n }\n\n if (isGitHubOptions(options)) {\n const { GitHubProvider } = await import('./providers/github.js');\n return new GitHubProvider(options);\n }\n\n throw new ValidationError('Unsupported auth provider type', {\n supportedTypes: [\n 'keycloak',\n 'cognito',\n 'nostr',\n 'kanidm',\n 'google',\n 'github',\n ],\n providedType: (options as Record<string, unknown>).type,\n });\n}\n\n/**\n * Auto-detect provider based on available configuration.\n *\n * @param options - Configuration options that may contain provider-specific settings\n * @returns Promise resolving to an AuthInterface based on detected configuration\n * @throws {ValidationError} When no provider can be detected\n *\n * @example\n * ```typescript\n * // Auto-detect Keycloak from serverUrl and realm\n * const auth = await getAuthAuto({\n * serverUrl: 'https://auth.example.com',\n * realm: 'my-realm',\n * clientId: 'my-app'\n * });\n *\n * // Auto-detect Cognito from region and userPoolId\n * const auth = await getAuthAuto({\n * region: 'us-east-1',\n * userPoolId: 'us-east-1_xxx',\n * clientId: 'xxx'\n * });\n *\n * // Auto-detect Nostr from relays\n * const auth = await getAuthAuto({\n * relays: ['wss://relay.damus.io']\n * });\n * ```\n */\nexport async function getAuthAuto(\n options: Record<string, unknown>,\n): Promise<AuthInterface> {\n // Detect Keycloak from serverUrl and realm\n if (options.serverUrl && options.realm) {\n return getAuth({ ...options, type: 'keycloak' } as KeycloakOptions);\n }\n\n // Detect Cognito from region and userPoolId\n if (options.region && options.userPoolId) {\n return getAuth({ ...options, type: 'cognito' } as CognitoOptions);\n }\n\n // Detect Nostr from relays\n if (\n options.relays &&\n Array.isArray(options.relays) &&\n options.relays.length > 0\n ) {\n return getAuth({ ...options, type: 'nostr' } as NostrOptions);\n }\n\n throw new ValidationError(\n 'Could not auto-detect auth provider from options',\n {\n hint: 'Please specify a \"type\" field or provide provider-specific configuration',\n supportedTypes: ['keycloak', 'cognito', 'nostr'],\n providedOptions: Object.keys(options),\n },\n );\n}\n"],"names":["AuthErrorCode"],"mappings":";AAUO,IAAK,kCAAAA,mBAAL;AAELA,iBAAA,qBAAA,IAAsB;AACtBA,iBAAA,eAAA,IAAgB;AAChBA,iBAAA,eAAA,IAAgB;AAChBA,iBAAA,uBAAA,IAAwB;AACxBA,iBAAA,iBAAA,IAAkB;AAClBA,iBAAA,cAAA,IAAe;AACfA,iBAAA,kBAAA,IAAmB;AAGnBA,iBAAA,eAAA,IAAgB;AAChBA,iBAAA,oBAAA,IAAqB;AACrBA,iBAAA,cAAA,IAAe;AAGfA,iBAAA,gBAAA,IAAiB;AACjBA,iBAAA,qBAAA,IAAsB;AACtBA,iBAAA,eAAA,IAAgB;AAGhBA,iBAAA,gBAAA,IAAiB;AACjBA,iBAAA,qBAAA,IAAsB;AACtBA,iBAAA,eAAA,IAAgB;AAGhBA,iBAAA,eAAA,IAAgB;AAChBA,iBAAA,eAAA,IAAgB;AAChBA,iBAAA,eAAA,IAAgB;AAChBA,iBAAA,gBAAA,IAAiB;AACjBA,iBAAA,sBAAA,IAAuB;AAGvBA,iBAAA,mBAAA,IAAoB;AACpBA,iBAAA,aAAA,IAAc;AACdA,iBAAA,mBAAA,IAAoB;AACpBA,iBAAA,qBAAA,IAAsB;AACtBA,iBAAA,aAAA,IAAc;AAGdA,iBAAA,iBAAA,IAAkB;AAClBA,iBAAA,eAAA,IAAgB;AAzCN,SAAAA;AAAA,GAAA,iBAAA,CAAA,CAAA;AA+CL,MAAM,kBAAkB,MAAM;AAAA,EACnB;AAAA,EACA;AAAA,EACA;AAAA,EAEhB,YACE,SACA,MACA,UACA,SACA;AACA,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,OAAO;AACZ,SAAK,WAAW;AAChB,SAAK,UAAU;AAGf,QAAI,MAAM,mBAAmB;AAC3B,YAAM,kBAAkB,MAAM,SAAS;AAAA,IACzC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,SAAkC;AAChC,WAAO;AAAA,MACL,MAAM,KAAK;AAAA,MACX,SAAS,KAAK;AAAA,MACd,MAAM,KAAK;AAAA,MACX,UAAU,KAAK;AAAA,MACf,SAAS,KAAK;AAAA,MACd,OAAO,KAAK;AAAA,IAAA;AAAA,EAEhB;AACF;AASO,MAAM,gCAAgC,UAAU;AAAA,EACrD,YAAY,UAAmB,SAAmC;AAChE;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAEF,SAAK,OAAO;AAAA,EACd;AACF;AAKO,MAAM,0BAA0B,UAAU;AAAA,EAC/C,YACE,SACA,UACA,SACA;AACA;AAAA,MACE,WAAW;AAAA,MACX;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAEF,SAAK,OAAO;AAAA,EACd;AACF;AAKO,MAAM,0BAA0B,UAAU;AAAA,EAC/B;AAAA,EAEhB,YACE,UACA,WACA,SACA;AACA,UAAM,qBAAqB,iBAA6B,UAAU,OAAO;AACzE,SAAK,OAAO;AACZ,SAAK,YAAY;AAAA,EACnB;AACF;AAKO,MAAM,iCAAiC,UAAU;AAAA,EACtD,YAAY,UAAmB,SAAmC;AAChE;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAEF,SAAK,OAAO;AAAA,EACd;AACF;AAKO,MAAM,4BAA4B,UAAU;AAAA,EACjD,YAAY,UAAmB,SAAmC;AAChE;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAEF,SAAK,OAAO;AAAA,EACd;AACF;AAKO,MAAM,yBAAyB,UAAU;AAAA,EAC9B;AAAA,EAEhB,YACE,UACA,YACA,SACA;AACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAEF,SAAK,OAAO;AACZ,SAAK,aAAa;AAAA,EACpB;AACF;AAKO,MAAM,4BAA4B,UAAU;AAAA,EACjD,YAAY,UAAmB,SAAmC;AAChE;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAEF,SAAK,OAAO;AAAA,EACd;AACF;AASO,MAAM,0BAA0B,UAAU;AAAA,EAC/C,YACE,SACA,UACA,SACA;AACA;AAAA,MACE,WAAW;AAAA,MACX;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAEF,SAAK,OAAO;AAAA,EACd;AACF;AAKO,MAAM,+BAA+B,UAAU;AAAA,EACpC;AAAA,EACA;AAAA,EAEhB,YACE,gBACA,eACA,UACA,SACA;AACA;AAAA,MACE,iCAAiC,gBAAgB,KAAK,IAAI,KAAK,SAAS;AAAA,MACxE;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAEF,SAAK,OAAO;AACZ,SAAK,iBAAiB;AACtB,SAAK,gBAAgB;AAAA,EACvB;AACF;AASO,MAAM,0BAA0B,UAAU;AAAA,EAC/B;AAAA,EAEhB,YACE,QACA,UACA,SACA;AACA;AAAA,MACE,SAAS,mBAAmB,MAAM,KAAK;AAAA,MACvC;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAEF,SAAK,OAAO;AACZ,SAAK,SAAS;AAAA,EAChB;AACF;AAKO,MAAM,+BAA+B,UAAU;AAAA,EACpD,YACE,YACA,UACA,SACA;AACA;AAAA,MACE,aAAa,wBAAwB,UAAU,KAAK;AAAA,MACpD;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAEF,SAAK,OAAO;AAAA,EACd;AACF;AAKO,MAAM,0BAA0B,UAAU;AAAA,EAC/C,YACE,QACA,UACA,SACA;AACA;AAAA,MACE,SAAS,qBAAqB,MAAM,KAAK;AAAA,MACzC;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAEF,SAAK,OAAO;AAAA,EACd;AACF;AASO,MAAM,sBAAsB,UAAU;AAAA,EAC3B;AAAA,EAEhB,YACE,SACA,UACA,eACA,SACA;AACA,UAAM,SAAS,kBAA8B,UAAU,OAAO;AAC9D,SAAK,OAAO;AACZ,SAAK,gBAAgB;AAAA,EACvB;AACF;AAKO,MAAM,2BAA2B,UAAU;AAAA,EAChD,YACE,SACA,UACA,SACA;AACA,UAAM,SAAS,uBAAmC,UAAU,OAAO;AACnE,SAAK,OAAO;AAAA,EACd;AACF;AAKO,MAAM,qBAAqB,UAAU;AAAA,EAC1B;AAAA,EAEhB,YACE,SACA,UACA,eACA,SACA;AACA;AAAA,MACE,WAAW;AAAA,MACX;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAEF,SAAK,OAAO;AACZ,SAAK,gBAAgB;AAAA,EACvB;AACF;AASO,MAAM,0BAA0B,UAAU;AAAA,EAC/C,YAAY,UAAmB,SAAmC;AAChE;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAEF,SAAK,OAAO;AAAA,EACd;AACF;AAKO,MAAM,0BAA0B,UAAU;AAAA,EAC/C,YAAY,UAAmB,SAAmC;AAChE;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAEF,SAAK,OAAO;AAAA,EACd;AACF;AAKO,MAAM,0BAA0B,UAAU;AAAA,EAC/C,YACE,SACA,UACA,SACA;AACA;AAAA,MACE,WAAW;AAAA,MACX;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAEF,SAAK,OAAO;AAAA,EACd;AACF;AAKO,MAAM,2BAA2B,UAAU;AAAA,EAChD,YAAY,UAAmB,SAAmC;AAChE;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAEF,SAAK,OAAO;AAAA,EACd;AACF;AAKO,MAAM,gCAAgC,UAAU;AAAA,EACrD,YAAY,UAAmB,SAAmC;AAChE;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAEF,SAAK,OAAO;AAAA,EACd;AACF;AASO,MAAM,8BAA8B,UAAU;AAAA,EACnD,YAAY,SAAkB,SAAmC;AAC/D;AAAA,MACE,WAAW;AAAA,MACX;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAEF,SAAK,OAAO;AAAA,EACd;AACF;AAKO,MAAM,mBAAmB,UAAU;AAAA,EACxB;AAAA,EACA;AAAA,EAEhB,YACE,SACA,UACA,eACA,SACA;AACA,UAAM,SAAS,eAA2B,SAAS;AAAA,MACjD,GAAG;AAAA,MACH;AAAA,IAAA,CACD;AACD,SAAK,OAAO;AACZ,SAAK,WAAW;AAChB,SAAK,gBAAgB;AAAA,EACvB;AACF;AAKO,MAAM,8BAA8B,UAAU;AAAA,EACnD,YAAY,SAAmC;AAC7C;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAEF,SAAK,OAAO;AAAA,EACd;AACF;AAKO,MAAM,+BAA+B,UAAU;AAAA,EACpD,YAAY,SAAmC;AAC7C;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAEF,SAAK,OAAO;AAAA,EACd;AACF;AAKO,MAAM,wBAAwB,UAAU;AAAA,EAC7C,YAAY,SAAkB,SAAmC;AAC/D;AAAA,MACE,WAAW;AAAA,MACX;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAEF,SAAK,OAAO;AAAA,EACd;AACF;AASO,MAAM,4BAA4B,UAAU;AAAA,EACjC;AAAA,EAEhB,YACE,WACA,UACA,SACA;AACA;AAAA,MACE,cAAc,SAAS;AAAA,MACvB;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAEF,SAAK,OAAO;AACZ,SAAK,YAAY;AAAA,EACnB;AACF;AAKO,SAAS,YAAY,OAAoC;AAC9D,SAAO,iBAAiB;AAC1B;AAKO,SAAS,aAAa,OAAgB,MAA8B;AACzE,SAAO,YAAY,KAAK,KAAK,MAAM,SAAS;AAC9C;ACzjBA,SAAS,kBACP,SAC4B;AAC5B,SAAO,QAAQ,SAAS;AAC1B;AAKA,SAAS,iBAAiB,SAAoD;AAC5E,SAAO,QAAQ,SAAS;AAC1B;AAKA,SAAS,eAAe,SAAkD;AACxE,SAAO,QAAQ,SAAS;AAC1B;AAKA,SAAS,gBAAgB,SAAmD;AAC1E,SAAO,QAAQ,SAAS;AAC1B;AAKA,SAAS,gBAAgB,SAAmD;AAC1E,SAAO,QAAQ,SAAS;AAC1B;AAKA,SAAS,gBAAgB,SAAmD;AAC1E,SAAO,QAAQ,SAAS;AAC1B;AA0DA,eAAsB,QAAQ,SAAiD;AAE7E,QAAM,oBAAoB;AAAA,IACxB;AAAA,IACA;AAAA,MACE,aAAa;AAAA,MACb,QAAQ;AAAA,QACN,MAAM;AAAA,QACN,WAAW;AAAA,QACX,OAAO;AAAA,QACP,UAAU;AAAA,QACV,cAAc;AAAA,QACd,aAAa;AAAA,QACb,QAAQ;AAAA;AAAA,QACR,QAAQ;AAAA,QACR,YAAY;AAAA,QACZ,QAAQ;AAAA,QACR,QAAQ;AAAA;AAAA,QACR,YAAY;AAAA,QACZ,qBAAqB;AAAA,QACrB,cAAc;AAAA,QACd,SAAS;AAAA,QACT,YAAY;AAAA;AAAA,QAEZ,eAAe;AAAA,QACf,eAAe;AAAA,MAAA;AAAA,MAEjB,WAAW;AAAA;AAAA,QAET,QAAQ,CAAC,UACP,MACG,MAAM,GAAG,EACT,IAAI,CAAC,MAAM,EAAE,KAAA,CAAM,EACnB,OAAO,OAAO;AAAA,QACnB,QAAQ,CAAC,UACP,MACG,MAAM,GAAG,EACT,IAAI,CAAC,MAAM,EAAE,KAAA,CAAM,EACnB,OAAO,OAAO;AAAA,MAAA;AAAA,IACrB;AAAA,EACF;AAEF,YAAU;AAEV,MAAI,kBAAkB,OAAO,GAAG;AAC9B,UAAM,EAAE,iBAAA,IAAqB,MAAM,OAAO,+BAAyB;AACnE,WAAO,IAAI,iBAAiB,OAAO;AAAA,EACrC;AAEA,MAAI,iBAAiB,OAAO,GAAG;AAC7B,UAAM,EAAE,gBAAA,IAAoB,MAAM,OAAO,8BAAwB;AACjE,WAAO,IAAI,gBAAgB,OAAO;AAAA,EACpC;AAEA,MAAI,eAAe,OAAO,GAAG;AAC3B,UAAM,EAAE,cAAA,IAAkB,MAAM,OAAO,4BAA4B;AACnE,WAAO,IAAI,cAAc,OAAO;AAAA,EAClC;AAEA,MAAI,gBAAgB,OAAO,GAAG;AAC5B,UAAM,EAAE,eAAA,IAAmB,MAAM,OAAO,6BAAuB;AAC/D,WAAO,IAAI,eAAe,OAAO;AAAA,EACnC;AAEA,MAAI,gBAAgB,OAAO,GAAG;AAC5B,UAAM,EAAE,eAAA,IAAmB,MAAM,OAAO,6BAAuB;AAC/D,WAAO,IAAI,eAAe,OAAO;AAAA,EACnC;AAEA,MAAI,gBAAgB,OAAO,GAAG;AAC5B,UAAM,EAAE,eAAA,IAAmB,MAAM,OAAO,6BAAuB;AAC/D,WAAO,IAAI,eAAe,OAAO;AAAA,EACnC;AAEA,QAAM,IAAI,gBAAgB,kCAAkC;AAAA,IAC1D,gBAAgB;AAAA,MACd;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAAA,IAEF,cAAe,QAAoC;AAAA,EAAA,CACpD;AACH;AA+BA,eAAsB,YACpB,SACwB;AAExB,MAAI,QAAQ,aAAa,QAAQ,OAAO;AACtC,WAAO,QAAQ,EAAE,GAAG,SAAS,MAAM,YAA+B;AAAA,EACpE;AAGA,MAAI,QAAQ,UAAU,QAAQ,YAAY;AACxC,WAAO,QAAQ,EAAE,GAAG,SAAS,MAAM,WAA6B;AAAA,EAClE;AAGA,MACE,QAAQ,UACR,MAAM,QAAQ,QAAQ,MAAM,KAC5B,QAAQ,OAAO,SAAS,GACxB;AACA,WAAO,QAAQ,EAAE,GAAG,SAAS,MAAM,SAAyB;AAAA,EAC9D;AAEA,QAAM,IAAI;AAAA,IACR;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,gBAAgB,CAAC,YAAY,WAAW,OAAO;AAAA,MAC/C,iBAAiB,OAAO,KAAK,OAAO;AAAA,IAAA;AAAA,EACtC;AAEJ;"}
|