@holeauth/core 0.0.1-alpha.0 → 0.0.2-alpha.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/LICENSE +1 -1
- package/dist/cookies/index.d.ts +2 -2
- package/dist/events/index.d.ts +2 -2
- package/dist/flows/index.d.ts +3 -3
- package/dist/{index-BIXESLma.d.ts → index-BELADTaD.d.ts} +1 -1
- package/dist/{index-BmYQquGs.d.ts → index-Bt3CyLaq.d.ts} +30 -11
- package/dist/{index-CotvcK_b.d.ts → index-BydOBZfs.d.ts} +2 -2
- package/dist/{index-BbEXbI_k.d.ts → index-C3lSoShz.d.ts} +2 -2
- package/dist/{index-CHS-socJ.d.ts → index-CcMMWIEe.d.ts} +67 -3
- package/dist/{index-DRN-5E_H.d.ts → index-CngIcZZk.d.ts} +3 -2
- package/dist/{index-D57PvFMN.d.ts → index-D0r6eY4L.d.ts} +45 -3
- package/dist/index.d.ts +9 -9
- package/dist/index.js +161 -52
- package/dist/index.js.map +1 -1
- package/dist/plugins/index.d.ts +3 -3
- package/dist/{registry-CZhM1tEB.d.ts → registry-B-I45f0J.d.ts} +1 -1
- package/dist/session/index.d.ts +2 -2
- package/dist/session/index.js +89 -1
- package/dist/session/index.js.map +1 -1
- package/dist/sso/index.d.ts +2 -2
- package/dist/sso/index.js +64 -1
- package/dist/sso/index.js.map +1 -1
- package/package.json +1 -1
package/LICENSE
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2026 Robert Kratz
|
|
3
|
+
Copyright (c) 2026 Robert Julian Kratz <contact@holeauth.dev> (https://holeauth.dev)
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
package/dist/cookies/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { B as BuildCookieInput, C as CSRF_HEADER, a as CookieName, b as CookieSpec, c as buildCookie, d as cookieName, e as deleteCookie, g as generateCsrfToken, f as isProduction, s as serializeCookie, v as verifyCsrf } from '../index-
|
|
2
|
-
import '../index-
|
|
1
|
+
export { B as BuildCookieInput, C as CSRF_HEADER, a as CookieName, b as CookieSpec, c as buildCookie, d as cookieName, e as deleteCookie, g as generateCsrfToken, f as isProduction, s as serializeCookie, v as verifyCsrf } from '../index-BELADTaD.js';
|
|
2
|
+
import '../index-Bt3CyLaq.js';
|
|
3
3
|
import '../index-CNtnPdzk.js';
|
package/dist/events/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { u as HoleauthEvent,
|
|
2
|
-
export { e as emit, s as subscribe, u as unsubscribe } from '../index-
|
|
1
|
+
export { v as CoreHoleauthEventType, u as HoleauthEvent, w as HoleauthEventType } from '../index-Bt3CyLaq.js';
|
|
2
|
+
export { e as emit, s as subscribe, u as unsubscribe } from '../index-CngIcZZk.js';
|
|
3
3
|
import '../index-CNtnPdzk.js';
|
package/dist/flows/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { c as changePassword, a as consumeInvite, b as consumePasswordReset, d as createInvite, e as deleteUser, g as getInviteInfo, f as issuePendingToken, l as listInvites, r as refresh, h as register, j as requestPasswordReset, k as revokeInvite, s as signIn, m as signOut, u as updateUser, v as verifyPendingToken } from '../index-
|
|
2
|
-
import '../index-
|
|
1
|
+
export { c as changePassword, a as consumeInvite, b as consumePasswordReset, d as createInvite, e as deleteUser, g as getInviteInfo, f as issuePendingToken, l as listInvites, r as refresh, h as register, j as requestPasswordReset, k as revokeInvite, s as signIn, m as signOut, u as updateUser, v as verifyPendingToken } from '../index-C3lSoShz.js';
|
|
2
|
+
import '../index-Bt3CyLaq.js';
|
|
3
3
|
import '../index-CNtnPdzk.js';
|
|
4
|
-
import '../registry-
|
|
4
|
+
import '../registry-B-I45f0J.js';
|
|
@@ -1,18 +1,21 @@
|
|
|
1
1
|
import { a as AdapterAuditEvent, A as AdapterUser, U as UserAdapter, S as SessionAdapter, b as AuditLogAdapter, c as AccountAdapter, V as VerificationTokenAdapter, T as TransactionAdapter } from './index-CNtnPdzk.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
* `user.*`, `session.*`, `account.*`, `sso.*` events; plugins emit under
|
|
6
|
-
* their own `<pluginId>.<name>` namespace (e.g. `twofa.verified`).
|
|
4
|
+
* Well-known event types emitted by @holeauth/core.
|
|
7
5
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* - plugin.error
|
|
6
|
+
* IDEs will autocomplete these names when calling `subscribe()` or
|
|
7
|
+
* `auth.on()`. The type is intentionally open-ended: plugins emit
|
|
8
|
+
* additional events under their own `<pluginId>.<name>` namespace
|
|
9
|
+
* (e.g. `twofa.verified`, `rbac.group_assigned`). Those names are
|
|
10
|
+
* accepted via the `(string & {})` escape hatch.
|
|
14
11
|
*/
|
|
15
|
-
type
|
|
12
|
+
type CoreHoleauthEventType = 'user.registered' | 'user.signed_in' | 'user.signed_out' | 'user.updated' | 'user.deleted' | 'session.created' | 'session.rotated' | 'session.revoked' | 'session.reuse_detected' | 'password.changed' | 'password.reset_requested' | 'password.reset_consumed' | 'account.linked' | 'account.unlinked' | 'sso.authorize' | 'sso.callback_ok' | 'sso.callback_failed' | 'invite.created' | 'user.invite_consumed' | 'invite.revoked' | 'plugin.error';
|
|
13
|
+
/**
|
|
14
|
+
* The discriminant of all holeauth events. Extends `CoreHoleauthEventType`
|
|
15
|
+
* with an open-string escape hatch so plugin-namespaced events still type-
|
|
16
|
+
* check, while preserving IDE autocomplete for the well-known names.
|
|
17
|
+
*/
|
|
18
|
+
type HoleauthEventType = CoreHoleauthEventType | (string & {});
|
|
16
19
|
interface HoleauthEvent extends AdapterAuditEvent {
|
|
17
20
|
type: HoleauthEventType;
|
|
18
21
|
}
|
|
@@ -558,6 +561,22 @@ interface HoleauthInstance {
|
|
|
558
561
|
tokens: IssuedTokens;
|
|
559
562
|
}>;
|
|
560
563
|
};
|
|
564
|
+
/**
|
|
565
|
+
* Subscribe to an event emitted by this auth instance.
|
|
566
|
+
* Shorthand for `import { events } from '@holeauth/core'; events.subscribe(auth.config, type, handler)`.
|
|
567
|
+
*
|
|
568
|
+
* @param type - Well-known event type (autocompleted) or any plugin-namespaced string.
|
|
569
|
+
* @param handler - Async-safe handler; errors are swallowed to avoid blocking flows.
|
|
570
|
+
* @returns An unsubscribe function.
|
|
571
|
+
*
|
|
572
|
+
* @example
|
|
573
|
+
* ```ts
|
|
574
|
+
* auth.on('user.registered', async (e) => {
|
|
575
|
+
* await assignDefaultGroup(e.userId);
|
|
576
|
+
* });
|
|
577
|
+
* ```
|
|
578
|
+
*/
|
|
579
|
+
on(type: HoleauthEventType, handler: (e: HoleauthEvent) => void | Promise<void>): () => void;
|
|
561
580
|
}
|
|
562
581
|
|
|
563
|
-
export type {
|
|
582
|
+
export type { SessionIssueHookData as A, BaseProviderConfig as B, ChallengeResult as C, SessionRevokeHookData as D, SessionRotateHookData as E, HoleauthPlugin as H, InviteClaims as I, LoggerOptions as L, OAuth2ProviderConfig as O, PluginsApi as P, RegistrationConfig as R, SessionData as S, TokenPolicy as T, HoleauthConfig as a, HoleauthInstance as b, ConsumeInviteInput as c, ConsumeInviteResult as d, CreateInviteResult as e, HoleauthAdapters as f, HoleauthHooks as g, HoleauthSecrets as h, InviteInput as i, InviteListEntry as j, IssuedTokens as k, OIDCProviderConfig as l, PluginContext as m, PluginCoreSurface as n, PluginEvents as o, PluginLogger as p, PluginRoute as q, PluginRouteContext as r, ProviderConfig as s, SignInResult as t, HoleauthEvent as u, CoreHoleauthEventType as v, HoleauthEventType as w, PasswordChangeHookInput as x, PasswordResetHookInput as y, RegisterHookInput as z };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { H as HoleauthPlugin, C as ChallengeResult, g as HoleauthHooks,
|
|
2
|
-
import { H as HookRunner, P as PluginRegistry, b as buildRegistry, e as emptyRegistry, r as runOnInit } from './registry-
|
|
1
|
+
import { H as HoleauthPlugin, C as ChallengeResult, g as HoleauthHooks, x as PasswordChangeHookInput, y as PasswordResetHookInput, m as PluginContext, n as PluginCoreSurface, o as PluginEvents, p as PluginLogger, q as PluginRoute, r as PluginRouteContext, P as PluginsApi, z as RegisterHookInput, A as SessionIssueHookData, D as SessionRevokeHookData, E as SessionRotateHookData } from './index-Bt3CyLaq.js';
|
|
2
|
+
import { H as HookRunner, P as PluginRegistry, b as buildRegistry, e as emptyRegistry, r as runOnInit } from './registry-B-I45f0J.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Identity helper that preserves the literal `id` on the plugin type so
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { a as HoleauthConfig, t as SignInResult, k as IssuedTokens, c as ConsumeInviteInput, d as ConsumeInviteResult, i as InviteInput, e as CreateInviteResult, I as InviteClaims, j as InviteListEntry } from './index-
|
|
1
|
+
import { a as HoleauthConfig, t as SignInResult, k as IssuedTokens, c as ConsumeInviteInput, d as ConsumeInviteResult, i as InviteInput, e as CreateInviteResult, I as InviteClaims, j as InviteListEntry } from './index-Bt3CyLaq.js';
|
|
2
2
|
import { A as AdapterUser } from './index-CNtnPdzk.js';
|
|
3
|
-
import { H as HookRunner } from './registry-
|
|
3
|
+
import { H as HookRunner } from './registry-B-I45f0J.js';
|
|
4
4
|
|
|
5
5
|
interface RegisterInput {
|
|
6
6
|
email: string;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as HoleauthConfig, s as ProviderConfig, k as IssuedTokens, l as OIDCProviderConfig, O as OAuth2ProviderConfig } from './index-
|
|
1
|
+
import { a as HoleauthConfig, s as ProviderConfig, k as IssuedTokens, l as OIDCProviderConfig, O as OAuth2ProviderConfig } from './index-Bt3CyLaq.js';
|
|
2
2
|
import { A as AdapterUser } from './index-CNtnPdzk.js';
|
|
3
3
|
|
|
4
4
|
interface AuthorizeParams {
|
|
@@ -76,9 +76,73 @@ interface GithubOptions {
|
|
|
76
76
|
/** GitHub OAuth2 provider. Uses REST userinfo (no OIDC). */
|
|
77
77
|
declare function GithubProvider(opts: GithubOptions): OAuth2ProviderConfig;
|
|
78
78
|
|
|
79
|
+
interface DiscordOptions {
|
|
80
|
+
clientId: string;
|
|
81
|
+
clientSecret: string;
|
|
82
|
+
redirectUri: string;
|
|
83
|
+
id?: string;
|
|
84
|
+
scopes?: string[];
|
|
85
|
+
}
|
|
86
|
+
/** Discord OAuth2 provider. Uses REST userinfo (no OIDC discovery). */
|
|
87
|
+
declare function DiscordProvider(opts: DiscordOptions): OAuth2ProviderConfig;
|
|
88
|
+
|
|
89
|
+
interface MicrosoftOptions {
|
|
90
|
+
clientId: string;
|
|
91
|
+
clientSecret: string;
|
|
92
|
+
redirectUri: string;
|
|
93
|
+
/**
|
|
94
|
+
* Microsoft tenant. Common values:
|
|
95
|
+
* - 'common' → both work + school and personal accounts
|
|
96
|
+
* - 'organizations' → work + school only
|
|
97
|
+
* - 'consumers' → personal Microsoft accounts only
|
|
98
|
+
* - '<tenant-guid>' → a specific Azure AD tenant
|
|
99
|
+
*
|
|
100
|
+
* Default: 'common'.
|
|
101
|
+
*/
|
|
102
|
+
tenantId?: string;
|
|
103
|
+
id?: string;
|
|
104
|
+
scopes?: string[];
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Microsoft Identity Platform (Azure AD / Entra ID) OpenID Connect provider.
|
|
108
|
+
*
|
|
109
|
+
* Note: the issuer for tenant 'common' is technically per-tenant at runtime
|
|
110
|
+
* (`https://login.microsoftonline.com/{tid}/v2.0`). We expose the multi-tenant
|
|
111
|
+
* issuer string; callers that need strict issuer validation should pin a
|
|
112
|
+
* specific tenant ID.
|
|
113
|
+
*/
|
|
114
|
+
declare function MicrosoftProvider(opts: MicrosoftOptions): OIDCProviderConfig;
|
|
115
|
+
|
|
116
|
+
interface OIDCOptions {
|
|
117
|
+
/** Provider id (used as the `:provider` URL segment). */
|
|
118
|
+
id: string;
|
|
119
|
+
/** Display name. */
|
|
120
|
+
name?: string;
|
|
121
|
+
clientId: string;
|
|
122
|
+
clientSecret: string;
|
|
123
|
+
redirectUri: string;
|
|
124
|
+
/** OIDC issuer (used for ID token `iss` validation). */
|
|
125
|
+
issuer: string;
|
|
126
|
+
authorizationUrl: string;
|
|
127
|
+
tokenUrl: string;
|
|
128
|
+
userinfoUrl: string;
|
|
129
|
+
scopes?: string[];
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Generic OpenID Connect provider. Use this for any spec-compliant OIDC
|
|
133
|
+
* Identity Provider (Keycloak, Auth0, Okta, Authentik, holeauth-as-IDP, …).
|
|
134
|
+
*
|
|
135
|
+
* Endpoint discovery is currently the caller's responsibility — fetch
|
|
136
|
+
* `${issuer}/.well-known/openid-configuration` and pass the resulting URLs.
|
|
137
|
+
*/
|
|
138
|
+
declare function OIDCProvider(opts: OIDCOptions): OIDCProviderConfig;
|
|
139
|
+
|
|
79
140
|
type index_AuthorizeParams = AuthorizeParams;
|
|
141
|
+
declare const index_DiscordProvider: typeof DiscordProvider;
|
|
80
142
|
declare const index_GithubProvider: typeof GithubProvider;
|
|
81
143
|
declare const index_GoogleProvider: typeof GoogleProvider;
|
|
144
|
+
declare const index_MicrosoftProvider: typeof MicrosoftProvider;
|
|
145
|
+
declare const index_OIDCProvider: typeof OIDCProvider;
|
|
82
146
|
type index_TokenExchangeInput = TokenExchangeInput;
|
|
83
147
|
declare const index_authorize: typeof authorize;
|
|
84
148
|
declare const index_base64url: typeof base64url;
|
|
@@ -91,7 +155,7 @@ declare const index_generateNonce: typeof generateNonce;
|
|
|
91
155
|
declare const index_generatePkcePair: typeof generatePkcePair;
|
|
92
156
|
declare const index_generateState: typeof generateState;
|
|
93
157
|
declare namespace index {
|
|
94
|
-
export { type index_AuthorizeParams as AuthorizeParams, index_GithubProvider as GithubProvider, index_GoogleProvider as GoogleProvider, type index_TokenExchangeInput as TokenExchangeInput, index_authorize as authorize, index_base64url as base64url, index_buildAuthorizeUrl as buildAuthorizeUrl, index_callback as callback, index_exchangeCode as exchangeCode, index_fetchUserInfo as fetchUserInfo, index_findProvider as findProvider, index_generateNonce as generateNonce, index_generatePkcePair as generatePkcePair, index_generateState as generateState };
|
|
158
|
+
export { type index_AuthorizeParams as AuthorizeParams, index_DiscordProvider as DiscordProvider, index_GithubProvider as GithubProvider, index_GoogleProvider as GoogleProvider, index_MicrosoftProvider as MicrosoftProvider, index_OIDCProvider as OIDCProvider, type index_TokenExchangeInput as TokenExchangeInput, index_authorize as authorize, index_base64url as base64url, index_buildAuthorizeUrl as buildAuthorizeUrl, index_callback as callback, index_exchangeCode as exchangeCode, index_fetchUserInfo as fetchUserInfo, index_findProvider as findProvider, index_generateNonce as generateNonce, index_generatePkcePair as generatePkcePair, index_generateState as generateState };
|
|
95
159
|
}
|
|
96
160
|
|
|
97
|
-
export { type AuthorizeParams as A, GithubProvider as G, type TokenExchangeInput as T, GoogleProvider as a, authorize as b, base64url as c, buildAuthorizeUrl as d, callback as e, exchangeCode as f, fetchUserInfo as g, findProvider as h, index as i, generateNonce as j, generatePkcePair as k, generateState as l };
|
|
161
|
+
export { type AuthorizeParams as A, DiscordProvider as D, GithubProvider as G, MicrosoftProvider as M, OIDCProvider as O, type TokenExchangeInput as T, GoogleProvider as a, authorize as b, base64url as c, buildAuthorizeUrl as d, callback as e, exchangeCode as f, fetchUserInfo as g, findProvider as h, index as i, generateNonce as j, generatePkcePair as k, generateState as l };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as HoleauthConfig, u as HoleauthEvent, v as HoleauthEventType } from './index-
|
|
1
|
+
import { a as HoleauthConfig, u as HoleauthEvent, v as CoreHoleauthEventType, w as HoleauthEventType } from './index-Bt3CyLaq.js';
|
|
2
2
|
|
|
3
3
|
type Handler = (e: HoleauthEvent) => void | Promise<void>;
|
|
4
4
|
/** Subscribe to an event type. Use '*' to match all events. Returns an unsubscribe fn. */
|
|
@@ -14,13 +14,14 @@ declare function unsubscribe(cfg: HoleauthConfig, type: string, handler: Handler
|
|
|
14
14
|
*/
|
|
15
15
|
declare function emit(cfg: HoleauthConfig, event: HoleauthEvent): Promise<void>;
|
|
16
16
|
|
|
17
|
+
declare const index_CoreHoleauthEventType: typeof CoreHoleauthEventType;
|
|
17
18
|
declare const index_HoleauthEvent: typeof HoleauthEvent;
|
|
18
19
|
declare const index_HoleauthEventType: typeof HoleauthEventType;
|
|
19
20
|
declare const index_emit: typeof emit;
|
|
20
21
|
declare const index_subscribe: typeof subscribe;
|
|
21
22
|
declare const index_unsubscribe: typeof unsubscribe;
|
|
22
23
|
declare namespace index {
|
|
23
|
-
export { index_HoleauthEvent as HoleauthEvent, index_HoleauthEventType as HoleauthEventType, index_emit as emit, index_subscribe as subscribe, index_unsubscribe as unsubscribe };
|
|
24
|
+
export { index_CoreHoleauthEventType as CoreHoleauthEventType, index_HoleauthEvent as HoleauthEvent, index_HoleauthEventType as HoleauthEventType, index_emit as emit, index_subscribe as subscribe, index_unsubscribe as unsubscribe };
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
export { emit as e, index as i, subscribe as s, unsubscribe as u };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as HoleauthConfig, k as IssuedTokens, S as SessionData, b as HoleauthInstance } from './index-
|
|
1
|
+
import { a as HoleauthConfig, k as IssuedTokens, S as SessionData, b as HoleauthInstance } from './index-Bt3CyLaq.js';
|
|
2
2
|
|
|
3
3
|
interface IssueInput {
|
|
4
4
|
userId: string;
|
|
@@ -87,10 +87,52 @@ interface GetSessionOrRefreshResult {
|
|
|
87
87
|
*/
|
|
88
88
|
declare function getSessionOrRefresh(instance: HoleauthInstance, input: GetSessionOrRefreshInput): Promise<GetSessionOrRefreshResult>;
|
|
89
89
|
|
|
90
|
+
interface RequestRefreshResult {
|
|
91
|
+
/** Resolved session, or null if both validation and refresh failed. */
|
|
92
|
+
session: SessionData | null;
|
|
93
|
+
/** Freshly-issued token bundle when a refresh occurred; null otherwise. */
|
|
94
|
+
tokens: IssuedTokens | null;
|
|
95
|
+
/** True when the refresh token was rotated. */
|
|
96
|
+
refreshed: boolean;
|
|
97
|
+
/**
|
|
98
|
+
* Ready-to-forward `Set-Cookie` header values. Empty when no rotation
|
|
99
|
+
* occurred. The caller must append these to its outgoing response.
|
|
100
|
+
*/
|
|
101
|
+
setCookieHeaders: string[];
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Read cookies from a Web API `Request`, validate the access token, and
|
|
105
|
+
* transparently rotate the refresh token when needed.
|
|
106
|
+
*
|
|
107
|
+
* **Framework-agnostic** — works wherever the Web Fetch `Request` type is
|
|
108
|
+
* available: Next.js App Router route handlers, Hono, plain `fetch` handlers,
|
|
109
|
+
* tRPC fetch adapters, Cloudflare Workers, Deno, etc.
|
|
110
|
+
*
|
|
111
|
+
* The caller is responsible for forwarding `setCookieHeaders` on the response
|
|
112
|
+
* when the result's `refreshed` flag is `true`.
|
|
113
|
+
*
|
|
114
|
+
* @example tRPC context (fetch adapter)
|
|
115
|
+
* ```ts
|
|
116
|
+
* import { getSessionOrRefreshFromRequest } from '@holeauth/core/session';
|
|
117
|
+
*
|
|
118
|
+
* export const createTrpcContext = createHoleauthContext(auth);
|
|
119
|
+
* // internally calls getSessionOrRefreshFromRequest(req, auth)
|
|
120
|
+
* ```
|
|
121
|
+
*
|
|
122
|
+
* @example Manual use in a route handler
|
|
123
|
+
* ```ts
|
|
124
|
+
* const { session, setCookieHeaders } = await getSessionOrRefreshFromRequest(req, auth);
|
|
125
|
+
* for (const c of setCookieHeaders) resHeaders.append('Set-Cookie', c);
|
|
126
|
+
* ```
|
|
127
|
+
*/
|
|
128
|
+
declare function getSessionOrRefreshFromRequest(req: Request, instance: HoleauthInstance): Promise<RequestRefreshResult>;
|
|
129
|
+
|
|
90
130
|
type index_GetSessionOrRefreshInput = GetSessionOrRefreshInput;
|
|
91
131
|
type index_GetSessionOrRefreshResult = GetSessionOrRefreshResult;
|
|
92
132
|
type index_IssueInput = IssueInput;
|
|
133
|
+
type index_RequestRefreshResult = RequestRefreshResult;
|
|
93
134
|
declare const index_getSessionOrRefresh: typeof getSessionOrRefresh;
|
|
135
|
+
declare const index_getSessionOrRefreshFromRequest: typeof getSessionOrRefreshFromRequest;
|
|
94
136
|
declare const index_issueSession: typeof issueSession;
|
|
95
137
|
declare const index_revokeAllForUser: typeof revokeAllForUser;
|
|
96
138
|
declare const index_revokeByRefresh: typeof revokeByRefresh;
|
|
@@ -99,7 +141,7 @@ declare const index_rotateRefresh: typeof rotateRefresh;
|
|
|
99
141
|
declare const index_sha256b64url: typeof sha256b64url;
|
|
100
142
|
declare const index_validateSession: typeof validateSession;
|
|
101
143
|
declare namespace index {
|
|
102
|
-
export { type index_GetSessionOrRefreshInput as GetSessionOrRefreshInput, type index_GetSessionOrRefreshResult as GetSessionOrRefreshResult, type index_IssueInput as IssueInput, index_getSessionOrRefresh as getSessionOrRefresh, index_issueSession as issueSession, index_revokeAllForUser as revokeAllForUser, index_revokeByRefresh as revokeByRefresh, index_revokeSession as revokeSession, index_rotateRefresh as rotateRefresh, index_sha256b64url as sha256b64url, index_validateSession as validateSession };
|
|
144
|
+
export { type index_GetSessionOrRefreshInput as GetSessionOrRefreshInput, type index_GetSessionOrRefreshResult as GetSessionOrRefreshResult, type index_IssueInput as IssueInput, type index_RequestRefreshResult as RequestRefreshResult, index_getSessionOrRefresh as getSessionOrRefresh, index_getSessionOrRefreshFromRequest as getSessionOrRefreshFromRequest, index_issueSession as issueSession, index_revokeAllForUser as revokeAllForUser, index_revokeByRefresh as revokeByRefresh, index_revokeSession as revokeSession, index_rotateRefresh as rotateRefresh, index_sha256b64url as sha256b64url, index_validateSession as validateSession };
|
|
103
145
|
}
|
|
104
146
|
|
|
105
|
-
export { type GetSessionOrRefreshInput as G, type IssueInput as I, type GetSessionOrRefreshResult as a,
|
|
147
|
+
export { type GetSessionOrRefreshInput as G, type IssueInput as I, type RequestRefreshResult as R, type GetSessionOrRefreshResult as a, getSessionOrRefreshFromRequest as b, issueSession as c, revokeByRefresh as d, revokeSession as e, rotateRefresh as f, getSessionOrRefresh as g, index as i, revokeAllForUser as r, sha256b64url as s, validateSession as v };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import { H as HoleauthPlugin, a as HoleauthConfig, b as HoleauthInstance, P as PluginsApi } from './index-
|
|
2
|
-
export { B as BaseProviderConfig, C as ChallengeResult, c as ConsumeInviteInput, d as ConsumeInviteResult, e as CreateInviteResult, f as HoleauthAdapters, g as HoleauthHooks, h as HoleauthSecrets, I as InviteClaims, i as InviteInput, j as InviteListEntry, k as IssuedTokens, L as LoggerOptions, O as OAuth2ProviderConfig, l as OIDCProviderConfig, m as PluginContext, n as PluginCoreSurface, o as PluginEvents, p as PluginLogger, q as PluginRoute, r as PluginRouteContext, s as ProviderConfig, R as RegistrationConfig, S as SessionData, t as SignInResult, T as TokenPolicy } from './index-
|
|
1
|
+
import { H as HoleauthPlugin, a as HoleauthConfig, b as HoleauthInstance, P as PluginsApi } from './index-Bt3CyLaq.js';
|
|
2
|
+
export { B as BaseProviderConfig, C as ChallengeResult, c as ConsumeInviteInput, d as ConsumeInviteResult, e as CreateInviteResult, f as HoleauthAdapters, g as HoleauthHooks, h as HoleauthSecrets, I as InviteClaims, i as InviteInput, j as InviteListEntry, k as IssuedTokens, L as LoggerOptions, O as OAuth2ProviderConfig, l as OIDCProviderConfig, m as PluginContext, n as PluginCoreSurface, o as PluginEvents, p as PluginLogger, q as PluginRoute, r as PluginRouteContext, s as ProviderConfig, R as RegistrationConfig, S as SessionData, t as SignInResult, T as TokenPolicy } from './index-Bt3CyLaq.js';
|
|
3
3
|
export { AccountConflictError, AdapterError, CredentialsError, CsrfError, HoleauthError, InvalidTokenError, NotSupportedError, PendingChallengeError, ProviderError, RefreshReuseError, RegistrationDisabledError, SessionExpiredError } from './errors/index.js';
|
|
4
4
|
export { i as jwt } from './index-CjEXpqaW.js';
|
|
5
|
-
export { i as session } from './index-
|
|
5
|
+
export { i as session } from './index-D0r6eY4L.js';
|
|
6
6
|
export { i as password } from './index-BYtkmk9_.js';
|
|
7
7
|
export { i as otp } from './index-BwEvEa8-.js';
|
|
8
|
-
export { i as sso } from './index-
|
|
8
|
+
export { i as sso } from './index-CcMMWIEe.js';
|
|
9
9
|
export { i as adapters } from './index-CNtnPdzk.js';
|
|
10
|
-
export { i as cookies } from './index-
|
|
11
|
-
export { i as events } from './index-
|
|
12
|
-
export { i as flows } from './index-
|
|
13
|
-
export { d as definePlugin, i as plugins } from './index-
|
|
14
|
-
import { P as PluginRegistry } from './registry-
|
|
10
|
+
export { i as cookies } from './index-BELADTaD.js';
|
|
11
|
+
export { i as events } from './index-CngIcZZk.js';
|
|
12
|
+
export { i as flows } from './index-C3lSoShz.js';
|
|
13
|
+
export { d as definePlugin, i as plugins } from './index-BydOBZfs.js';
|
|
14
|
+
import { P as PluginRegistry } from './registry-B-I45f0J.js';
|
|
15
15
|
import 'jose';
|
|
16
16
|
|
|
17
17
|
/** Framework-binding helper (not part of the public API surface). */
|
package/dist/index.js
CHANGED
|
@@ -112,6 +112,7 @@ function decode(token) {
|
|
|
112
112
|
var session_exports = {};
|
|
113
113
|
__export(session_exports, {
|
|
114
114
|
getSessionOrRefresh: () => getSessionOrRefresh,
|
|
115
|
+
getSessionOrRefreshFromRequest: () => getSessionOrRefreshFromRequest,
|
|
115
116
|
issueSession: () => issueSession,
|
|
116
117
|
revokeAllForUser: () => revokeAllForUser,
|
|
117
118
|
revokeByRefresh: () => revokeByRefresh,
|
|
@@ -446,6 +447,97 @@ async function getSessionOrRefresh(instance, input) {
|
|
|
446
447
|
return { session, tokens, refreshed: true };
|
|
447
448
|
}
|
|
448
449
|
|
|
450
|
+
// src/cookies/spec.ts
|
|
451
|
+
function cookieName(cfg, kind) {
|
|
452
|
+
const prefix = cfg.tokens?.cookiePrefix ?? "holeauth";
|
|
453
|
+
switch (kind) {
|
|
454
|
+
case "access":
|
|
455
|
+
return `${prefix}.at`;
|
|
456
|
+
case "refresh":
|
|
457
|
+
return `${prefix}.rt`;
|
|
458
|
+
case "csrf":
|
|
459
|
+
return `${prefix}.csrf`;
|
|
460
|
+
case "pending":
|
|
461
|
+
return `${prefix}.pending`;
|
|
462
|
+
case "oauthState":
|
|
463
|
+
return `${prefix}.oauth.state`;
|
|
464
|
+
case "oauthPkce":
|
|
465
|
+
return `${prefix}.oauth.pkce`;
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
function isProduction() {
|
|
469
|
+
return globalThis.process?.env?.NODE_ENV === "production";
|
|
470
|
+
}
|
|
471
|
+
function buildCookie(cfg, input) {
|
|
472
|
+
const httpOnly = input.httpOnly ?? input.kind !== "csrf";
|
|
473
|
+
const secure = cfg.tokens?.cookieSecure ?? isProduction();
|
|
474
|
+
return {
|
|
475
|
+
name: cookieName(cfg, input.kind),
|
|
476
|
+
value: input.value,
|
|
477
|
+
maxAge: input.maxAge,
|
|
478
|
+
httpOnly,
|
|
479
|
+
secure,
|
|
480
|
+
sameSite: input.sameSite ?? cfg.tokens?.sameSite ?? "lax",
|
|
481
|
+
path: input.path ?? "/",
|
|
482
|
+
domain: cfg.tokens?.cookieDomain
|
|
483
|
+
};
|
|
484
|
+
}
|
|
485
|
+
function serializeCookie(c) {
|
|
486
|
+
const parts = [`${c.name}=${encodeURIComponent(c.value)}`];
|
|
487
|
+
parts.push(`Path=${c.path}`);
|
|
488
|
+
if (c.domain) parts.push(`Domain=${c.domain}`);
|
|
489
|
+
if (c.maxAge !== void 0) {
|
|
490
|
+
parts.push(`Max-Age=${c.maxAge}`);
|
|
491
|
+
if (c.maxAge === 0) parts.push("Expires=Thu, 01 Jan 1970 00:00:00 GMT");
|
|
492
|
+
}
|
|
493
|
+
if (c.httpOnly) parts.push("HttpOnly");
|
|
494
|
+
if (c.secure) parts.push("Secure");
|
|
495
|
+
parts.push(`SameSite=${c.sameSite.charAt(0).toUpperCase()}${c.sameSite.slice(1)}`);
|
|
496
|
+
return parts.join("; ");
|
|
497
|
+
}
|
|
498
|
+
function deleteCookie(cfg, kind) {
|
|
499
|
+
return buildCookie(cfg, { kind, value: "", maxAge: 0 });
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
// src/session/request.ts
|
|
503
|
+
function parseCookies(header) {
|
|
504
|
+
const out = {};
|
|
505
|
+
if (!header) return out;
|
|
506
|
+
for (const part of header.split(";")) {
|
|
507
|
+
const i = part.indexOf("=");
|
|
508
|
+
if (i < 0) continue;
|
|
509
|
+
const k = part.slice(0, i).trim();
|
|
510
|
+
const v = decodeURIComponent(part.slice(i + 1).trim());
|
|
511
|
+
if (k) out[k] = v;
|
|
512
|
+
}
|
|
513
|
+
return out;
|
|
514
|
+
}
|
|
515
|
+
function buildSetCookieHeaders(cfg, tokens) {
|
|
516
|
+
const accessTtl = cfg.tokens?.accessTtl ?? 900;
|
|
517
|
+
const refreshTtl = cfg.tokens?.refreshTtl ?? 2592e3;
|
|
518
|
+
return [
|
|
519
|
+
serializeCookie(buildCookie(cfg, { kind: "access", value: tokens.accessToken, maxAge: accessTtl })),
|
|
520
|
+
serializeCookie(buildCookie(cfg, { kind: "refresh", value: tokens.refreshToken, maxAge: refreshTtl })),
|
|
521
|
+
serializeCookie(buildCookie(cfg, { kind: "csrf", value: tokens.csrfToken, maxAge: refreshTtl, httpOnly: false }))
|
|
522
|
+
];
|
|
523
|
+
}
|
|
524
|
+
async function getSessionOrRefreshFromRequest(req, instance) {
|
|
525
|
+
const cfg = instance.config;
|
|
526
|
+
const jar = parseCookies(req.headers.get("cookie"));
|
|
527
|
+
const accessToken = jar[cookieName(cfg, "access")];
|
|
528
|
+
const refreshToken = jar[cookieName(cfg, "refresh")];
|
|
529
|
+
const ip = req.headers.get("x-forwarded-for")?.split(",")[0]?.trim() ?? req.headers.get("x-real-ip") ?? void 0;
|
|
530
|
+
const userAgent = req.headers.get("user-agent") ?? void 0;
|
|
531
|
+
const result = await getSessionOrRefresh(instance, {
|
|
532
|
+
accessToken,
|
|
533
|
+
refreshToken,
|
|
534
|
+
ip,
|
|
535
|
+
userAgent
|
|
536
|
+
});
|
|
537
|
+
const setCookieHeaders = result.tokens ? buildSetCookieHeaders(cfg, result.tokens) : [];
|
|
538
|
+
return { ...result, setCookieHeaders };
|
|
539
|
+
}
|
|
540
|
+
|
|
449
541
|
// src/password/index.ts
|
|
450
542
|
var password_exports = {};
|
|
451
543
|
__export(password_exports, {
|
|
@@ -545,8 +637,11 @@ function isExpired(challenge) {
|
|
|
545
637
|
// src/sso/index.ts
|
|
546
638
|
var sso_exports = {};
|
|
547
639
|
__export(sso_exports, {
|
|
640
|
+
DiscordProvider: () => DiscordProvider,
|
|
548
641
|
GithubProvider: () => GithubProvider,
|
|
549
642
|
GoogleProvider: () => GoogleProvider,
|
|
643
|
+
MicrosoftProvider: () => MicrosoftProvider,
|
|
644
|
+
OIDCProvider: () => OIDCProvider,
|
|
550
645
|
authorize: () => authorize,
|
|
551
646
|
base64url: () => base64url,
|
|
552
647
|
buildAuthorizeUrl: () => buildAuthorizeUrl,
|
|
@@ -840,6 +935,69 @@ function GithubProvider(opts) {
|
|
|
840
935
|
};
|
|
841
936
|
}
|
|
842
937
|
|
|
938
|
+
// src/sso/providers/discord.ts
|
|
939
|
+
function DiscordProvider(opts) {
|
|
940
|
+
return {
|
|
941
|
+
kind: "oauth2",
|
|
942
|
+
id: opts.id ?? "discord",
|
|
943
|
+
name: "Discord",
|
|
944
|
+
clientId: opts.clientId,
|
|
945
|
+
clientSecret: opts.clientSecret,
|
|
946
|
+
redirectUri: opts.redirectUri,
|
|
947
|
+
scopes: opts.scopes ?? ["identify", "email"],
|
|
948
|
+
authorizationUrl: "https://discord.com/oauth2/authorize",
|
|
949
|
+
tokenUrl: "https://discord.com/api/oauth2/token",
|
|
950
|
+
userinfoUrl: "https://discord.com/api/users/@me",
|
|
951
|
+
profile: (raw) => {
|
|
952
|
+
const p = raw ?? {};
|
|
953
|
+
const id = String(p.id ?? "");
|
|
954
|
+
const image = id && p.avatar ? `https://cdn.discordapp.com/avatars/${id}/${p.avatar}.png` : null;
|
|
955
|
+
return {
|
|
956
|
+
providerAccountId: id,
|
|
957
|
+
email: p.email ?? "",
|
|
958
|
+
name: p.global_name ?? p.username ?? null,
|
|
959
|
+
image
|
|
960
|
+
};
|
|
961
|
+
}
|
|
962
|
+
};
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
// src/sso/providers/microsoft.ts
|
|
966
|
+
function MicrosoftProvider(opts) {
|
|
967
|
+
const tenant = opts.tenantId ?? "common";
|
|
968
|
+
const base = `https://login.microsoftonline.com/${tenant}`;
|
|
969
|
+
return {
|
|
970
|
+
kind: "oidc",
|
|
971
|
+
id: opts.id ?? "microsoft",
|
|
972
|
+
name: "Microsoft",
|
|
973
|
+
clientId: opts.clientId,
|
|
974
|
+
clientSecret: opts.clientSecret,
|
|
975
|
+
redirectUri: opts.redirectUri,
|
|
976
|
+
scopes: opts.scopes ?? ["openid", "email", "profile"],
|
|
977
|
+
issuer: `${base}/v2.0`,
|
|
978
|
+
authorizationUrl: `${base}/oauth2/v2.0/authorize`,
|
|
979
|
+
tokenUrl: `${base}/oauth2/v2.0/token`,
|
|
980
|
+
userinfoUrl: "https://graph.microsoft.com/oidc/userinfo"
|
|
981
|
+
};
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
// src/sso/providers/oidc.ts
|
|
985
|
+
function OIDCProvider(opts) {
|
|
986
|
+
return {
|
|
987
|
+
kind: "oidc",
|
|
988
|
+
id: opts.id,
|
|
989
|
+
name: opts.name ?? opts.id,
|
|
990
|
+
clientId: opts.clientId,
|
|
991
|
+
clientSecret: opts.clientSecret,
|
|
992
|
+
redirectUri: opts.redirectUri,
|
|
993
|
+
scopes: opts.scopes ?? ["openid", "email", "profile"],
|
|
994
|
+
issuer: opts.issuer,
|
|
995
|
+
authorizationUrl: opts.authorizationUrl,
|
|
996
|
+
tokenUrl: opts.tokenUrl,
|
|
997
|
+
userinfoUrl: opts.userinfoUrl
|
|
998
|
+
};
|
|
999
|
+
}
|
|
1000
|
+
|
|
843
1001
|
// src/adapters/index.ts
|
|
844
1002
|
var adapters_exports = {};
|
|
845
1003
|
|
|
@@ -856,58 +1014,6 @@ __export(cookies_exports, {
|
|
|
856
1014
|
verifyCsrf: () => verifyCsrf
|
|
857
1015
|
});
|
|
858
1016
|
|
|
859
|
-
// src/cookies/spec.ts
|
|
860
|
-
function cookieName(cfg, kind) {
|
|
861
|
-
const prefix = cfg.tokens?.cookiePrefix ?? "holeauth";
|
|
862
|
-
switch (kind) {
|
|
863
|
-
case "access":
|
|
864
|
-
return `${prefix}.at`;
|
|
865
|
-
case "refresh":
|
|
866
|
-
return `${prefix}.rt`;
|
|
867
|
-
case "csrf":
|
|
868
|
-
return `${prefix}.csrf`;
|
|
869
|
-
case "pending":
|
|
870
|
-
return `${prefix}.pending`;
|
|
871
|
-
case "oauthState":
|
|
872
|
-
return `${prefix}.oauth.state`;
|
|
873
|
-
case "oauthPkce":
|
|
874
|
-
return `${prefix}.oauth.pkce`;
|
|
875
|
-
}
|
|
876
|
-
}
|
|
877
|
-
function isProduction() {
|
|
878
|
-
return globalThis.process?.env?.NODE_ENV === "production";
|
|
879
|
-
}
|
|
880
|
-
function buildCookie(cfg, input) {
|
|
881
|
-
const httpOnly = input.httpOnly ?? input.kind !== "csrf";
|
|
882
|
-
const secure = cfg.tokens?.cookieSecure ?? isProduction();
|
|
883
|
-
return {
|
|
884
|
-
name: cookieName(cfg, input.kind),
|
|
885
|
-
value: input.value,
|
|
886
|
-
maxAge: input.maxAge,
|
|
887
|
-
httpOnly,
|
|
888
|
-
secure,
|
|
889
|
-
sameSite: input.sameSite ?? cfg.tokens?.sameSite ?? "lax",
|
|
890
|
-
path: input.path ?? "/",
|
|
891
|
-
domain: cfg.tokens?.cookieDomain
|
|
892
|
-
};
|
|
893
|
-
}
|
|
894
|
-
function serializeCookie(c) {
|
|
895
|
-
const parts = [`${c.name}=${encodeURIComponent(c.value)}`];
|
|
896
|
-
parts.push(`Path=${c.path}`);
|
|
897
|
-
if (c.domain) parts.push(`Domain=${c.domain}`);
|
|
898
|
-
if (c.maxAge !== void 0) {
|
|
899
|
-
parts.push(`Max-Age=${c.maxAge}`);
|
|
900
|
-
if (c.maxAge === 0) parts.push("Expires=Thu, 01 Jan 1970 00:00:00 GMT");
|
|
901
|
-
}
|
|
902
|
-
if (c.httpOnly) parts.push("HttpOnly");
|
|
903
|
-
if (c.secure) parts.push("Secure");
|
|
904
|
-
parts.push(`SameSite=${c.sameSite.charAt(0).toUpperCase()}${c.sameSite.slice(1)}`);
|
|
905
|
-
return parts.join("; ");
|
|
906
|
-
}
|
|
907
|
-
function deleteCookie(cfg, kind) {
|
|
908
|
-
return buildCookie(cfg, { kind, value: "", maxAge: 0 });
|
|
909
|
-
}
|
|
910
|
-
|
|
911
1017
|
// src/events/index.ts
|
|
912
1018
|
var events_exports = {};
|
|
913
1019
|
__export(events_exports, {
|
|
@@ -1737,6 +1843,9 @@ function defineHoleauth(config) {
|
|
|
1737
1843
|
sso: {
|
|
1738
1844
|
authorize: (providerId) => authorize(config, providerId),
|
|
1739
1845
|
callback: (providerId, input) => callback(config, providerId, input)
|
|
1846
|
+
},
|
|
1847
|
+
on(type, handler) {
|
|
1848
|
+
return subscribe(config, type, handler);
|
|
1740
1849
|
}
|
|
1741
1850
|
};
|
|
1742
1851
|
const merged = { ...instance, ...registry.api };
|