@absolutejs/auth 0.49.3 → 0.51.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/migrate.js +40 -2
- package/dist/cli/migrate.js.map +6 -6
- package/dist/htmx/index.js +38 -5
- package/dist/htmx/index.js.map +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +144 -19
- package/dist/index.js.map +15 -15
- package/dist/mfa/challenge.d.ts +1 -1
- package/dist/mfa/config.d.ts +2 -0
- package/dist/mfa/postgresMfaStore.d.ts +15 -0
- package/dist/mfa/types.d.ts +1 -0
- package/dist/providers/clients.d.ts +1740 -6
- package/dist/providers/index.js +38 -5
- package/dist/providers/index.js.map +3 -3
- package/dist/routes/authorize.d.ts +2 -2
- package/dist/typebox.d.ts +1 -3
- package/dist/types.d.ts +29 -4
- package/dist/utils.d.ts +5 -4
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ import { AuthConfig } from './types';
|
|
|
12
12
|
* `UserType`); the routes are reached by path at runtime / direct fetch. */
|
|
13
13
|
type MergeAuthContext<Base, Extra> = Base extends Elysia<infer Path, infer Singleton, infer Definitions, infer Metadata, infer Routes, infer Ephemeral, infer Volatile> ? Extra extends Elysia<infer ExtraPath, infer ExtraSingleton, infer ExtraDefinitions, infer ExtraMetadata, infer ExtraRoutes, infer ExtraEphemeral, infer ExtraVolatile> ? Elysia<Path & ExtraPath, Singleton & ExtraSingleton, Definitions & ExtraDefinitions, Metadata & ExtraMetadata, Routes & ExtraRoutes, Ephemeral & ExtraEphemeral, Volatile & ExtraVolatile> : never : never;
|
|
14
14
|
export type AuthInstance<UserType> = MergeAuthContext<ReturnType<typeof protectRoutePlugin<UserType>>, ReturnType<typeof stepUpPlugin<UserType>>>;
|
|
15
|
-
export declare const auth: <UserType>({ providersConfiguration, authorizeRoute, cookieSecure, callbackRoute, profileRoute, signoutRoute, statusRoute, refreshRoute, revokeRoute, cleanupIntervalMs, maxSessions, sessionDurationMs, authSessionStore, audit, credentials, mfa, passwordless, lockout, sessions, sso, scim, apikeys, oidc, organizations, roles, portal, authorization, compliance, webauthn, webhooks, htmx, tracing, resolveAuthIntent, onAuthorizeSuccess, onAuthorizeError, onProfileSuccess, onProfileError, onCallbackSuccess, onLinkIdentity, onLinkIdentityConflict, onLinkConnector, onCallbackError, onStatus, onRefreshSuccess, onRefreshError, onSignOut, onRevocationSuccess, onRevocationError, onSessionCleanup }: AuthConfig<UserType>) => Promise<Elysia<"", {
|
|
15
|
+
export declare const auth: <UserType>({ providersConfiguration, authorizeRoute, cookieSecure, callbackRoute, profileRoute, signoutRoute, statusRoute, refreshRoute, revokeRoute, cleanupIntervalMs, maxSessions, sessionDurationMs, authSessionStore, audit, credentials, customProviders, mfa, passwordless, lockout, sessions, sso, scim, apikeys, oidc, organizations, roles, portal, authorization, compliance, webauthn, webhooks, htmx, tracing, resolveAuthIntent, onAuthorizeSuccess, onAuthorizeError, onProfileSuccess, onProfileError, onCallbackSuccess, onLinkIdentity, onLinkIdentityConflict, onLinkConnector, onCallbackError, onStatus, onRefreshSuccess, onRefreshError, onSignOut, onRevocationSuccess, onRevocationError, onSessionCleanup }: AuthConfig<UserType>) => Promise<Elysia<"", {
|
|
16
16
|
decorator: {};
|
|
17
17
|
store: {
|
|
18
18
|
session: import("./types").SessionRecord<UserType>;
|
|
@@ -127,8 +127,8 @@ export { resolveAuthHtmxRenderers } from './htmx/renderers';
|
|
|
127
127
|
export type { AuthHtmxConfig, AuthHtmxConnectorTarget, AuthHtmxProviderData, AuthHtmxProviderInfo, AuthHtmxRenderOverrides, AuthHtmxRenderersConfig, AuthHtmxUser, AuthIdentityPayload, LinkedProviderPayload } from './htmx/types';
|
|
128
128
|
export * from './utils';
|
|
129
129
|
export { buildClientProviders, resolveClientProviderEntry, resolveProviderClientConfiguration } from './providers/clients';
|
|
130
|
-
export type { OAuth2TokenResponse, OAuth2Client, ProviderOption, PKCEProvider, OIDCProvider, RefreshableProvider, RevocableProvider, ScopeRequiredProvider, ProvidersMap, ProviderConfiguration, CredentialsFor } from 'citra';
|
|
131
|
-
export { providers, providerOptions, refreshableProviderOptions, revocableProviderOptions, oidcProviderOptions, pkceProviderOptions, scopeRequiredProviderOptions, decodeJWT, extractPropFromIdentity, isValidProviderOption, isRefreshableOAuth2Client, isRefreshableProviderOption, isOIDCProviderOption, isPKCEProviderOption, isRevocableProviderOption, isRevocableOAuth2Client } from 'citra';
|
|
130
|
+
export type { OAuth2TokenResponse, OAuth2Client, OAuth2ClientForConfig, CustomProviderCredentials, ProviderConfig, ProviderOption, PKCEProvider, OIDCProvider, RefreshableProvider, RevocableProvider, ScopeRequiredProvider, ProvidersMap, ProviderConfiguration, CredentialsFor } from 'citra';
|
|
131
|
+
export { providers, providerOptions, createCustomOAuth2Client, defineProvider, refreshableProviderOptions, revocableProviderOptions, oidcProviderOptions, pkceProviderOptions, scopeRequiredProviderOptions, decodeJWT, extractPropFromIdentity, isValidProviderOption, isRefreshableOAuth2Client, isRefreshableProviderOption, isOIDCProviderOption, isPKCEProviderOption, isRevocableProviderOption, isRevocableOAuth2Client } from 'citra';
|
|
132
132
|
export * from './crypto';
|
|
133
133
|
export * from './tenancy';
|
|
134
134
|
export * from './credentials/config';
|
package/dist/index.js
CHANGED
|
@@ -262,6 +262,7 @@ var anilistProfileQuery = `query {
|
|
|
262
262
|
}
|
|
263
263
|
}`;
|
|
264
264
|
var defineProviders = (providers) => providers;
|
|
265
|
+
var defineProvider = (config) => config;
|
|
265
266
|
var providers = defineProviders({
|
|
266
267
|
"42": {
|
|
267
268
|
authorizationUrl: "https://api.intra.42.fr/oauth/authorize",
|
|
@@ -1347,6 +1348,37 @@ var providers = defineProviders({
|
|
|
1347
1348
|
url: (config) => `https://${config.domain}/oauth2/default/v1/token`
|
|
1348
1349
|
}
|
|
1349
1350
|
},
|
|
1351
|
+
onspark: {
|
|
1352
|
+
authorizationUrl: "https://app.onspark.com/oauth2/authorize",
|
|
1353
|
+
email: ["email"],
|
|
1354
|
+
familyName: ["family_name"],
|
|
1355
|
+
fullName: ["name"],
|
|
1356
|
+
givenName: ["given_name"],
|
|
1357
|
+
isOIDC: true,
|
|
1358
|
+
isRefreshable: true,
|
|
1359
|
+
picture: ["picture"],
|
|
1360
|
+
PKCEMethod: "S256",
|
|
1361
|
+
profileRequest: {
|
|
1362
|
+
authIn: "header",
|
|
1363
|
+
encoding: "application/json",
|
|
1364
|
+
method: "GET",
|
|
1365
|
+
url: "https://app.onspark.com/oauth2/userinfo"
|
|
1366
|
+
},
|
|
1367
|
+
revocationRequest: {
|
|
1368
|
+
authIn: "body",
|
|
1369
|
+
encoding: "application/x-www-form-urlencoded",
|
|
1370
|
+
tokenParamName: "token",
|
|
1371
|
+
url: "https://app.onspark.com/oauth2/revoke"
|
|
1372
|
+
},
|
|
1373
|
+
scopeRequired: true,
|
|
1374
|
+
subject: ["sub"],
|
|
1375
|
+
subjectType: "string",
|
|
1376
|
+
tokenRequest: {
|
|
1377
|
+
authIn: "body",
|
|
1378
|
+
encoding: "application/x-www-form-urlencoded",
|
|
1379
|
+
url: "https://app.onspark.com/oauth2/token"
|
|
1380
|
+
}
|
|
1381
|
+
},
|
|
1350
1382
|
osu: {
|
|
1351
1383
|
authorizationUrl: "https://osu.ppy.sh/oauth/authorize",
|
|
1352
1384
|
isOIDC: false,
|
|
@@ -1898,6 +1930,7 @@ var providers = defineProviders({
|
|
|
1898
1930
|
method: "POST",
|
|
1899
1931
|
url: "https://wbsapi.withings.net/v2/oauth2"
|
|
1900
1932
|
},
|
|
1933
|
+
scopeDelimiter: ",",
|
|
1901
1934
|
scopeRequired: true,
|
|
1902
1935
|
subject: ["userid"],
|
|
1903
1936
|
subjectType: "string",
|
|
@@ -2529,8 +2562,7 @@ var refreshableProviderOptions = Object.keys(providers).filter(isRefreshableProv
|
|
|
2529
2562
|
var revocableProviderOptions = Object.keys(providers).filter(isRevocableProviderOption);
|
|
2530
2563
|
var scopeRequiredProviderOptions = Object.keys(providers).filter(isScopeRequiredProviderOption);
|
|
2531
2564
|
var readPath = (value, path) => path.reduce((cursor, key) => cursor && typeof cursor === "object" ? Reflect.get(cursor, key) : undefined, value);
|
|
2532
|
-
var
|
|
2533
|
-
const meta = providers[providerName];
|
|
2565
|
+
var buildOAuth2Client = async (meta, config) => {
|
|
2534
2566
|
const isConfigPropertyFunction = (cfgProp) => typeof cfgProp === "function";
|
|
2535
2567
|
const resolveConfigProp = async (cfgProp) => {
|
|
2536
2568
|
const result = isConfigPropertyFunction(cfgProp) ? cfgProp(config) : cfgProp;
|
|
@@ -2549,8 +2581,7 @@ var createOAuth2Client = async (providerName, config) => {
|
|
|
2549
2581
|
if (state)
|
|
2550
2582
|
url.searchParams.set("state", state);
|
|
2551
2583
|
if (scope.length !== 0) {
|
|
2552
|
-
|
|
2553
|
-
url.searchParams.set(meta.scopeParamName ?? "scope", scope.join(delimeter));
|
|
2584
|
+
url.searchParams.set(meta.scopeParamName ?? "scope", scope.join(meta.scopeDelimiter ?? " "));
|
|
2554
2585
|
}
|
|
2555
2586
|
if (meta.PKCEMethod !== undefined) {
|
|
2556
2587
|
if (!codeVerifier) {
|
|
@@ -2732,6 +2763,8 @@ var createOAuth2Client = async (providerName, config) => {
|
|
|
2732
2763
|
}
|
|
2733
2764
|
};
|
|
2734
2765
|
};
|
|
2766
|
+
var createCustomOAuth2Client = (providerConfig, credentials) => buildOAuth2Client(providerConfig, credentials);
|
|
2767
|
+
var createOAuth2Client = (providerName, config) => buildOAuth2Client(providers[providerName], config);
|
|
2735
2768
|
|
|
2736
2769
|
// src/index.ts
|
|
2737
2770
|
import { Elysia as Elysia40 } from "elysia";
|
|
@@ -3201,7 +3234,7 @@ var authIntentOption = t2.Optional(t2.Union([
|
|
|
3201
3234
|
t2.Literal("link_identity"),
|
|
3202
3235
|
t2.Literal("link_connector")
|
|
3203
3236
|
]));
|
|
3204
|
-
var authProviderOption = t2.
|
|
3237
|
+
var authProviderOption = t2.String({ minLength: 1 });
|
|
3205
3238
|
var userSessionIdTypebox = t2.Optional(t2.TemplateLiteral("${string}-${string}-${string}-${string}-${string}"));
|
|
3206
3239
|
|
|
3207
3240
|
// src/authorization/protectPermission.ts
|
|
@@ -3273,6 +3306,7 @@ var getStatus = async (session, user_session_id) => {
|
|
|
3273
3306
|
};
|
|
3274
3307
|
var instantiateUserSession = async ({
|
|
3275
3308
|
authProvider,
|
|
3309
|
+
providerConfiguration,
|
|
3276
3310
|
cookieSecure,
|
|
3277
3311
|
session,
|
|
3278
3312
|
user_session_id,
|
|
@@ -3287,6 +3321,7 @@ var instantiateUserSession = async ({
|
|
|
3287
3321
|
}) => {
|
|
3288
3322
|
const authorization = resolvedAuthorization ?? await resolveOAuthAuthorization({
|
|
3289
3323
|
authProvider,
|
|
3324
|
+
providerConfiguration,
|
|
3290
3325
|
providerInstance,
|
|
3291
3326
|
tokenResponse
|
|
3292
3327
|
});
|
|
@@ -3331,23 +3366,28 @@ var instantiateUserSession = async ({
|
|
|
3331
3366
|
var resolveCookieSecure = (override) => override ?? false;
|
|
3332
3367
|
var resolveOAuthAuthorization = async ({
|
|
3333
3368
|
authProvider,
|
|
3369
|
+
providerConfiguration,
|
|
3334
3370
|
providerInstance,
|
|
3335
3371
|
tokenResponse,
|
|
3336
3372
|
now = Date.now()
|
|
3337
3373
|
}) => {
|
|
3374
|
+
const meta = providerConfiguration ?? (isValidProviderOption(authProvider) ? providers[authProvider] : undefined);
|
|
3375
|
+
if (!meta) {
|
|
3376
|
+
throw new Error(`No provider configuration for "${authProvider}" \u2014 pass providerConfiguration (custom provider) or resolvedAuthorization`);
|
|
3377
|
+
}
|
|
3338
3378
|
let userIdentity;
|
|
3339
3379
|
let accessToken = tokenResponse.access_token;
|
|
3340
3380
|
let refreshToken = tokenResponse.refresh_token;
|
|
3341
3381
|
if (tokenResponse.id_token) {
|
|
3342
3382
|
userIdentity = normalizeProviderIdentity({
|
|
3343
3383
|
identity: decodeJWT(tokenResponse.id_token),
|
|
3344
|
-
providerConfiguration:
|
|
3384
|
+
providerConfiguration: meta,
|
|
3345
3385
|
source: "idToken"
|
|
3346
3386
|
});
|
|
3347
|
-
} else if (
|
|
3387
|
+
} else if (meta.subjectBySource?.tokenResponse) {
|
|
3348
3388
|
userIdentity = normalizeProviderIdentity({
|
|
3349
3389
|
identity: tokenResponse,
|
|
3350
|
-
providerConfiguration:
|
|
3390
|
+
providerConfiguration: meta,
|
|
3351
3391
|
source: "tokenResponse"
|
|
3352
3392
|
});
|
|
3353
3393
|
} else if (authProvider === "withings") {
|
|
@@ -3357,7 +3397,7 @@ var resolveOAuthAuthorization = async ({
|
|
|
3357
3397
|
} else {
|
|
3358
3398
|
userIdentity = normalizeProviderIdentity({
|
|
3359
3399
|
identity: await providerInstance.fetchUserProfile(tokenResponse.access_token),
|
|
3360
|
-
providerConfiguration:
|
|
3400
|
+
providerConfiguration: meta,
|
|
3361
3401
|
source: "profile"
|
|
3362
3402
|
});
|
|
3363
3403
|
}
|
|
@@ -4354,6 +4394,7 @@ var DEFAULT_SMS_CODE_LENGTH = 6;
|
|
|
4354
4394
|
var SMS_CODE_TTL_MINUTES = 5;
|
|
4355
4395
|
var DEFAULT_SMS_CODE_TTL_MS = SMS_CODE_TTL_MINUTES * SECONDS_IN_A_MINUTE * MILLISECONDS_IN_A_SECOND;
|
|
4356
4396
|
var DEFAULT_SMS_MAX_ATTEMPTS = 3;
|
|
4397
|
+
var DEFAULT_TOTP_MAX_ATTEMPTS = 5;
|
|
4357
4398
|
|
|
4358
4399
|
// src/mfa/secret.ts
|
|
4359
4400
|
init_crypto();
|
|
@@ -4521,7 +4562,8 @@ var mfaChallenge = ({
|
|
|
4521
4562
|
sessionDurationMs = DEFAULT_MFA_SESSION_TTL_MS,
|
|
4522
4563
|
smsCodeLength = DEFAULT_SMS_CODE_LENGTH,
|
|
4523
4564
|
smsCodeTtlMs = DEFAULT_SMS_CODE_TTL_MS,
|
|
4524
|
-
smsMaxAttempts = DEFAULT_SMS_MAX_ATTEMPTS
|
|
4565
|
+
smsMaxAttempts = DEFAULT_SMS_MAX_ATTEMPTS,
|
|
4566
|
+
totpMaxAttempts = DEFAULT_TOTP_MAX_ATTEMPTS
|
|
4525
4567
|
}) => new Elysia13().use(sessionStore()).post(challengeRoute, async ({
|
|
4526
4568
|
body: { action, code, factor },
|
|
4527
4569
|
cookie: { user_session_id },
|
|
@@ -4620,12 +4662,24 @@ var mfaChallenge = ({
|
|
|
4620
4662
|
if (code === undefined) {
|
|
4621
4663
|
return status("Unauthorized", "Invalid MFA code");
|
|
4622
4664
|
}
|
|
4665
|
+
if ((enrollment.totpFailedAttempts ?? 0) >= totpMaxAttempts) {
|
|
4666
|
+
await onMfaChallengeError?.({
|
|
4667
|
+
error: new Error("mfa_totp_attempts_exceeded"),
|
|
4668
|
+
userId: getUserId(user)
|
|
4669
|
+
});
|
|
4670
|
+
return status("Unauthorized", "Too many attempts");
|
|
4671
|
+
}
|
|
4623
4672
|
const totpValid = enrollment.totpVerified && enrollment.totpSecretCiphertext ? await verifyTotp({
|
|
4624
4673
|
secret: await decryptTotpSecret(enrollment.totpSecretCiphertext, encryptionKey),
|
|
4625
4674
|
token: code
|
|
4626
4675
|
}) : false;
|
|
4627
4676
|
const remainingBackupHashes = totpValid ? undefined : await consumeBackupCode(code, enrollment.backupCodeHashes);
|
|
4628
4677
|
if (!totpValid && remainingBackupHashes === undefined) {
|
|
4678
|
+
await mfaStore.saveEnrollment({
|
|
4679
|
+
...enrollment,
|
|
4680
|
+
totpFailedAttempts: (enrollment.totpFailedAttempts ?? 0) + 1,
|
|
4681
|
+
updatedAt: Date.now()
|
|
4682
|
+
});
|
|
4629
4683
|
await onMfaChallengeError?.({
|
|
4630
4684
|
error: new Error("invalid_mfa_code"),
|
|
4631
4685
|
userId: getUserId(user)
|
|
@@ -4636,6 +4690,7 @@ var mfaChallenge = ({
|
|
|
4636
4690
|
...enrollment,
|
|
4637
4691
|
backupCodeHashes: remainingBackupHashes ?? enrollment.backupCodeHashes,
|
|
4638
4692
|
lastUsedAt: Date.now(),
|
|
4693
|
+
totpFailedAttempts: 0,
|
|
4639
4694
|
updatedAt: Date.now()
|
|
4640
4695
|
});
|
|
4641
4696
|
return promote();
|
|
@@ -8252,7 +8307,52 @@ var roleRoutes = ({
|
|
|
8252
8307
|
// src/providers/clients.ts
|
|
8253
8308
|
var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
8254
8309
|
var isProviderClientConfig = (value) => isRecord(value) && ("credentials" in value);
|
|
8255
|
-
var
|
|
8310
|
+
var isCustomClientConfig = (value) => isRecord(value) && ("credentials" in value) && ("providerConfig" in value);
|
|
8311
|
+
var normalizeCustomClients = (providerName, providerConfig) => {
|
|
8312
|
+
if (isCustomClientConfig(providerConfig))
|
|
8313
|
+
return { "": providerConfig };
|
|
8314
|
+
if (!isRecord(providerConfig) || Object.keys(providerConfig).length === 0) {
|
|
8315
|
+
throw new Error(`Invalid custom provider configuration for ${providerName}`);
|
|
8316
|
+
}
|
|
8317
|
+
Object.entries(providerConfig).forEach(([clientName, clientConfig]) => {
|
|
8318
|
+
if (!isCustomClientConfig(clientConfig)) {
|
|
8319
|
+
throw new Error(`Invalid custom client configuration for ${providerName}.${clientName}`);
|
|
8320
|
+
}
|
|
8321
|
+
});
|
|
8322
|
+
return providerConfig;
|
|
8323
|
+
};
|
|
8324
|
+
var buildCustomProviderGroups = async (customProviders) => {
|
|
8325
|
+
const groups = await Promise.all(Object.entries(customProviders).map(async ([providerName, config]) => {
|
|
8326
|
+
if (isValidProviderOption(providerName)) {
|
|
8327
|
+
throw new Error(`Custom provider "${providerName}" collides with a built-in provider \u2014 configure it under providersConfiguration instead`);
|
|
8328
|
+
}
|
|
8329
|
+
const clients = normalizeCustomClients(providerName, config);
|
|
8330
|
+
const entries = await Promise.all(Object.entries(clients).map(async ([clientName, clientConfig]) => {
|
|
8331
|
+
const providerInstance = await createCustomOAuth2Client(clientConfig.providerConfig, clientConfig.credentials);
|
|
8332
|
+
return [
|
|
8333
|
+
clientName,
|
|
8334
|
+
{
|
|
8335
|
+
clientName: clientName.length > 0 ? clientName : undefined,
|
|
8336
|
+
providerConfiguration: clientConfig.providerConfig,
|
|
8337
|
+
providerInstance,
|
|
8338
|
+
requiresPKCE: clientConfig.providerConfig.PKCEMethod !== undefined,
|
|
8339
|
+
scope: clientConfig.scope,
|
|
8340
|
+
searchParams: clientConfig.searchParams
|
|
8341
|
+
}
|
|
8342
|
+
];
|
|
8343
|
+
}));
|
|
8344
|
+
return [
|
|
8345
|
+
providerName,
|
|
8346
|
+
{
|
|
8347
|
+
entries: Object.fromEntries(entries),
|
|
8348
|
+
isSingleClient: entries.length === 1 && entries[0]?.[0] === ""
|
|
8349
|
+
}
|
|
8350
|
+
];
|
|
8351
|
+
}));
|
|
8352
|
+
return Object.fromEntries(groups);
|
|
8353
|
+
};
|
|
8354
|
+
var buildClientProviders = async (providersConfiguration, createOAuth2ClientFn, customProviders) => {
|
|
8355
|
+
const customGroups = customProviders ? await buildCustomProviderGroups(customProviders) : {};
|
|
8256
8356
|
const normalized = normalizeProvidersConfiguration(providersConfiguration);
|
|
8257
8357
|
const groups = await Promise.all(Object.entries(normalized).map(async ([providerName, clients]) => {
|
|
8258
8358
|
if (!isValidProviderOption(providerName)) {
|
|
@@ -8264,7 +8364,9 @@ var buildClientProviders = async (providersConfiguration, createOAuth2ClientFn)
|
|
|
8264
8364
|
clientName,
|
|
8265
8365
|
{
|
|
8266
8366
|
clientName: clientName.length > 0 ? clientName : undefined,
|
|
8367
|
+
providerConfiguration: providers[providerName],
|
|
8267
8368
|
providerInstance,
|
|
8369
|
+
requiresPKCE: providers[providerName].PKCEMethod !== undefined,
|
|
8268
8370
|
scope: providerConfig.scope,
|
|
8269
8371
|
searchParams: providerConfig.searchParams
|
|
8270
8372
|
}
|
|
@@ -8278,7 +8380,7 @@ var buildClientProviders = async (providersConfiguration, createOAuth2ClientFn)
|
|
|
8278
8380
|
}
|
|
8279
8381
|
];
|
|
8280
8382
|
}));
|
|
8281
|
-
return Object.fromEntries(groups);
|
|
8383
|
+
return { ...customGroups, ...Object.fromEntries(groups) };
|
|
8282
8384
|
};
|
|
8283
8385
|
var normalizeClientConfig = (providerName, clientName, clientConfig) => {
|
|
8284
8386
|
if (!isProviderClientConfig(clientConfig)) {
|
|
@@ -8414,7 +8516,13 @@ var authorize = ({
|
|
|
8414
8516
|
if ("error" in resolvedProvider) {
|
|
8415
8517
|
return status("Unauthorized", resolvedProvider.error);
|
|
8416
8518
|
}
|
|
8417
|
-
const {
|
|
8519
|
+
const {
|
|
8520
|
+
clientName,
|
|
8521
|
+
providerInstance,
|
|
8522
|
+
requiresPKCE,
|
|
8523
|
+
scope,
|
|
8524
|
+
searchParams
|
|
8525
|
+
} = resolvedProvider.entry;
|
|
8418
8526
|
const referer = parseReferer(headers["referer"]);
|
|
8419
8527
|
const authIntent = isAuthIntent(intent) ? intent : undefined;
|
|
8420
8528
|
origin_url.set({
|
|
@@ -8462,7 +8570,7 @@ var authorize = ({
|
|
|
8462
8570
|
secure,
|
|
8463
8571
|
value: currentState
|
|
8464
8572
|
});
|
|
8465
|
-
const codeVerifier =
|
|
8573
|
+
const codeVerifier = requiresPKCE ? generateCodeVerifier() : undefined;
|
|
8466
8574
|
if (codeVerifier) {
|
|
8467
8575
|
code_verifier.set({
|
|
8468
8576
|
httpOnly: true,
|
|
@@ -8574,9 +8682,13 @@ var callback = ({
|
|
|
8574
8682
|
if ("error" in resolvedProvider) {
|
|
8575
8683
|
return status("Unauthorized", resolvedProvider.error);
|
|
8576
8684
|
}
|
|
8577
|
-
const {
|
|
8685
|
+
const {
|
|
8686
|
+
clientName,
|
|
8687
|
+
providerConfiguration,
|
|
8688
|
+
providerInstance,
|
|
8689
|
+
requiresPKCE
|
|
8690
|
+
} = resolvedProvider.entry;
|
|
8578
8691
|
stored_state.remove();
|
|
8579
|
-
const requiresPKCE = isPKCEProviderOption(authProvider);
|
|
8580
8692
|
const verifier = requiresPKCE ? code_verifier.value : undefined;
|
|
8581
8693
|
if (requiresPKCE && verifier === undefined) {
|
|
8582
8694
|
return status("Bad Request", "Code verifier not found and is required");
|
|
@@ -8624,6 +8736,7 @@ var callback = ({
|
|
|
8624
8736
|
cookie,
|
|
8625
8737
|
currentUser,
|
|
8626
8738
|
originUrl,
|
|
8739
|
+
providerConfiguration,
|
|
8627
8740
|
providerInstance,
|
|
8628
8741
|
redirect,
|
|
8629
8742
|
session: callbackSession,
|
|
@@ -23203,6 +23316,7 @@ var mfaEnrollmentsTable = pgTable("auth_mfa_enrollments", {
|
|
|
23203
23316
|
sms_pending_code_hash: text("sms_pending_code_hash"),
|
|
23204
23317
|
sms_phone: varchar("sms_phone", { length: PHONE_LENGTH }),
|
|
23205
23318
|
sms_verified: boolean("sms_verified").notNull().default(false),
|
|
23319
|
+
totp_failed_attempts: smallint("totp_failed_attempts").notNull().default(0),
|
|
23206
23320
|
totp_secret_ciphertext: text("totp_secret_ciphertext"),
|
|
23207
23321
|
totp_verified: boolean("totp_verified").notNull().default(false),
|
|
23208
23322
|
updated_at_ms: bigint("updated_at_ms", { mode: "number" }).notNull(),
|
|
@@ -23217,6 +23331,7 @@ var toEnrollment = (row) => ({
|
|
|
23217
23331
|
smsPendingCodeHash: row.sms_pending_code_hash ?? undefined,
|
|
23218
23332
|
smsPhone: row.sms_phone ?? undefined,
|
|
23219
23333
|
smsVerified: row.sms_verified,
|
|
23334
|
+
totpFailedAttempts: row.totp_failed_attempts,
|
|
23220
23335
|
totpSecretCiphertext: row.totp_secret_ciphertext ?? undefined,
|
|
23221
23336
|
totpVerified: row.totp_verified,
|
|
23222
23337
|
updatedAt: row.updated_at_ms,
|
|
@@ -23245,6 +23360,7 @@ var createPostgresMfaStore = (db) => ({
|
|
|
23245
23360
|
sms_pending_code_hash: enrollment.smsPendingCodeHash ?? null,
|
|
23246
23361
|
sms_phone: enrollment.smsPhone ?? null,
|
|
23247
23362
|
sms_verified: enrollment.smsVerified,
|
|
23363
|
+
totp_failed_attempts: enrollment.totpFailedAttempts ?? 0,
|
|
23248
23364
|
totp_secret_ciphertext: enrollment.totpSecretCiphertext ?? null,
|
|
23249
23365
|
totp_verified: enrollment.totpVerified,
|
|
23250
23366
|
updated_at_ms: enrollment.updatedAt,
|
|
@@ -26573,6 +26689,10 @@ var mfaSmsColumnsMigration = {
|
|
|
26573
26689
|
].join(`
|
|
26574
26690
|
`)
|
|
26575
26691
|
};
|
|
26692
|
+
var mfaTotpLockoutMigration = {
|
|
26693
|
+
id: "0003_totp_lockout",
|
|
26694
|
+
sql: 'ALTER TABLE "auth_mfa_enrollments" ADD COLUMN IF NOT EXISTS "totp_failed_attempts" smallint NOT NULL DEFAULT 0;'
|
|
26695
|
+
};
|
|
26576
26696
|
var blockMigrations = {
|
|
26577
26697
|
adaptive: initMigration("adaptive", [knownDevicesTable, loginHistoryTable]),
|
|
26578
26698
|
apikeys: initMigration("apikeys", [
|
|
@@ -26596,7 +26716,8 @@ var blockMigrations = {
|
|
|
26596
26716
|
block: "mfa",
|
|
26597
26717
|
migrations: [
|
|
26598
26718
|
...initMigration("mfa", [mfaEnrollmentsTable]).migrations,
|
|
26599
|
-
mfaSmsColumnsMigration
|
|
26719
|
+
mfaSmsColumnsMigration,
|
|
26720
|
+
mfaTotpLockoutMigration
|
|
26600
26721
|
]
|
|
26601
26722
|
},
|
|
26602
26723
|
oidc: initMigration("oidc", [
|
|
@@ -27310,6 +27431,7 @@ var auth = async ({
|
|
|
27310
27431
|
authSessionStore,
|
|
27311
27432
|
audit,
|
|
27312
27433
|
credentials,
|
|
27434
|
+
customProviders,
|
|
27313
27435
|
mfa,
|
|
27314
27436
|
passwordless,
|
|
27315
27437
|
lockout,
|
|
@@ -27347,7 +27469,7 @@ var auth = async ({
|
|
|
27347
27469
|
}) => {
|
|
27348
27470
|
if (tracing !== undefined)
|
|
27349
27471
|
await initTracing(tracing);
|
|
27350
|
-
const clientProviders = await buildClientProviders(providersConfiguration, createOAuth2Client);
|
|
27472
|
+
const clientProviders = await buildClientProviders(providersConfiguration, createOAuth2Client, customProviders);
|
|
27351
27473
|
const resolvedCookieSecure = resolveCookieSecure(cookieSecure);
|
|
27352
27474
|
const webhookDispatch = webhooks ? createWebhookDispatcher(webhooks) : undefined;
|
|
27353
27475
|
const auditEmit = audit || webhookDispatch ? createAuditEmitter({
|
|
@@ -27677,6 +27799,7 @@ export {
|
|
|
27677
27799
|
deleteRegisteredClient,
|
|
27678
27800
|
defineScimAttributeMap,
|
|
27679
27801
|
defineProvidersConfiguration,
|
|
27802
|
+
defineProvider,
|
|
27680
27803
|
defineAuthSettings,
|
|
27681
27804
|
defineAuthHtmxConfig,
|
|
27682
27805
|
defineAuthConfig,
|
|
@@ -27822,6 +27945,7 @@ export {
|
|
|
27822
27945
|
createInMemoryAccessTokenStore,
|
|
27823
27946
|
createFgaEngine,
|
|
27824
27947
|
createFederatedTokenStore,
|
|
27948
|
+
createCustomOAuth2Client,
|
|
27825
27949
|
createCredentialOffer,
|
|
27826
27950
|
createAuthHtmxRoutes,
|
|
27827
27951
|
createAuditRedactor,
|
|
@@ -27872,6 +27996,7 @@ export {
|
|
|
27872
27996
|
DEFAULT_VP_ROUTE,
|
|
27873
27997
|
DEFAULT_VERIFICATION_TOKEN_TTL_MS,
|
|
27874
27998
|
DEFAULT_VCI_ROUTE,
|
|
27999
|
+
DEFAULT_TOTP_MAX_ATTEMPTS,
|
|
27875
28000
|
DEFAULT_TOKEN_ROUTE,
|
|
27876
28001
|
DEFAULT_STATUS_ROUTE,
|
|
27877
28002
|
DEFAULT_SSO_SESSION_TTL_MS,
|
|
@@ -27903,5 +28028,5 @@ export {
|
|
|
27903
28028
|
AuthIdentityConflictError
|
|
27904
28029
|
};
|
|
27905
28030
|
|
|
27906
|
-
//# debugId=
|
|
28031
|
+
//# debugId=CF57DC7D601D3EC464756E2164756E21
|
|
27907
28032
|
//# sourceMappingURL=index.js.map
|