@absolutejs/auth 0.48.6 → 0.49.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 +30 -4
- package/dist/cli/migrate.js.map +5 -5
- package/dist/htmx/index.js +5 -3
- package/dist/htmx/index.js.map +3 -3
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1638 -1372
- package/dist/index.js.map +14 -13
- package/dist/mfa/challenge.d.ts +8 -3
- package/dist/mfa/config.d.ts +14 -0
- package/dist/mfa/postgresMfaStore.d.ts +75 -0
- package/dist/mfa/routes.d.ts +62 -1
- package/dist/mfa/sms.d.ts +105 -0
- package/dist/mfa/types.d.ts +6 -1
- package/dist/providers/index.js +5 -3
- package/dist/providers/index.js.map +3 -3
- package/package.json +2 -2
package/dist/mfa/challenge.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Elysia } from 'elysia';
|
|
2
2
|
import { type MfaRouteProps } from './config';
|
|
3
|
-
export declare const mfaChallenge: <UserType>({ authSessionStore, challengeRoute, cookieSecure, encryptionKey, getChallengeUser, getUserId, mfaStore, onMfaChallengeError, onMfaChallengeSuccess, sessionDurationMs }: MfaRouteProps<UserType>) => Elysia<"", {
|
|
3
|
+
export declare const mfaChallenge: <UserType>({ authSessionStore, challengeRoute, cookieSecure, encryptionKey, getChallengeUser, getUserId, mfaStore, onMfaChallengeError, onMfaChallengeSuccess, onSendSmsCode, sessionDurationMs, smsCodeLength, smsCodeTtlMs, smsMaxAttempts }: MfaRouteProps<UserType>) => Elysia<"", {
|
|
4
4
|
decorator: {};
|
|
5
5
|
store: {
|
|
6
6
|
session: import("..").SessionRecord<UserType>;
|
|
@@ -22,14 +22,19 @@ export declare const mfaChallenge: <UserType>({ authSessionStore, challengeRoute
|
|
|
22
22
|
[x: string]: {
|
|
23
23
|
post: {
|
|
24
24
|
body: {
|
|
25
|
-
code
|
|
25
|
+
code?: string | undefined;
|
|
26
|
+
action?: "verify" | "send" | undefined;
|
|
27
|
+
factor?: "sms" | undefined;
|
|
26
28
|
};
|
|
27
29
|
params: {};
|
|
28
30
|
query: unknown;
|
|
29
31
|
headers: unknown;
|
|
30
32
|
response: {
|
|
31
|
-
|
|
33
|
+
400: "SMS code required" | "No SMS code in progress";
|
|
34
|
+
401: "SMS code expired" | "Too many attempts" | "No MFA challenge in progress" | "Invalid MFA code";
|
|
32
35
|
200: {
|
|
36
|
+
readonly status: "sent";
|
|
37
|
+
} | {
|
|
33
38
|
readonly status: "authenticated";
|
|
34
39
|
};
|
|
35
40
|
422: {
|
package/dist/mfa/config.d.ts
CHANGED
|
@@ -4,6 +4,14 @@ import type { MFAStore } from './types';
|
|
|
4
4
|
export declare const DEFAULT_BACKUP_CODE_COUNT = 10;
|
|
5
5
|
export declare const DEFAULT_MFA_ISSUER = "AbsoluteAuth";
|
|
6
6
|
export declare const DEFAULT_MFA_SESSION_TTL_MS: number;
|
|
7
|
+
export declare const DEFAULT_SMS_CODE_LENGTH = 6;
|
|
8
|
+
export declare const DEFAULT_SMS_CODE_TTL_MS: number;
|
|
9
|
+
export declare const DEFAULT_SMS_MAX_ATTEMPTS = 3;
|
|
10
|
+
export type SmsCodeMessage = {
|
|
11
|
+
code: string;
|
|
12
|
+
expiresAt: number;
|
|
13
|
+
phone: string;
|
|
14
|
+
};
|
|
7
15
|
export type MfaConfig<UserType> = {
|
|
8
16
|
mfaStore: MFAStore;
|
|
9
17
|
getUserId: (user: UserType) => string;
|
|
@@ -23,7 +31,13 @@ export type MfaConfig<UserType> = {
|
|
|
23
31
|
onMfaEnrolled?: (context: {
|
|
24
32
|
userId: string;
|
|
25
33
|
}) => void | Promise<void>;
|
|
34
|
+
onSendSmsCode?: (message: SmsCodeMessage) => void | Promise<void>;
|
|
26
35
|
sessionDurationMs?: number;
|
|
36
|
+
smsCodeLength?: number;
|
|
37
|
+
smsCodeTtlMs?: number;
|
|
38
|
+
smsMaxAttempts?: number;
|
|
39
|
+
smsSetupRoute?: RouteString;
|
|
40
|
+
smsVerifyRoute?: RouteString;
|
|
27
41
|
totpSetupRoute?: RouteString;
|
|
28
42
|
totpVerifyRoute?: RouteString;
|
|
29
43
|
};
|
|
@@ -49,6 +49,81 @@ export declare const mfaEnrollmentsTable: import("drizzle-orm/pg-core").PgTableW
|
|
|
49
49
|
identity: undefined;
|
|
50
50
|
generated: undefined;
|
|
51
51
|
}>;
|
|
52
|
+
sms_failed_attempts: import("drizzle-orm/pg-core").PgBuildColumn<"auth_mfa_enrollments", import("drizzle-orm/pg-core").SetHasDefault<import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgSmallIntBuilder>>, {
|
|
53
|
+
name: string;
|
|
54
|
+
tableName: "auth_mfa_enrollments";
|
|
55
|
+
dataType: "number int16";
|
|
56
|
+
data: number;
|
|
57
|
+
driverParam: string | number;
|
|
58
|
+
notNull: true;
|
|
59
|
+
hasDefault: true;
|
|
60
|
+
isPrimaryKey: false;
|
|
61
|
+
isAutoincrement: false;
|
|
62
|
+
hasRuntimeDefault: false;
|
|
63
|
+
enumValues: undefined;
|
|
64
|
+
identity: undefined;
|
|
65
|
+
generated: undefined;
|
|
66
|
+
}>;
|
|
67
|
+
sms_pending_code_expires_at_ms: import("drizzle-orm/pg-core").PgBuildColumn<"auth_mfa_enrollments", import("drizzle-orm/pg-core").PgBigInt53Builder, {
|
|
68
|
+
name: string;
|
|
69
|
+
tableName: "auth_mfa_enrollments";
|
|
70
|
+
dataType: "number int53";
|
|
71
|
+
data: number;
|
|
72
|
+
driverParam: string | number;
|
|
73
|
+
notNull: false;
|
|
74
|
+
hasDefault: false;
|
|
75
|
+
isPrimaryKey: false;
|
|
76
|
+
isAutoincrement: false;
|
|
77
|
+
hasRuntimeDefault: false;
|
|
78
|
+
enumValues: undefined;
|
|
79
|
+
identity: undefined;
|
|
80
|
+
generated: undefined;
|
|
81
|
+
}>;
|
|
82
|
+
sms_pending_code_hash: import("drizzle-orm/pg-core").PgBuildColumn<"auth_mfa_enrollments", import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]>, {
|
|
83
|
+
name: string;
|
|
84
|
+
tableName: "auth_mfa_enrollments";
|
|
85
|
+
dataType: "string";
|
|
86
|
+
data: string;
|
|
87
|
+
driverParam: string;
|
|
88
|
+
notNull: false;
|
|
89
|
+
hasDefault: false;
|
|
90
|
+
isPrimaryKey: false;
|
|
91
|
+
isAutoincrement: false;
|
|
92
|
+
hasRuntimeDefault: false;
|
|
93
|
+
enumValues: undefined;
|
|
94
|
+
identity: undefined;
|
|
95
|
+
generated: undefined;
|
|
96
|
+
}>;
|
|
97
|
+
sms_phone: import("drizzle-orm/pg-core").PgBuildColumn<"auth_mfa_enrollments", import("drizzle-orm/pg-core").PgVarcharBuilder<[string, ...string[]]>, {
|
|
98
|
+
name: string;
|
|
99
|
+
tableName: "auth_mfa_enrollments";
|
|
100
|
+
dataType: "string";
|
|
101
|
+
data: string;
|
|
102
|
+
driverParam: string;
|
|
103
|
+
notNull: false;
|
|
104
|
+
hasDefault: false;
|
|
105
|
+
isPrimaryKey: false;
|
|
106
|
+
isAutoincrement: false;
|
|
107
|
+
hasRuntimeDefault: false;
|
|
108
|
+
enumValues: undefined;
|
|
109
|
+
identity: undefined;
|
|
110
|
+
generated: undefined;
|
|
111
|
+
}>;
|
|
112
|
+
sms_verified: import("drizzle-orm/pg-core").PgBuildColumn<"auth_mfa_enrollments", import("drizzle-orm/pg-core").SetHasDefault<import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgBooleanBuilder>>, {
|
|
113
|
+
name: string;
|
|
114
|
+
tableName: "auth_mfa_enrollments";
|
|
115
|
+
dataType: "boolean";
|
|
116
|
+
data: boolean;
|
|
117
|
+
driverParam: boolean;
|
|
118
|
+
notNull: true;
|
|
119
|
+
hasDefault: true;
|
|
120
|
+
isPrimaryKey: false;
|
|
121
|
+
isAutoincrement: false;
|
|
122
|
+
hasRuntimeDefault: false;
|
|
123
|
+
enumValues: undefined;
|
|
124
|
+
identity: undefined;
|
|
125
|
+
generated: undefined;
|
|
126
|
+
}>;
|
|
52
127
|
totp_secret_ciphertext: import("drizzle-orm/pg-core").PgBuildColumn<"auth_mfa_enrollments", import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]>, {
|
|
53
128
|
name: string;
|
|
54
129
|
tableName: "auth_mfa_enrollments";
|
package/dist/mfa/routes.d.ts
CHANGED
|
@@ -70,6 +70,34 @@ export declare const mfaRoutes: <UserType>(config: MfaRouteProps<UserType>) => E
|
|
|
70
70
|
};
|
|
71
71
|
};
|
|
72
72
|
};
|
|
73
|
+
} & {
|
|
74
|
+
[x: string]: {
|
|
75
|
+
post: {
|
|
76
|
+
body: {
|
|
77
|
+
phone: string;
|
|
78
|
+
};
|
|
79
|
+
params: {};
|
|
80
|
+
query: unknown;
|
|
81
|
+
headers: unknown;
|
|
82
|
+
response: {
|
|
83
|
+
400: "Phone must be in E.164 format";
|
|
84
|
+
401: "Authentication required";
|
|
85
|
+
501: "SMS MFA is not configured";
|
|
86
|
+
200: {
|
|
87
|
+
readonly phone: string;
|
|
88
|
+
};
|
|
89
|
+
422: {
|
|
90
|
+
type: "validation";
|
|
91
|
+
on: string;
|
|
92
|
+
summary?: string;
|
|
93
|
+
message?: string;
|
|
94
|
+
found?: unknown;
|
|
95
|
+
property?: string;
|
|
96
|
+
expected?: string;
|
|
97
|
+
};
|
|
98
|
+
};
|
|
99
|
+
};
|
|
100
|
+
};
|
|
73
101
|
} & {
|
|
74
102
|
[x: string]: {
|
|
75
103
|
post: {
|
|
@@ -80,8 +108,41 @@ export declare const mfaRoutes: <UserType>(config: MfaRouteProps<UserType>) => E
|
|
|
80
108
|
query: unknown;
|
|
81
109
|
headers: unknown;
|
|
82
110
|
response: {
|
|
83
|
-
|
|
111
|
+
400: "No SMS enrollment in progress" | "SMS code expired" | "Invalid SMS code";
|
|
112
|
+
401: "Authentication required";
|
|
113
|
+
200: {
|
|
114
|
+
readonly status: "enrolled";
|
|
115
|
+
};
|
|
116
|
+
422: {
|
|
117
|
+
type: "validation";
|
|
118
|
+
on: string;
|
|
119
|
+
summary?: string;
|
|
120
|
+
message?: string;
|
|
121
|
+
found?: unknown;
|
|
122
|
+
property?: string;
|
|
123
|
+
expected?: string;
|
|
124
|
+
};
|
|
125
|
+
429: "Too many attempts";
|
|
126
|
+
};
|
|
127
|
+
};
|
|
128
|
+
};
|
|
129
|
+
} & {
|
|
130
|
+
[x: string]: {
|
|
131
|
+
post: {
|
|
132
|
+
body: {
|
|
133
|
+
code?: string | undefined;
|
|
134
|
+
action?: "verify" | "send" | undefined;
|
|
135
|
+
factor?: "sms" | undefined;
|
|
136
|
+
};
|
|
137
|
+
params: {};
|
|
138
|
+
query: unknown;
|
|
139
|
+
headers: unknown;
|
|
140
|
+
response: {
|
|
141
|
+
400: "SMS code required" | "No SMS code in progress";
|
|
142
|
+
401: "SMS code expired" | "Too many attempts" | "No MFA challenge in progress" | "Invalid MFA code";
|
|
84
143
|
200: {
|
|
144
|
+
readonly status: "sent";
|
|
145
|
+
} | {
|
|
85
146
|
readonly status: "authenticated";
|
|
86
147
|
};
|
|
87
148
|
422: {
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { Elysia } from 'elysia';
|
|
2
|
+
import { type MfaRouteProps, type SmsCodeMessage } from './config';
|
|
3
|
+
import type { MfaEnrollment, MFAStore } from './types';
|
|
4
|
+
export declare const isE164Phone: (phone: string) => boolean;
|
|
5
|
+
export declare const issueAndStoreSmsCode: ({ codeLength, enrollment, mfaStore, onSendSmsCode, ttlMs }: {
|
|
6
|
+
codeLength: number;
|
|
7
|
+
enrollment: MfaEnrollment;
|
|
8
|
+
mfaStore: MFAStore;
|
|
9
|
+
onSendSmsCode?: (message: SmsCodeMessage) => void | Promise<void>;
|
|
10
|
+
ttlMs: number;
|
|
11
|
+
}) => Promise<number | undefined>;
|
|
12
|
+
export declare const maskPhone: (phone: string) => string;
|
|
13
|
+
export declare const mfaSmsRoutes: <UserType>({ authSessionStore, getUserId, mfaStore, onMfaEnrolled, onSendSmsCode, smsCodeLength, smsCodeTtlMs, smsMaxAttempts, smsSetupRoute, smsVerifyRoute }: MfaRouteProps<UserType>) => Elysia<"", {
|
|
14
|
+
decorator: {};
|
|
15
|
+
store: {
|
|
16
|
+
session: import("..").SessionRecord<UserType>;
|
|
17
|
+
unregisteredSession: import("..").UnregisteredSessionRecord;
|
|
18
|
+
};
|
|
19
|
+
derive: {};
|
|
20
|
+
resolve: {};
|
|
21
|
+
}, {
|
|
22
|
+
typebox: {};
|
|
23
|
+
error: {};
|
|
24
|
+
}, {
|
|
25
|
+
schema: {};
|
|
26
|
+
standaloneSchema: {};
|
|
27
|
+
macro: {};
|
|
28
|
+
macroFn: {};
|
|
29
|
+
parser: {};
|
|
30
|
+
response: {};
|
|
31
|
+
}, {
|
|
32
|
+
[x: string]: {
|
|
33
|
+
post: {
|
|
34
|
+
body: {
|
|
35
|
+
phone: string;
|
|
36
|
+
};
|
|
37
|
+
params: {};
|
|
38
|
+
query: unknown;
|
|
39
|
+
headers: unknown;
|
|
40
|
+
response: {
|
|
41
|
+
400: "Phone must be in E.164 format";
|
|
42
|
+
401: "Authentication required";
|
|
43
|
+
501: "SMS MFA is not configured";
|
|
44
|
+
200: {
|
|
45
|
+
readonly phone: string;
|
|
46
|
+
};
|
|
47
|
+
422: {
|
|
48
|
+
type: "validation";
|
|
49
|
+
on: string;
|
|
50
|
+
summary?: string;
|
|
51
|
+
message?: string;
|
|
52
|
+
found?: unknown;
|
|
53
|
+
property?: string;
|
|
54
|
+
expected?: string;
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
} & {
|
|
60
|
+
[x: string]: {
|
|
61
|
+
post: {
|
|
62
|
+
body: {
|
|
63
|
+
code: string;
|
|
64
|
+
};
|
|
65
|
+
params: {};
|
|
66
|
+
query: unknown;
|
|
67
|
+
headers: unknown;
|
|
68
|
+
response: {
|
|
69
|
+
400: "No SMS enrollment in progress" | "SMS code expired" | "Invalid SMS code";
|
|
70
|
+
401: "Authentication required";
|
|
71
|
+
200: {
|
|
72
|
+
readonly status: "enrolled";
|
|
73
|
+
};
|
|
74
|
+
422: {
|
|
75
|
+
type: "validation";
|
|
76
|
+
on: string;
|
|
77
|
+
summary?: string;
|
|
78
|
+
message?: string;
|
|
79
|
+
found?: unknown;
|
|
80
|
+
property?: string;
|
|
81
|
+
expected?: string;
|
|
82
|
+
};
|
|
83
|
+
429: "Too many attempts";
|
|
84
|
+
};
|
|
85
|
+
};
|
|
86
|
+
};
|
|
87
|
+
}, {
|
|
88
|
+
derive: {};
|
|
89
|
+
resolve: {};
|
|
90
|
+
schema: {};
|
|
91
|
+
standaloneSchema: {};
|
|
92
|
+
response: {};
|
|
93
|
+
}, {
|
|
94
|
+
derive: {};
|
|
95
|
+
resolve: {};
|
|
96
|
+
schema: {};
|
|
97
|
+
standaloneSchema: {};
|
|
98
|
+
response: {};
|
|
99
|
+
} & {
|
|
100
|
+
derive: {};
|
|
101
|
+
resolve: {};
|
|
102
|
+
schema: {};
|
|
103
|
+
standaloneSchema: {};
|
|
104
|
+
response: {};
|
|
105
|
+
}>;
|
package/dist/mfa/types.d.ts
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
|
-
export type MfaFactorType = 'backup_codes' | 'totp';
|
|
1
|
+
export type MfaFactorType = 'backup_codes' | 'sms' | 'totp';
|
|
2
2
|
export type MfaEnrollment = {
|
|
3
3
|
backupCodeHashes: string[];
|
|
4
4
|
createdAt: number;
|
|
5
5
|
lastUsedAt?: number;
|
|
6
|
+
smsFailedAttempts?: number;
|
|
7
|
+
smsPendingCodeHash?: string;
|
|
8
|
+
smsPendingCodeExpiresAt?: number;
|
|
9
|
+
smsPhone?: string;
|
|
10
|
+
smsVerified: boolean;
|
|
6
11
|
totpSecretCiphertext?: string;
|
|
7
12
|
totpVerified: boolean;
|
|
8
13
|
updatedAt: number;
|
package/dist/providers/index.js
CHANGED
|
@@ -795,10 +795,10 @@ var providers = defineProviders({
|
|
|
795
795
|
isOIDC: false,
|
|
796
796
|
isRefreshable: true,
|
|
797
797
|
profileRequest: {
|
|
798
|
-
authIn: "
|
|
798
|
+
authIn: "path",
|
|
799
799
|
encoding: "application/json",
|
|
800
800
|
method: "GET",
|
|
801
|
-
url: "https://api.hubapi.com/oauth/v1/access-tokens
|
|
801
|
+
url: "https://api.hubapi.com/oauth/v1/access-tokens"
|
|
802
802
|
},
|
|
803
803
|
scopeRequired: true,
|
|
804
804
|
subject: ["hub_id"],
|
|
@@ -2448,6 +2448,8 @@ var createOAuth2Client = async (providerName, config) => {
|
|
|
2448
2448
|
const profileHeaders = Object.fromEntries(headerEntries.filter(([, value]) => value !== ""));
|
|
2449
2449
|
if (authIn === "header") {
|
|
2450
2450
|
profileHeaders.Authorization = `Bearer ${accessToken}`;
|
|
2451
|
+
} else if (authIn === "path") {
|
|
2452
|
+
endpoint.pathname = `${endpoint.pathname.replace(/\/+$/, "")}/${accessToken}`;
|
|
2451
2453
|
} else {
|
|
2452
2454
|
endpoint.searchParams.append("access_token", accessToken);
|
|
2453
2455
|
}
|
|
@@ -2608,5 +2610,5 @@ export {
|
|
|
2608
2610
|
decodeJWT
|
|
2609
2611
|
};
|
|
2610
2612
|
|
|
2611
|
-
//# debugId=
|
|
2613
|
+
//# debugId=303770E52ED6DEBF64756E2164756E21
|
|
2612
2614
|
//# sourceMappingURL=index.js.map
|