@absolutejs/auth 0.25.1 → 0.26.0-beta.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/audit/config.d.ts +8 -0
- package/dist/audit/inMemoryAuditStore.d.ts +2 -0
- package/dist/audit/postgresAuditStore.d.ts +142 -0
- package/dist/audit/types.d.ts +18 -0
- package/dist/audit/wrap.d.ts +9 -0
- package/dist/credentials/config.d.ts +61 -0
- package/dist/credentials/emailVerification.d.ts +83 -0
- package/dist/credentials/inMemoryCredentialStore.d.ts +2 -0
- package/dist/credentials/login.d.ts +75 -0
- package/dist/credentials/passwordPolicy.d.ts +14 -0
- package/dist/credentials/passwordReset.d.ts +87 -0
- package/dist/credentials/postgresCredentialStore.d.ts +279 -0
- package/dist/credentials/register.d.ts +54 -0
- package/dist/credentials/routes.d.ts +200 -0
- package/dist/credentials/types.d.ts +26 -0
- package/dist/crypto.d.ts +32 -0
- package/dist/{ui → htmx}/index.js +2 -2
- package/dist/{ui → htmx}/index.js.map +2 -2
- package/dist/{htmxRoutes.d.ts → htmx/routes.d.ts} +4 -4
- package/dist/index.d.ts +427 -27
- package/dist/index.js +3314 -1932
- package/dist/index.js.map +60 -27
- package/dist/{neonLinkedProviders.d.ts → linkedProviders/neonStores.d.ts} +619 -613
- package/dist/{oauthLinkedProviderResolver.d.ts → linkedProviders/oauthResolver.d.ts} +1 -1
- package/dist/lockout/config.d.ts +17 -0
- package/dist/lockout/inMemoryLockoutStore.d.ts +2 -0
- package/dist/lockout/postgresLockoutStore.d.ts +81 -0
- package/dist/lockout/types.d.ts +12 -0
- package/dist/mfa/backupCodes.d.ts +5 -0
- package/dist/mfa/challenge.d.ts +65 -0
- package/dist/mfa/config.d.ts +32 -0
- package/dist/mfa/gate.d.ts +2 -0
- package/dist/mfa/inMemoryMfaStore.d.ts +2 -0
- package/dist/mfa/postgresMfaStore.d.ts +134 -0
- package/dist/mfa/routes.d.ts +117 -0
- package/dist/mfa/secret.d.ts +2 -0
- package/dist/mfa/totp.d.ts +91 -0
- package/dist/mfa/types.d.ts +16 -0
- package/dist/{providerClients.d.ts → providers/clients.d.ts} +35 -19
- package/dist/{authorize.d.ts → routes/authorize.d.ts} +5 -5
- package/dist/{callback.d.ts → routes/callback.d.ts} +4 -4
- package/dist/{profile.d.ts → routes/profile.d.ts} +5 -5
- package/dist/{protectRoute.d.ts → routes/protectRoute.d.ts} +5 -5
- package/dist/{refresh.d.ts → routes/refresh.d.ts} +5 -5
- package/dist/{revoke.d.ts → routes/revoke.d.ts} +6 -6
- package/dist/routes/sessions.d.ts +103 -0
- package/dist/{signout.d.ts → routes/signout.d.ts} +4 -4
- package/dist/routes/stepUp.d.ts +48 -0
- package/dist/{userStatus.d.ts → routes/userStatus.d.ts} +4 -4
- package/dist/{sessionAccess.d.ts → session/access.d.ts} +12 -12
- package/dist/{sessionCleanup.d.ts → session/cleanup.d.ts} +2 -2
- package/dist/{authSessionStores.d.ts → session/inMemoryStore.d.ts} +2 -2
- package/dist/{neonAuthSessionStore.d.ts → session/neonStore.d.ts} +209 -175
- package/dist/session/promote.d.ts +13 -0
- package/dist/session/sessionsConfig.d.ts +9 -0
- package/dist/{sessionStore.d.ts → session/state.d.ts} +1 -1
- package/dist/{sessionTypes.d.ts → session/types.d.ts} +1 -1
- package/dist/session/userSessions.d.ts +16 -0
- package/dist/stores/postgres.d.ts +5 -0
- package/dist/tenancy.d.ts +9 -0
- package/dist/typeGuards.d.ts +2 -2
- package/dist/typebox.d.ts +3 -3
- package/dist/types.d.ts +33 -3
- package/dist/utils.d.ts +9 -9
- package/package.json +19 -16
- /package/dist/{ui → htmx}/index.d.ts +0 -0
- /package/dist/{ui → htmx}/renderers.d.ts +0 -0
- /package/dist/{ui → htmx}/types.d.ts +0 -0
- /package/dist/{linkedProviderStores.d.ts → linkedProviders/inMemoryStores.d.ts} +0 -0
- /package/dist/{linkedProviderResolver.d.ts → linkedProviders/resolver.d.ts} +0 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { SessionData, UserSessionId } from '../types';
|
|
2
|
+
import type { AuthSessionStore } from './types';
|
|
3
|
+
export type UserSession<UserType> = {
|
|
4
|
+
id: UserSessionId;
|
|
5
|
+
session: SessionData<UserType>;
|
|
6
|
+
};
|
|
7
|
+
type ListUserSessionsProps<UserType> = {
|
|
8
|
+
authSessionStore: AuthSessionStore<UserType>;
|
|
9
|
+
getUserId: (user: UserType) => string;
|
|
10
|
+
userId: string;
|
|
11
|
+
};
|
|
12
|
+
export declare const listUserSessions: <UserType>({ authSessionStore, getUserId, userId }: ListUserSessionsProps<UserType>) => Promise<UserSession<UserType>[]>;
|
|
13
|
+
export declare const revokeUserSessions: <UserType>({ authSessionStore, exceptSessionId, getUserId, userId }: ListUserSessionsProps<UserType> & {
|
|
14
|
+
exceptSessionId?: UserSessionId;
|
|
15
|
+
}) => Promise<number>;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { PgDatabase, PgQueryResultHKT } from 'drizzle-orm/pg-core';
|
|
2
|
+
export type AnyPgDatabase = PgDatabase<PgQueryResultHKT>;
|
|
3
|
+
export declare const createNeonDatabase: (databaseUrl: string) => import("drizzle-orm/neon-http").NeonHttpDatabase<Record<string, never>> & {
|
|
4
|
+
$client: import("@neondatabase/serverless").NeonQueryFunction<false, false>;
|
|
5
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export type OrganizationId = string;
|
|
2
|
+
export type WithOrganization<Resource> = Resource & {
|
|
3
|
+
organizationId?: OrganizationId;
|
|
4
|
+
};
|
|
5
|
+
export declare const hasOrganizationScope: (value: {
|
|
6
|
+
organizationId?: OrganizationId;
|
|
7
|
+
}) => value is {
|
|
8
|
+
organizationId: OrganizationId;
|
|
9
|
+
};
|
package/dist/typeGuards.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AuthIntent, StatusReturn, UserSessionId } from './types';
|
|
2
2
|
export declare const isValidUser: <UserType>(user: unknown) => user is UserType;
|
|
3
|
-
export declare const
|
|
3
|
+
export declare const isAuthIntent: (value: unknown) => value is AuthIntent;
|
|
4
4
|
export declare const isNonEmptyString: (str: string | null | undefined) => str is string;
|
|
5
5
|
export declare const isStatusResponse: (value: unknown) => value is StatusReturn;
|
|
6
|
-
export declare const
|
|
6
|
+
export declare const isUserSessionId: (key: string) => key is UserSessionId;
|
package/dist/typebox.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export declare const
|
|
1
|
+
export declare const authClientOption: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
2
|
+
export declare const authIntentOption: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"login">, import("@sinclair/typebox").TLiteral<"link_identity">, import("@sinclair/typebox").TLiteral<"link_connector">]>>;
|
|
2
3
|
export declare const authProviderOption: import("@sinclair/typebox").TEnum<{
|
|
3
4
|
[k: string]: "42" | "amazoncognito" | "anilist" | "apple" | "atlassian" | "auth0" | "authentik" | "autodesk" | "battlenet" | "bitbucket" | "box" | "bungie" | "coinbase" | "discord" | "donationalerts" | "dribbble" | "dropbox" | "epicgames" | "etsy" | "facebook" | "figma" | "gitea" | "github" | "gitlab" | "google" | "intuit" | "kakao" | "keycloak" | "kick" | "lichess" | "line" | "linear" | "linkedin" | "mastodon" | "mercadolibre" | "mercadopago" | "microsoftentraid" | "myanimelist" | "naver" | "notion" | "okta" | "osu" | "patreon" | "polar" | "polaraccesslink" | "polarteampro" | "reddit" | "roblox" | "salesforce" | "shikimori" | "slack" | "spotify" | "startgg" | "strava" | "synology" | "tiktok" | "tiltify" | "tumblr" | "twitch" | "twitter" | "vk" | "withings" | "workos" | "yahoo" | "yandex" | "zoom";
|
|
4
5
|
}>;
|
|
5
|
-
export declare const
|
|
6
|
-
export declare const authIntentOption: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"login">, import("@sinclair/typebox").TLiteral<"link_identity">, import("@sinclair/typebox").TLiteral<"link_connector">]>>;
|
|
6
|
+
export declare const userSessionIdTypebox: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TTemplateLiteralSyntax<"${string}-${string}-${string}-${string}-${string}">>;
|
package/dist/types.d.ts
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import { CredentialsFor, NonEmptyArray, OAuth2Client, OAuth2TokenResponse, ProviderOption, ProvidersMap } from 'citra';
|
|
2
2
|
import { Cookie, status as statusType, redirect as redirectType } from 'elysia';
|
|
3
3
|
import { ElysiaCustomStatusResponse } from 'elysia/error';
|
|
4
|
+
import type { AuditConfig } from './audit/config';
|
|
5
|
+
import type { CredentialsConfig } from './credentials/config';
|
|
4
6
|
import type { AuthIdentityConflict } from './errors';
|
|
5
|
-
import type {
|
|
6
|
-
import type {
|
|
7
|
+
import type { AuthHtmxConfig, AuthHtmxUser } from './htmx/types';
|
|
8
|
+
import type { LockoutConfig } from './lockout/config';
|
|
9
|
+
import type { MfaConfig } from './mfa/config';
|
|
10
|
+
import type { SessionsConfig } from './session/sessionsConfig';
|
|
11
|
+
import type { AuthSessionStore } from './session/types';
|
|
7
12
|
export type AuthIntent = 'login' | 'link_identity' | 'link_connector';
|
|
8
13
|
export type OAuth2ProviderClientConfiguration<Provider extends ProviderOption> = {
|
|
9
14
|
credentials: CredentialsFor<Provider>;
|
|
@@ -20,9 +25,15 @@ export type OAuth2ConfigurationOptions = {
|
|
|
20
25
|
export type UserSessionId = `${string}-${string}-${string}-${string}-${string}`;
|
|
21
26
|
export type SessionData<UserType> = {
|
|
22
27
|
user: UserType;
|
|
23
|
-
|
|
28
|
+
/** OAuth provider access token. Optional: credential / SSO sessions are not backed
|
|
29
|
+
* by a provider token, so they omit it. Only the OAuth routes (profile, refresh,
|
|
30
|
+
* revoke) read it, and they are all gated on an `auth_provider`. */
|
|
31
|
+
accessToken?: string;
|
|
24
32
|
refreshToken?: string;
|
|
25
33
|
expiresAt: number;
|
|
34
|
+
/** When the session was last established by an actual authentication (login, OAuth
|
|
35
|
+
* callback, or MFA challenge — NOT a token refresh). Drives step-up `requireRecentAuth`. */
|
|
36
|
+
authenticatedAt?: number;
|
|
26
37
|
};
|
|
27
38
|
export type SessionRecord<UserType> = Record<UserSessionId, SessionData<UserType>>;
|
|
28
39
|
export type UnregisteredSessionData = {
|
|
@@ -151,6 +162,25 @@ export type AuthConfig<UserType> = {
|
|
|
151
162
|
maxSessions?: number;
|
|
152
163
|
sessionDurationMs?: number;
|
|
153
164
|
authSessionStore?: AuthSessionStore<UserType>;
|
|
165
|
+
/** Append-only audit logging. When present, `auth()` emits structured events
|
|
166
|
+
* (register, login, mfa_*, password_reset, logout, …) from every flow into the
|
|
167
|
+
* `auditStore` and/or `onAuditEvent` hook. SOC 2 prerequisite. */
|
|
168
|
+
audit?: AuditConfig<UserType>;
|
|
169
|
+
/** Local email/password (credentials) block. Additive and optional — when present,
|
|
170
|
+
* mounts register / verify-email / login / reset-password routes that produce the
|
|
171
|
+
* same `SessionData<UserType>` as OAuth, transparent to `protectRoute`. */
|
|
172
|
+
credentials?: CredentialsConfig<UserType>;
|
|
173
|
+
/** Multi-factor auth (TOTP + backup codes). When present alongside `credentials`,
|
|
174
|
+
* `auth()` auto-wires the login MFA gate, mounts the enroll/challenge routes, and
|
|
175
|
+
* promotes the parked session once a factor is verified. */
|
|
176
|
+
mfa?: MfaConfig<UserType>;
|
|
177
|
+
/** Per-identity attempt throttling + account lockout on the credential login route
|
|
178
|
+
* (progressive: locks after `maxAttempts` failures within `windowMs`). */
|
|
179
|
+
lockout?: LockoutConfig;
|
|
180
|
+
/** Self-service session management: `GET /auth/sessions` (list the caller's active
|
|
181
|
+
* sessions) and `DELETE /auth/sessions/:id` (remote revoke). Requires an
|
|
182
|
+
* `authSessionStore` that can enumerate sessions. */
|
|
183
|
+
sessions?: SessionsConfig<UserType>;
|
|
154
184
|
/** Enable the built-in HTMX fragment routes (login, identities, connectors,
|
|
155
185
|
* account, signout, delete-account). Supply provider display data + the
|
|
156
186
|
* identity/connector data actions; the package owns the route wiring and
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,15 +1,7 @@
|
|
|
1
1
|
import { OAuth2Client, OAuth2TokenResponse, ProviderOption } from 'citra';
|
|
2
2
|
import { Cookie } from 'elysia';
|
|
3
|
+
import { AuthHtmxConfig } from './htmx/types';
|
|
3
4
|
import { AuthConfig, InsantiateUserSessionProps, OAuth2ConfigurationOptions, ResolvedOAuthAuthorization, SessionRecord, UnregisteredSessionRecord, UserSessionId } from './types';
|
|
4
|
-
import { AuthHtmxConfig } from './ui/types';
|
|
5
|
-
export declare const resolveOAuthTokenExpiresAt: (tokenResponse: OAuth2TokenResponse, now?: number) => number | undefined;
|
|
6
|
-
export declare const resolveOAuthAuthorization: ({ authProvider, providerInstance, tokenResponse, now }: {
|
|
7
|
-
authProvider: ProviderOption;
|
|
8
|
-
providerInstance: OAuth2Client<ProviderOption>;
|
|
9
|
-
tokenResponse: OAuth2TokenResponse;
|
|
10
|
-
now?: number;
|
|
11
|
-
}) => Promise<ResolvedOAuthAuthorization>;
|
|
12
|
-
export declare const instantiateUserSession: <UserType>({ authProvider, session, user_session_id, unregisteredSession, tokenResponse, providerInstance, getUser, onNewUser, resolvedAuthorization, sessionDurationMs, unregisteredSessionDurationMs }: InsantiateUserSessionProps<UserType>) => Promise<import("./types").StatusReturn | Response | undefined>;
|
|
13
5
|
export declare const defineAuthConfig: <UserType>(configuration: AuthConfig<UserType>) => AuthConfig<UserType>;
|
|
14
6
|
export declare const defineAuthHtmxConfig: (htmxConfig: AuthHtmxConfig) => AuthHtmxConfig;
|
|
15
7
|
export declare const defineProvidersConfiguration: (providersConfiguration: OAuth2ConfigurationOptions) => OAuth2ConfigurationOptions;
|
|
@@ -23,6 +15,14 @@ export declare const getStatus: <UserType>(session: SessionRecord<UserType>, use
|
|
|
23
15
|
error: null;
|
|
24
16
|
user: NonNullable<UserType> | null;
|
|
25
17
|
}>;
|
|
18
|
+
export declare const instantiateUserSession: <UserType>({ authProvider, session, user_session_id, unregisteredSession, tokenResponse, providerInstance, getUser, onNewUser, resolvedAuthorization, sessionDurationMs, unregisteredSessionDurationMs }: InsantiateUserSessionProps<UserType>) => Promise<Response | import("./types").StatusReturn | undefined>;
|
|
19
|
+
export declare const resolveOAuthAuthorization: ({ authProvider, providerInstance, tokenResponse, now }: {
|
|
20
|
+
authProvider: ProviderOption;
|
|
21
|
+
providerInstance: OAuth2Client<ProviderOption>;
|
|
22
|
+
tokenResponse: OAuth2TokenResponse;
|
|
23
|
+
now?: number;
|
|
24
|
+
}) => Promise<ResolvedOAuthAuthorization>;
|
|
25
|
+
export declare const resolveOAuthTokenExpiresAt: (tokenResponse: OAuth2TokenResponse, now?: number) => number | undefined;
|
|
26
26
|
type ValidateSessionProps<SessionType extends Record<string, unknown> & {
|
|
27
27
|
expiresAt: number;
|
|
28
28
|
}> = {
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.
|
|
2
|
+
"version": "0.26.0-beta.0",
|
|
3
3
|
"name": "@absolutejs/auth",
|
|
4
4
|
"description": "An authorization library for absolutejs",
|
|
5
5
|
"repository": {
|
|
@@ -10,11 +10,11 @@
|
|
|
10
10
|
"license": "CC BY-NC 4.0",
|
|
11
11
|
"author": "Alex Kahn",
|
|
12
12
|
"scripts": {
|
|
13
|
-
"build": "rm -rf dist && bun build src/index.ts src/
|
|
14
|
-
"test": "
|
|
15
|
-
"format": "prettier --write
|
|
16
|
-
"lint": "
|
|
17
|
-
"typecheck": "
|
|
13
|
+
"build": "rm -rf dist && bun build src/index.ts src/htmx/index.ts --outdir dist --sourcemap --target=bun --external elysia && tsc --emitDeclarationOnly --project tsconfig.json",
|
|
14
|
+
"test": "bun test",
|
|
15
|
+
"format": "absolute prettier --write",
|
|
16
|
+
"lint": "absolute eslint",
|
|
17
|
+
"typecheck": "absolute typecheck",
|
|
18
18
|
"release": "bun run format && bun run build && bun publish"
|
|
19
19
|
},
|
|
20
20
|
"keywords": [
|
|
@@ -35,17 +35,20 @@
|
|
|
35
35
|
"drizzle-orm": "0.41.0"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
|
-
"@
|
|
38
|
+
"@absolutejs/absolute": "^0.19.0-beta.1023",
|
|
39
|
+
"@eslint/js": "^10.0.1",
|
|
40
|
+
"@stylistic/eslint-plugin": "^5.10.0",
|
|
39
41
|
"@types/bun": "1.2.9",
|
|
42
|
+
"@typescript-eslint/parser": "^8.57.2",
|
|
40
43
|
"elysia": "1.4.26",
|
|
41
|
-
"eslint": "
|
|
42
|
-
"eslint-plugin-absolute": "0.0
|
|
43
|
-
"eslint-plugin-
|
|
44
|
-
"eslint-plugin-
|
|
45
|
-
"
|
|
44
|
+
"eslint": "^10.1.0",
|
|
45
|
+
"eslint-plugin-absolute": "^0.11.0",
|
|
46
|
+
"eslint-plugin-promise": "^7.2.1",
|
|
47
|
+
"eslint-plugin-security": "^4.0.0",
|
|
48
|
+
"globals": "^17.4.0",
|
|
46
49
|
"prettier": "3.5.3",
|
|
47
50
|
"typescript": "5.8.3",
|
|
48
|
-
"typescript-eslint": "8.
|
|
51
|
+
"typescript-eslint": "^8.57.2"
|
|
49
52
|
},
|
|
50
53
|
"module": "./dist/index.js",
|
|
51
54
|
"exports": {
|
|
@@ -53,9 +56,9 @@
|
|
|
53
56
|
"import": "./dist/index.js",
|
|
54
57
|
"types": "./dist/index.d.ts"
|
|
55
58
|
},
|
|
56
|
-
"./
|
|
57
|
-
"import": "./dist/
|
|
58
|
-
"types": "./dist/
|
|
59
|
+
"./htmx": {
|
|
60
|
+
"import": "./dist/htmx/index.js",
|
|
61
|
+
"types": "./dist/htmx/index.d.ts"
|
|
59
62
|
}
|
|
60
63
|
},
|
|
61
64
|
"type": "module",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|