@absolutejs/auth 0.26.0-beta.1 → 0.26.0-beta.3
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/audit/config.d.ts +2 -1
- package/dist/audit/types.d.ts +1 -1
- package/dist/authorization/config.d.ts +19 -0
- package/dist/authorization/protectPermission.d.ts +52 -0
- package/dist/compliance/cipher.d.ts +5 -0
- package/dist/compliance/config.d.ts +18 -0
- package/dist/compliance/redaction.d.ts +8 -0
- package/dist/compliance/routes.d.ts +89 -0
- package/dist/htmx/index.js +494 -98
- package/dist/htmx/index.js.map +3 -3
- package/dist/index.d.ts +2539 -344
- package/dist/index.js +3679 -1619
- package/dist/index.js.map +33 -13
- package/dist/lockout/redisLockoutStore.d.ts +3 -0
- package/dist/providers/clients.d.ts +3 -3
- package/dist/routes/authorize.d.ts +2 -2
- package/dist/routes/protectRoute.d.ts +2 -2
- package/dist/scim/config.d.ts +55 -0
- package/dist/scim/inMemoryScimTokenStore.d.ts +2 -0
- package/dist/scim/postgresScimTokenStore.d.ts +102 -0
- package/dist/scim/routes.d.ts +296 -0
- package/dist/scim/serialize.d.ts +45 -0
- package/dist/scim/types.d.ts +52 -0
- package/dist/session/promote.d.ts +9 -2
- package/dist/sso/config.d.ts +104 -0
- package/dist/sso/discoveryRoute.d.ts +63 -0
- package/dist/sso/inMemorySsoConnectionStore.d.ts +2 -0
- package/dist/sso/oidcRoutes.d.ts +97 -0
- package/dist/sso/postgresSsoConnectionStore.d.ts +139 -0
- package/dist/sso/samlRoutes.d.ts +176 -0
- package/dist/sso/types.d.ts +39 -0
- package/dist/stores/redis.d.ts +5 -0
- package/dist/typebox.d.ts +1 -1
- package/dist/types.d.ts +36 -0
- package/dist/webauthn/adapter.d.ts +59 -0
- package/dist/webauthn/config.d.ts +35 -0
- package/dist/webauthn/inMemoryWebAuthnCredentialStore.d.ts +2 -0
- package/dist/webauthn/postgresWebAuthnCredentialStore.d.ts +172 -0
- package/dist/webauthn/routes.d.ts +155 -0
- package/dist/webauthn/types.d.ts +17 -0
- package/package.json +2 -2
package/dist/types.d.ts
CHANGED
|
@@ -2,13 +2,18 @@ import { CredentialsFor, NonEmptyArray, OAuth2Client, OAuth2TokenResponse, Provi
|
|
|
2
2
|
import { Cookie, status as statusType, redirect as redirectType } from 'elysia';
|
|
3
3
|
import { ElysiaCustomStatusResponse } from 'elysia/error';
|
|
4
4
|
import type { AuditConfig } from './audit/config';
|
|
5
|
+
import type { AuthorizationConfig } from './authorization/config';
|
|
6
|
+
import type { ComplianceConfig } from './compliance/config';
|
|
5
7
|
import type { CredentialsConfig } from './credentials/config';
|
|
6
8
|
import type { AuthIdentityConflict } from './errors';
|
|
7
9
|
import type { AuthHtmxConfig, AuthHtmxUser } from './htmx/types';
|
|
8
10
|
import type { LockoutConfig } from './lockout/config';
|
|
9
11
|
import type { MfaConfig } from './mfa/config';
|
|
12
|
+
import type { ScimConfig } from './scim/config';
|
|
10
13
|
import type { SessionsConfig } from './session/sessionsConfig';
|
|
11
14
|
import type { AuthSessionStore } from './session/types';
|
|
15
|
+
import type { SSOConfig } from './sso/config';
|
|
16
|
+
import type { WebAuthnConfig } from './webauthn/config';
|
|
12
17
|
export type AuthIntent = 'login' | 'link_identity' | 'link_connector';
|
|
13
18
|
export type OAuth2ProviderClientConfiguration<Provider extends ProviderOption> = {
|
|
14
19
|
credentials: CredentialsFor<Provider>;
|
|
@@ -34,6 +39,14 @@ export type SessionData<UserType> = {
|
|
|
34
39
|
/** When the session was last established by an actual authentication (login, OAuth
|
|
35
40
|
* callback, or MFA challenge — NOT a token refresh). Drives step-up `requireRecentAuth`. */
|
|
36
41
|
authenticatedAt?: number;
|
|
42
|
+
/** SAML SP-initiated Single Logout context, captured at the SAML ACS. Lets
|
|
43
|
+
* `{ssoRoute}/saml/:org/logout` build a signed LogoutRequest (the IdP needs the original
|
|
44
|
+
* NameID + SessionIndex) for the connection the session was created from. */
|
|
45
|
+
samlLogout?: {
|
|
46
|
+
connectionId: string;
|
|
47
|
+
nameId: string;
|
|
48
|
+
sessionIndex?: string;
|
|
49
|
+
};
|
|
37
50
|
};
|
|
38
51
|
export type SessionRecord<UserType> = Record<UserSessionId, SessionData<UserType>>;
|
|
39
52
|
export type UnregisteredSessionData = {
|
|
@@ -181,6 +194,29 @@ export type AuthConfig<UserType> = {
|
|
|
181
194
|
* sessions) and `DELETE /auth/sessions/:id` (remote revoke). Requires an
|
|
182
195
|
* `authSessionStore` that can enumerate sessions. */
|
|
183
196
|
sessions?: SessionsConfig<UserType>;
|
|
197
|
+
/** Per-organization enterprise SSO (the WorkOS-style model). When present, mounts
|
|
198
|
+
* `GET {ssoRoute}/oidc/:organizationId/authorize` + `.../callback`, resolves the org's
|
|
199
|
+
* OIDC connection from `ssoConnectionStore`, verifies the id_token in-house against the
|
|
200
|
+
* issuer's JWKS, and mints the same `SessionData<UserType>` as every other flow. */
|
|
201
|
+
sso?: SSOConfig<UserType>;
|
|
202
|
+
/** SCIM 2.0 auto-provisioning for enterprise directory sync (Okta / Azure AD). When present,
|
|
203
|
+
* mounts `{scimRoute}/Users` (+ `/ServiceProviderConfig`) with per-org bearer-token auth via
|
|
204
|
+
* `scimTokenStore`, and maps SCIM resources to the consumer's user store through hooks. */
|
|
205
|
+
scim?: ScimConfig;
|
|
206
|
+
/** Role-based / attribute-based access control (E4). When present, `auth()` exposes a
|
|
207
|
+
* `protectPermission(check, handler)` derive (alongside `protectRoute`) that delegates the
|
|
208
|
+
* decision to your `hasPermission` hook — the package stays schema-agnostic about roles. */
|
|
209
|
+
authorization?: AuthorizationConfig<UserType>;
|
|
210
|
+
/** GDPR/CCPA self-service compliance (E5). When present, mounts `GET {complianceRoute}/export`
|
|
211
|
+
* (right to access) and `DELETE {complianceRoute}` (right to erasure — runs your delete hook,
|
|
212
|
+
* revokes the user's sessions, clears the cookie). Pair with `audit.redact` for PII redaction. */
|
|
213
|
+
compliance?: ComplianceConfig<UserType>;
|
|
214
|
+
/** Passwordless / passkey auth (WebAuthn). When present, mounts the registration ceremony
|
|
215
|
+
* (`{webauthnRoute}/register/options` + `/verify`, adds a passkey to the authenticated caller)
|
|
216
|
+
* and the authentication ceremony (`.../authenticate/options` + `/verify`, passwordless sign-in
|
|
217
|
+
* → mints the same `SessionData<UserType>`). A `webauthnAdapter` wraps a vetted library (e.g.
|
|
218
|
+
* `@simplewebauthn/server`); the package never bundles the WebAuthn crypto. */
|
|
219
|
+
webauthn?: WebAuthnConfig<UserType>;
|
|
184
220
|
/** Enable the built-in HTMX fragment routes (login, identities, connectors,
|
|
185
221
|
* account, signout, delete-account). Supply provider display data + the
|
|
186
222
|
* identity/connector data actions; the package owns the route wiring and
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
export type WebAuthnCredentialDescriptor = {
|
|
2
|
+
id: string;
|
|
3
|
+
transports?: string[];
|
|
4
|
+
};
|
|
5
|
+
export type WebAuthnRegistrationOptions = {
|
|
6
|
+
challenge: string;
|
|
7
|
+
options: Record<string, unknown>;
|
|
8
|
+
};
|
|
9
|
+
export type WebAuthnAuthenticationOptions = {
|
|
10
|
+
challenge: string;
|
|
11
|
+
options: Record<string, unknown>;
|
|
12
|
+
};
|
|
13
|
+
export type WebAuthnRegistrationResult = {
|
|
14
|
+
credential?: {
|
|
15
|
+
backedUp?: boolean;
|
|
16
|
+
counter: number;
|
|
17
|
+
credentialId: string;
|
|
18
|
+
deviceType?: string;
|
|
19
|
+
publicKey: string;
|
|
20
|
+
transports?: string[];
|
|
21
|
+
};
|
|
22
|
+
verified: boolean;
|
|
23
|
+
};
|
|
24
|
+
export type WebAuthnAuthenticationResult = {
|
|
25
|
+
newCounter?: number;
|
|
26
|
+
verified: boolean;
|
|
27
|
+
};
|
|
28
|
+
export type WebAuthnAdapter = {
|
|
29
|
+
createAuthenticationOptions: (request: {
|
|
30
|
+
allowCredentials: WebAuthnCredentialDescriptor[];
|
|
31
|
+
rpId: string;
|
|
32
|
+
}) => Promise<WebAuthnAuthenticationOptions> | WebAuthnAuthenticationOptions;
|
|
33
|
+
createRegistrationOptions: (request: {
|
|
34
|
+
excludeCredentials: WebAuthnCredentialDescriptor[];
|
|
35
|
+
rpId: string;
|
|
36
|
+
rpName: string;
|
|
37
|
+
userDisplayName: string;
|
|
38
|
+
userId: string;
|
|
39
|
+
userName: string;
|
|
40
|
+
}) => Promise<WebAuthnRegistrationOptions> | WebAuthnRegistrationOptions;
|
|
41
|
+
verifyAuthentication: (request: {
|
|
42
|
+
credential: {
|
|
43
|
+
counter: number;
|
|
44
|
+
credentialId: string;
|
|
45
|
+
publicKey: string;
|
|
46
|
+
transports?: string[];
|
|
47
|
+
};
|
|
48
|
+
expectedChallenge: string;
|
|
49
|
+
expectedOrigin: string;
|
|
50
|
+
expectedRPID: string;
|
|
51
|
+
response: unknown;
|
|
52
|
+
}) => Promise<WebAuthnAuthenticationResult>;
|
|
53
|
+
verifyRegistration: (request: {
|
|
54
|
+
expectedChallenge: string;
|
|
55
|
+
expectedOrigin: string;
|
|
56
|
+
expectedRPID: string;
|
|
57
|
+
response: unknown;
|
|
58
|
+
}) => Promise<WebAuthnRegistrationResult>;
|
|
59
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { AuditEmitter } from '../audit/config';
|
|
2
|
+
import type { AuthSessionStore } from '../session/types';
|
|
3
|
+
import type { RouteString, UserSessionId } from '../types';
|
|
4
|
+
import type { WebAuthnAdapter } from './adapter';
|
|
5
|
+
import type { WebAuthnCredentialStore } from './types';
|
|
6
|
+
export declare const DEFAULT_WEBAUTHN_CHALLENGE_TTL_MS = 300000;
|
|
7
|
+
export declare const DEFAULT_WEBAUTHN_ROUTE: RouteString;
|
|
8
|
+
export declare const DEFAULT_WEBAUTHN_SESSION_TTL_MS: number;
|
|
9
|
+
export declare const WEBAUTHN_CHALLENGE_COOKIE = "webauthn_challenge";
|
|
10
|
+
export type WebAuthnConfig<UserType> = {
|
|
11
|
+
credentialStore: WebAuthnCredentialStore;
|
|
12
|
+
getUserId: (user: UserType) => string;
|
|
13
|
+
getWebAuthnUser: (userId: string) => Promise<UserType | null | undefined> | UserType | null | undefined;
|
|
14
|
+
origin: string;
|
|
15
|
+
rpId: string;
|
|
16
|
+
rpName: string;
|
|
17
|
+
webauthnAdapter: WebAuthnAdapter;
|
|
18
|
+
challengeDurationMs?: number;
|
|
19
|
+
getUserDisplayName?: (user: UserType) => string;
|
|
20
|
+
getUserName?: (user: UserType) => string;
|
|
21
|
+
onWebAuthnAuthenticated?: (context: {
|
|
22
|
+
user: UserType;
|
|
23
|
+
userSessionId: UserSessionId;
|
|
24
|
+
}) => void | Promise<void>;
|
|
25
|
+
onWebAuthnRegistered?: (context: {
|
|
26
|
+
credentialId: string;
|
|
27
|
+
userId: string;
|
|
28
|
+
}) => void | Promise<void>;
|
|
29
|
+
sessionDurationMs?: number;
|
|
30
|
+
webauthnRoute?: RouteString;
|
|
31
|
+
};
|
|
32
|
+
export type WebAuthnRouteProps<UserType> = WebAuthnConfig<UserType> & {
|
|
33
|
+
authSessionStore?: AuthSessionStore<UserType>;
|
|
34
|
+
emit?: AuditEmitter;
|
|
35
|
+
};
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { type AnyPgDatabase } from '../stores/postgres';
|
|
2
|
+
import type { WebAuthnCredentialStore } from './types';
|
|
3
|
+
export declare const webauthnCredentialsTable: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
4
|
+
name: "auth_webauthn_credentials";
|
|
5
|
+
schema: undefined;
|
|
6
|
+
columns: {
|
|
7
|
+
backed_up: import("drizzle-orm/pg-core").PgColumn<{
|
|
8
|
+
name: "backed_up";
|
|
9
|
+
tableName: "auth_webauthn_credentials";
|
|
10
|
+
dataType: "boolean";
|
|
11
|
+
columnType: "PgBoolean";
|
|
12
|
+
data: boolean;
|
|
13
|
+
driverParam: boolean;
|
|
14
|
+
notNull: false;
|
|
15
|
+
hasDefault: false;
|
|
16
|
+
isPrimaryKey: false;
|
|
17
|
+
isAutoincrement: false;
|
|
18
|
+
hasRuntimeDefault: false;
|
|
19
|
+
enumValues: undefined;
|
|
20
|
+
baseColumn: never;
|
|
21
|
+
identity: undefined;
|
|
22
|
+
generated: undefined;
|
|
23
|
+
}, {}, {}>;
|
|
24
|
+
counter: import("drizzle-orm/pg-core").PgColumn<{
|
|
25
|
+
name: "counter";
|
|
26
|
+
tableName: "auth_webauthn_credentials";
|
|
27
|
+
dataType: "number";
|
|
28
|
+
columnType: "PgBigInt53";
|
|
29
|
+
data: number;
|
|
30
|
+
driverParam: string | number;
|
|
31
|
+
notNull: true;
|
|
32
|
+
hasDefault: true;
|
|
33
|
+
isPrimaryKey: false;
|
|
34
|
+
isAutoincrement: false;
|
|
35
|
+
hasRuntimeDefault: false;
|
|
36
|
+
enumValues: undefined;
|
|
37
|
+
baseColumn: never;
|
|
38
|
+
identity: undefined;
|
|
39
|
+
generated: undefined;
|
|
40
|
+
}, {}, {}>;
|
|
41
|
+
created_at_ms: import("drizzle-orm/pg-core").PgColumn<{
|
|
42
|
+
name: "created_at_ms";
|
|
43
|
+
tableName: "auth_webauthn_credentials";
|
|
44
|
+
dataType: "number";
|
|
45
|
+
columnType: "PgBigInt53";
|
|
46
|
+
data: number;
|
|
47
|
+
driverParam: string | number;
|
|
48
|
+
notNull: true;
|
|
49
|
+
hasDefault: false;
|
|
50
|
+
isPrimaryKey: false;
|
|
51
|
+
isAutoincrement: false;
|
|
52
|
+
hasRuntimeDefault: false;
|
|
53
|
+
enumValues: undefined;
|
|
54
|
+
baseColumn: never;
|
|
55
|
+
identity: undefined;
|
|
56
|
+
generated: undefined;
|
|
57
|
+
}, {}, {}>;
|
|
58
|
+
credential_id: import("drizzle-orm/pg-core").PgColumn<{
|
|
59
|
+
name: "credential_id";
|
|
60
|
+
tableName: "auth_webauthn_credentials";
|
|
61
|
+
dataType: "string";
|
|
62
|
+
columnType: "PgVarchar";
|
|
63
|
+
data: string;
|
|
64
|
+
driverParam: string;
|
|
65
|
+
notNull: true;
|
|
66
|
+
hasDefault: false;
|
|
67
|
+
isPrimaryKey: true;
|
|
68
|
+
isAutoincrement: false;
|
|
69
|
+
hasRuntimeDefault: false;
|
|
70
|
+
enumValues: [string, ...string[]];
|
|
71
|
+
baseColumn: never;
|
|
72
|
+
identity: undefined;
|
|
73
|
+
generated: undefined;
|
|
74
|
+
}, {}, {
|
|
75
|
+
length: 255;
|
|
76
|
+
}>;
|
|
77
|
+
device_type: import("drizzle-orm/pg-core").PgColumn<{
|
|
78
|
+
name: "device_type";
|
|
79
|
+
tableName: "auth_webauthn_credentials";
|
|
80
|
+
dataType: "string";
|
|
81
|
+
columnType: "PgVarchar";
|
|
82
|
+
data: string;
|
|
83
|
+
driverParam: string;
|
|
84
|
+
notNull: false;
|
|
85
|
+
hasDefault: false;
|
|
86
|
+
isPrimaryKey: false;
|
|
87
|
+
isAutoincrement: false;
|
|
88
|
+
hasRuntimeDefault: false;
|
|
89
|
+
enumValues: [string, ...string[]];
|
|
90
|
+
baseColumn: never;
|
|
91
|
+
identity: undefined;
|
|
92
|
+
generated: undefined;
|
|
93
|
+
}, {}, {
|
|
94
|
+
length: 32;
|
|
95
|
+
}>;
|
|
96
|
+
last_used_at_ms: import("drizzle-orm/pg-core").PgColumn<{
|
|
97
|
+
name: "last_used_at_ms";
|
|
98
|
+
tableName: "auth_webauthn_credentials";
|
|
99
|
+
dataType: "number";
|
|
100
|
+
columnType: "PgBigInt53";
|
|
101
|
+
data: number;
|
|
102
|
+
driverParam: string | number;
|
|
103
|
+
notNull: false;
|
|
104
|
+
hasDefault: false;
|
|
105
|
+
isPrimaryKey: false;
|
|
106
|
+
isAutoincrement: false;
|
|
107
|
+
hasRuntimeDefault: false;
|
|
108
|
+
enumValues: undefined;
|
|
109
|
+
baseColumn: never;
|
|
110
|
+
identity: undefined;
|
|
111
|
+
generated: undefined;
|
|
112
|
+
}, {}, {}>;
|
|
113
|
+
public_key: import("drizzle-orm/pg-core").PgColumn<{
|
|
114
|
+
name: "public_key";
|
|
115
|
+
tableName: "auth_webauthn_credentials";
|
|
116
|
+
dataType: "string";
|
|
117
|
+
columnType: "PgText";
|
|
118
|
+
data: string;
|
|
119
|
+
driverParam: string;
|
|
120
|
+
notNull: true;
|
|
121
|
+
hasDefault: false;
|
|
122
|
+
isPrimaryKey: false;
|
|
123
|
+
isAutoincrement: false;
|
|
124
|
+
hasRuntimeDefault: false;
|
|
125
|
+
enumValues: [string, ...string[]];
|
|
126
|
+
baseColumn: never;
|
|
127
|
+
identity: undefined;
|
|
128
|
+
generated: undefined;
|
|
129
|
+
}, {}, {}>;
|
|
130
|
+
transports: import("drizzle-orm/pg-core").PgColumn<{
|
|
131
|
+
name: "transports";
|
|
132
|
+
tableName: "auth_webauthn_credentials";
|
|
133
|
+
dataType: "json";
|
|
134
|
+
columnType: "PgJsonb";
|
|
135
|
+
data: string[];
|
|
136
|
+
driverParam: unknown;
|
|
137
|
+
notNull: false;
|
|
138
|
+
hasDefault: false;
|
|
139
|
+
isPrimaryKey: false;
|
|
140
|
+
isAutoincrement: false;
|
|
141
|
+
hasRuntimeDefault: false;
|
|
142
|
+
enumValues: undefined;
|
|
143
|
+
baseColumn: never;
|
|
144
|
+
identity: undefined;
|
|
145
|
+
generated: undefined;
|
|
146
|
+
}, {}, {
|
|
147
|
+
$type: string[];
|
|
148
|
+
}>;
|
|
149
|
+
user_id: import("drizzle-orm/pg-core").PgColumn<{
|
|
150
|
+
name: "user_id";
|
|
151
|
+
tableName: "auth_webauthn_credentials";
|
|
152
|
+
dataType: "string";
|
|
153
|
+
columnType: "PgVarchar";
|
|
154
|
+
data: string;
|
|
155
|
+
driverParam: string;
|
|
156
|
+
notNull: true;
|
|
157
|
+
hasDefault: false;
|
|
158
|
+
isPrimaryKey: false;
|
|
159
|
+
isAutoincrement: false;
|
|
160
|
+
hasRuntimeDefault: false;
|
|
161
|
+
enumValues: [string, ...string[]];
|
|
162
|
+
baseColumn: never;
|
|
163
|
+
identity: undefined;
|
|
164
|
+
generated: undefined;
|
|
165
|
+
}, {}, {
|
|
166
|
+
length: 255;
|
|
167
|
+
}>;
|
|
168
|
+
};
|
|
169
|
+
dialect: "pg";
|
|
170
|
+
}>;
|
|
171
|
+
export declare const createNeonWebAuthnCredentialStore: (databaseUrl: string) => WebAuthnCredentialStore;
|
|
172
|
+
export declare const createPostgresWebAuthnCredentialStore: (db: AnyPgDatabase) => WebAuthnCredentialStore;
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { Elysia } from 'elysia';
|
|
2
|
+
import { type WebAuthnRouteProps } from './config';
|
|
3
|
+
export declare const webauthnRoutes: <UserType>({ authSessionStore, challengeDurationMs, credentialStore, emit, getUserDisplayName, getUserId, getUserName, getWebAuthnUser, onWebAuthnAuthenticated, onWebAuthnRegistered, origin, rpId, rpName, sessionDurationMs, webauthnAdapter, webauthnRoute }: WebAuthnRouteProps<UserType>) => Elysia<"", {
|
|
4
|
+
decorator: {};
|
|
5
|
+
store: {
|
|
6
|
+
session: import("..").SessionRecord<UserType>;
|
|
7
|
+
unregisteredSession: import("..").UnregisteredSessionRecord;
|
|
8
|
+
};
|
|
9
|
+
derive: {};
|
|
10
|
+
resolve: {};
|
|
11
|
+
}, {
|
|
12
|
+
typebox: {};
|
|
13
|
+
error: {};
|
|
14
|
+
}, {
|
|
15
|
+
schema: {};
|
|
16
|
+
standaloneSchema: {};
|
|
17
|
+
macro: {};
|
|
18
|
+
macroFn: {};
|
|
19
|
+
parser: {};
|
|
20
|
+
response: {};
|
|
21
|
+
}, {
|
|
22
|
+
[x: string]: {
|
|
23
|
+
register: {
|
|
24
|
+
options: {
|
|
25
|
+
post: {
|
|
26
|
+
body: unknown;
|
|
27
|
+
params: {};
|
|
28
|
+
query: unknown;
|
|
29
|
+
headers: unknown;
|
|
30
|
+
response: {
|
|
31
|
+
200: {
|
|
32
|
+
[x: string]: unknown;
|
|
33
|
+
};
|
|
34
|
+
401: "Authentication required";
|
|
35
|
+
422: {
|
|
36
|
+
type: "validation";
|
|
37
|
+
on: string;
|
|
38
|
+
summary?: string;
|
|
39
|
+
message?: string;
|
|
40
|
+
found?: unknown;
|
|
41
|
+
property?: string;
|
|
42
|
+
expected?: string;
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
} & {
|
|
50
|
+
[x: string]: {
|
|
51
|
+
register: {
|
|
52
|
+
verify: {
|
|
53
|
+
post: {
|
|
54
|
+
body: {};
|
|
55
|
+
params: {};
|
|
56
|
+
query: unknown;
|
|
57
|
+
headers: unknown;
|
|
58
|
+
response: {
|
|
59
|
+
200: {
|
|
60
|
+
readonly credentialId: string;
|
|
61
|
+
readonly verified: true;
|
|
62
|
+
};
|
|
63
|
+
400: "No registration challenge in progress" | "WebAuthn registration failed";
|
|
64
|
+
401: "Authentication required";
|
|
65
|
+
422: {
|
|
66
|
+
type: "validation";
|
|
67
|
+
on: string;
|
|
68
|
+
summary?: string;
|
|
69
|
+
message?: string;
|
|
70
|
+
found?: unknown;
|
|
71
|
+
property?: string;
|
|
72
|
+
expected?: string;
|
|
73
|
+
};
|
|
74
|
+
};
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
};
|
|
78
|
+
};
|
|
79
|
+
} & {
|
|
80
|
+
[x: string]: {
|
|
81
|
+
authenticate: {
|
|
82
|
+
options: {
|
|
83
|
+
post: {
|
|
84
|
+
body: unknown;
|
|
85
|
+
params: {};
|
|
86
|
+
query: unknown;
|
|
87
|
+
headers: unknown;
|
|
88
|
+
response: {
|
|
89
|
+
200: {
|
|
90
|
+
[x: string]: unknown;
|
|
91
|
+
};
|
|
92
|
+
422: {
|
|
93
|
+
type: "validation";
|
|
94
|
+
on: string;
|
|
95
|
+
summary?: string;
|
|
96
|
+
message?: string;
|
|
97
|
+
found?: unknown;
|
|
98
|
+
property?: string;
|
|
99
|
+
expected?: string;
|
|
100
|
+
};
|
|
101
|
+
};
|
|
102
|
+
};
|
|
103
|
+
};
|
|
104
|
+
};
|
|
105
|
+
};
|
|
106
|
+
} & {
|
|
107
|
+
[x: string]: {
|
|
108
|
+
authenticate: {
|
|
109
|
+
verify: {
|
|
110
|
+
post: {
|
|
111
|
+
body: {
|
|
112
|
+
id: string;
|
|
113
|
+
};
|
|
114
|
+
params: {};
|
|
115
|
+
query: unknown;
|
|
116
|
+
headers: unknown;
|
|
117
|
+
response: {
|
|
118
|
+
200: {
|
|
119
|
+
readonly status: "authenticated";
|
|
120
|
+
};
|
|
121
|
+
400: "No authentication challenge in progress";
|
|
122
|
+
401: "Unknown credential" | "WebAuthn authentication failed";
|
|
123
|
+
422: {
|
|
124
|
+
type: "validation";
|
|
125
|
+
on: string;
|
|
126
|
+
summary?: string;
|
|
127
|
+
message?: string;
|
|
128
|
+
found?: unknown;
|
|
129
|
+
property?: string;
|
|
130
|
+
expected?: string;
|
|
131
|
+
};
|
|
132
|
+
};
|
|
133
|
+
};
|
|
134
|
+
};
|
|
135
|
+
};
|
|
136
|
+
};
|
|
137
|
+
}, {
|
|
138
|
+
derive: {};
|
|
139
|
+
resolve: {};
|
|
140
|
+
schema: {};
|
|
141
|
+
standaloneSchema: {};
|
|
142
|
+
response: {};
|
|
143
|
+
}, {
|
|
144
|
+
derive: {};
|
|
145
|
+
resolve: {};
|
|
146
|
+
schema: {};
|
|
147
|
+
standaloneSchema: {};
|
|
148
|
+
response: {};
|
|
149
|
+
} & {
|
|
150
|
+
derive: {};
|
|
151
|
+
resolve: {};
|
|
152
|
+
schema: {};
|
|
153
|
+
standaloneSchema: {};
|
|
154
|
+
response: {};
|
|
155
|
+
}>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export type WebAuthnCredential = {
|
|
2
|
+
backedUp?: boolean;
|
|
3
|
+
counter: number;
|
|
4
|
+
createdAt: number;
|
|
5
|
+
credentialId: string;
|
|
6
|
+
deviceType?: string;
|
|
7
|
+
lastUsedAt?: number;
|
|
8
|
+
publicKey: string;
|
|
9
|
+
transports?: string[];
|
|
10
|
+
userId: string;
|
|
11
|
+
};
|
|
12
|
+
export type WebAuthnCredentialStore = {
|
|
13
|
+
getCredential: (credentialId: string) => Promise<WebAuthnCredential | undefined>;
|
|
14
|
+
listCredentialsByUser: (userId: string) => Promise<WebAuthnCredential[]>;
|
|
15
|
+
removeCredential: (credentialId: string) => Promise<void>;
|
|
16
|
+
saveCredential: (credential: WebAuthnCredential) => Promise<void>;
|
|
17
|
+
};
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.26.0-beta.
|
|
2
|
+
"version": "0.26.0-beta.3",
|
|
3
3
|
"name": "@absolutejs/auth",
|
|
4
4
|
"description": "An authorization library for absolutejs",
|
|
5
5
|
"repository": {
|
|
@@ -30,8 +30,8 @@
|
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@absolutejs/linked-providers": "0.0.2",
|
|
33
|
-
"citra": "0.25.11",
|
|
34
33
|
"@neondatabase/serverless": "1.0.0",
|
|
34
|
+
"citra": "^0.28.0",
|
|
35
35
|
"drizzle-orm": "0.41.0"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|