@oglofus/auth 1.1.1 → 1.1.2

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.
@@ -1,5 +1,5 @@
1
1
  import type { AuthRequestContext, CompleteProfileInput, DiscoverAccountDecision, DiscoverAccountInput, TwoFactorVerifyInput, UserBase } from "../types/model.js";
2
- import type { AnyPlugin, AuthConfig, AuthPublicApi, AuthenticateInputFromPlugins, PluginApiMap, PluginMethodsWithApi, RegisterInputFromPlugins } from "../types/plugins.js";
2
+ import type { AnyPlugin, AuthConfig, AuthPublicApi, AuthenticateInputFromPlugins, PluginApiForMethod, PluginMethodsWithApi, RegisterInputFromPlugins } from "../types/plugins.js";
3
3
  import { type AuthResult, type OperationResult } from "../types/results.js";
4
4
  export declare class OglofusAuth<U extends UserBase, P extends readonly AnyPlugin<U>[]> implements AuthPublicApi<U, P> {
5
5
  private readonly config;
@@ -10,7 +10,7 @@ export declare class OglofusAuth<U extends UserBase, P extends readonly AnyPlugi
10
10
  discover(input: DiscoverAccountInput, request?: AuthRequestContext): Promise<OperationResult<DiscoverAccountDecision>>;
11
11
  authenticate(input: AuthenticateInputFromPlugins<P>, request?: AuthRequestContext): Promise<AuthResult<U>>;
12
12
  register(input: RegisterInputFromPlugins<P>, request?: AuthRequestContext): Promise<AuthResult<U>>;
13
- method<M extends PluginMethodsWithApi<P>>(method: M): PluginApiMap<P>[M];
13
+ method<M extends PluginMethodsWithApi<P>>(method: M): PluginApiForMethod<P, M>;
14
14
  verifySecondFactor(input: TwoFactorVerifyInput, request?: AuthRequestContext): Promise<AuthResult<U>>;
15
15
  completeProfile(input: CompleteProfileInput<U>, request?: AuthRequestContext): Promise<AuthResult<U>>;
16
16
  validateSession(sessionId: string, _request?: AuthRequestContext): Promise<{
@@ -9,4 +9,4 @@ export type EmailOtpPluginConfig<U extends UserBase, K extends keyof U> = {
9
9
  maxAttempts?: number;
10
10
  codeLength?: number;
11
11
  };
12
- export declare const emailOtpPlugin: <U extends UserBase, K extends keyof U>(config: EmailOtpPluginConfig<U, K>) => AuthMethodPlugin<"email_otp", EmailOtpRegisterInput<U, K>, EmailOtpAuthenticateInput, U, EmailOtpPluginApi>;
12
+ export declare const emailOtpPlugin: <U extends UserBase, K extends keyof U>(config: EmailOtpPluginConfig<U, K>) => AuthMethodPlugin<"email_otp", EmailOtpRegisterInput<U, K>, EmailOtpAuthenticateInput, U, EmailOtpPluginApi, true, true>;
@@ -8,4 +8,4 @@ export type MagicLinkPluginConfig<U extends UserBase, K extends keyof U> = {
8
8
  tokenTtlSeconds?: number;
9
9
  baseVerifyUrl: string;
10
10
  };
11
- export declare const magicLinkPlugin: <U extends UserBase, K extends keyof U>(config: MagicLinkPluginConfig<U, K>) => AuthMethodPlugin<"magic_link", MagicLinkRegisterInput<U, K>, MagicLinkAuthenticateInput, U, MagicLinkPluginApi>;
11
+ export declare const magicLinkPlugin: <U extends UserBase, K extends keyof U>(config: MagicLinkPluginConfig<U, K>) => AuthMethodPlugin<"magic_link", MagicLinkRegisterInput<U, K>, MagicLinkAuthenticateInput, U, MagicLinkPluginApi, true, true>;
@@ -38,11 +38,11 @@ export type OAuth2ProviderConfig<U extends UserBase, P extends string> = {
38
38
  };
39
39
  export type OAuth2PluginConfig<U extends UserBase, P extends string, K extends keyof U = never> = {
40
40
  providers: {
41
- [Provider in P]: OAuth2ProviderConfig<U, Provider>;
41
+ [Provider in P]?: OAuth2ProviderConfig<U, Provider>;
42
42
  };
43
43
  accounts: OAuth2AccountAdapter<P>;
44
44
  requiredProfileFields?: readonly K[];
45
45
  pendingProfileTtlSeconds?: number;
46
46
  };
47
47
  export declare const arcticAuthorizationCodeExchange: (client: ArcticAuthorizationCodeClient) => OAuth2AuthorizationCodeExchange;
48
- export declare const oauth2Plugin: <U extends UserBase, P extends string, K extends keyof U = never>(config: OAuth2PluginConfig<U, P, K>) => AuthMethodPlugin<"oauth2", OAuth2AuthenticateInput<P>, OAuth2AuthenticateInput<P>, U>;
48
+ export declare const oauth2Plugin: <U extends UserBase, P extends string, K extends keyof U = never>(config: OAuth2PluginConfig<U, P, K>) => AuthMethodPlugin<"oauth2", OAuth2AuthenticateInput<P>, OAuth2AuthenticateInput<P>, U, never, false, false>;
@@ -9,4 +9,4 @@ export type OrganizationsPluginOptions<O extends OrganizationBase, Role extends
9
9
  nextRole: Role;
10
10
  }) => boolean | Promise<boolean>;
11
11
  };
12
- export declare const organizationsPlugin: <U extends UserBase, O extends OrganizationBase, Role extends string, M extends MembershipBase<Role>, Permission extends string, Feature extends string, LimitKey extends string, RequiredOrgFields extends keyof O = never>(config: OrganizationsPluginOptions<O, Role, M, Permission, Feature, LimitKey, RequiredOrgFields>) => DomainPlugin<"organizations", U, OrganizationsPluginApi<O, Role, M, Permission, Feature, LimitKey, RequiredOrgFields>>;
12
+ export declare const organizationsPlugin: <U extends UserBase, O extends OrganizationBase, Role extends string, M extends MembershipBase<Role>, Permission extends string, Feature extends string, LimitKey extends string, RequiredOrgFields extends keyof O = never>(config: OrganizationsPluginOptions<O, Role, M, Permission, Feature, LimitKey, RequiredOrgFields>) => DomainPlugin<"organizations", U, OrganizationsPluginApi<O, Role, M, Permission, Feature, LimitKey, RequiredOrgFields>, true>;
@@ -5,4 +5,4 @@ export type PasskeyPluginConfig<U extends UserBase, K extends keyof U> = {
5
5
  requiredProfileFields: readonly K[];
6
6
  passkeys: PasskeyAdapter;
7
7
  };
8
- export declare const passkeyPlugin: <U extends UserBase, K extends keyof U>(config: PasskeyPluginConfig<U, K>) => AuthMethodPlugin<"passkey", PasskeyRegisterInput<U, K>, PasskeyAuthenticateInput, U>;
8
+ export declare const passkeyPlugin: <U extends UserBase, K extends keyof U>(config: PasskeyPluginConfig<U, K>) => AuthMethodPlugin<"passkey", PasskeyRegisterInput<U, K>, PasskeyAuthenticateInput, U, never, true, false>;
@@ -7,4 +7,4 @@ export type PasswordPluginConfig<U extends UserBase, K extends keyof U> = {
7
7
  hashPassword?: (password: string) => string;
8
8
  verifyPassword?: (password: string, hash: string) => boolean;
9
9
  };
10
- export declare const passwordPlugin: <U extends UserBase, K extends keyof U>(config: PasswordPluginConfig<U, K>) => AuthMethodPlugin<"password", PasswordRegisterInput<U, K>, PasswordAuthenticateInput, U>;
10
+ export declare const passwordPlugin: <U extends UserBase, K extends keyof U>(config: PasswordPluginConfig<U, K>) => AuthMethodPlugin<"password", PasswordRegisterInput<U, K>, PasswordAuthenticateInput, U, never, true, false>;
@@ -1,6 +1,6 @@
1
1
  import type Stripe from "stripe";
2
2
  import type { StripeCustomerAdapter, StripeSubscriptionAdapter, StripeTrialUsageAdapter, StripeWebhookEventAdapter } from "../types/adapters.js";
3
- import type { UserBase } from "../types/model.js";
3
+ import type { StripePlan, StripeSubject, UserBase } from "../types/model.js";
4
4
  import type { DomainPlugin, StripePlansResolver, StripePluginApi } from "../types/plugins.js";
5
5
  type StripePluginHandlers<Feature extends string, LimitKey extends string> = {
6
6
  customers: StripeCustomerAdapter;
@@ -15,5 +15,11 @@ export type StripePluginConfig<U extends UserBase, Feature extends string, Limit
15
15
  handlers: StripePluginHandlers<Feature, LimitKey>;
16
16
  customerMode?: "user" | "organization" | "both";
17
17
  };
18
- export declare const stripePlugin: <U extends UserBase, Feature extends string, LimitKey extends string>(config: StripePluginConfig<U, Feature, LimitKey>) => DomainPlugin<"stripe", U, StripePluginApi<Feature, LimitKey>>;
18
+ type StripePlanCatalogEntry<Feature extends string, LimitKey extends string> = Omit<StripePlan<Feature, LimitKey>, "scope"> & {
19
+ scope: StripeSubject["kind"];
20
+ };
21
+ type StripePlanCatalog<Feature extends string, LimitKey extends string> = readonly StripePlanCatalogEntry<Feature, LimitKey>[];
22
+ export declare const stripePlugin: <U extends UserBase, Feature extends string, LimitKey extends string, const Plans extends StripePlanCatalog<Feature, LimitKey>>(config: Omit<StripePluginConfig<U, Feature, LimitKey>, "plans"> & {
23
+ plans: StripePlansResolver<Feature, LimitKey, Plans>;
24
+ }) => DomainPlugin<"stripe", U, StripePluginApi<Feature, LimitKey>, true>;
19
25
  export {};
@@ -14,7 +14,7 @@ export type TwoFactorPluginConfig<U extends UserBase> = {
14
14
  challengeTtlSeconds?: number;
15
15
  issuer?: string;
16
16
  };
17
- export declare const twoFactorPlugin: <U extends UserBase>(config: TwoFactorPluginConfig<U>) => DomainPlugin<"two_factor", U, TwoFactorPluginApi<U>>;
17
+ export declare const twoFactorPlugin: <U extends UserBase>(config: TwoFactorPluginConfig<U>) => DomainPlugin<"two_factor", U, TwoFactorPluginApi<U>, true>;
18
18
  export declare const testHelpers: {
19
19
  generateTotp: (secret: string, at?: Date) => string;
20
20
  };
@@ -127,7 +127,7 @@ export type ProfileCompletionState<U extends UserBase> = {
127
127
  email?: string;
128
128
  missingFields: readonly Extract<keyof U, string>[];
129
129
  prefill: Partial<U>;
130
- continuation?: Record<string, unknown>;
130
+ continuation?: Record<string, unknown> | null;
131
131
  };
132
132
  export type CompleteProfileInput<U extends UserBase> = {
133
133
  pendingProfileId: string;
@@ -8,11 +8,12 @@ export interface AuthPluginContext<U extends UserBase> {
8
8
  request?: AuthRequestContext;
9
9
  getPluginApi?<T = unknown>(method: string): T | null;
10
10
  }
11
- export interface BasePlugin<Method extends string, U extends UserBase, ExposedApi extends object = {}> {
11
+ export interface BasePlugin<Method extends string, U extends UserBase, ExposedApi extends object = never, HasApi extends boolean = boolean> {
12
12
  kind: "auth_method" | "domain";
13
13
  method: Method;
14
14
  version: string;
15
- createApi?: (ctx: Omit<AuthPluginContext<U>, "request">) => ExposedApi;
15
+ createApi?: HasApi extends true ? (ctx: Omit<AuthPluginContext<U>, "request">) => ExposedApi : never;
16
+ readonly __pluginApiBrand?: HasApi extends true ? ExposedApi : null;
16
17
  }
17
18
  export interface CompletePendingProfileInput<U extends UserBase> {
18
19
  record: ProfileCompletionState<U>;
@@ -22,28 +23,28 @@ export interface AuthMethodPlugin<Method extends string, RegisterInput extends {
22
23
  method: Method;
23
24
  }, AuthenticateInput extends {
24
25
  method: Method;
25
- }, U extends UserBase, ExposedApi extends object = {}> extends BasePlugin<Method, U, ExposedApi> {
26
+ }, U extends UserBase, ExposedApi extends object = never, SupportsRegister extends boolean = boolean, HasApi extends boolean = boolean> extends BasePlugin<Method, U, ExposedApi, HasApi> {
26
27
  kind: "auth_method";
27
28
  supports: {
28
- register: boolean;
29
+ register: SupportsRegister;
29
30
  };
30
31
  validators?: {
31
32
  authenticate?: (input: unknown) => AuthenticateInput;
32
- register?: (input: unknown) => RegisterInput;
33
+ register?: SupportsRegister extends true ? (input: unknown) => RegisterInput : never;
33
34
  };
34
35
  issueFields?: {
35
36
  authenticate: readonly Extract<keyof AuthenticateInput, string>[];
36
- register?: readonly Extract<keyof RegisterInput, string>[];
37
+ register?: SupportsRegister extends true ? readonly Extract<keyof RegisterInput, string>[] : never;
37
38
  };
38
- register?: (ctx: AuthPluginContext<U>, input: RegisterInput) => Promise<OperationResult<{
39
+ register?: SupportsRegister extends true ? (ctx: AuthPluginContext<U>, input: RegisterInput) => Promise<OperationResult<{
39
40
  user: U;
40
- }>>;
41
+ }>> : never;
41
42
  authenticate: (ctx: AuthPluginContext<U>, input: AuthenticateInput) => Promise<OperationResult<{
42
43
  user: U;
43
44
  }>>;
44
45
  completePendingProfile?: (ctx: AuthPluginContext<U>, input: CompletePendingProfileInput<U>) => Promise<OperationResult<void>>;
45
46
  }
46
- export interface DomainPlugin<Method extends string, U extends UserBase, ExposedApi extends object = {}> extends BasePlugin<Method, U, ExposedApi> {
47
+ export interface DomainPlugin<Method extends string, U extends UserBase, ExposedApi extends object = never, HasApi extends boolean = boolean> extends BasePlugin<Method, U, ExposedApi, HasApi> {
47
48
  kind: "domain";
48
49
  }
49
50
  export interface TwoFactorEvaluateResult {
@@ -255,7 +256,7 @@ export interface OrganizationsPluginConfig<O extends OrganizationBase, Role exte
255
256
  organizationRequiredFields?: readonly Extract<RequiredOrgFields, string>[];
256
257
  handlers: OrganizationsPluginHandlers<O, Role, M, Permission, Feature, LimitKey>;
257
258
  }
258
- export type StripePlansResolver<Feature extends string, LimitKey extends string> = readonly StripePlan<Feature, LimitKey>[] | (() => Promise<readonly StripePlan<Feature, LimitKey>[]>);
259
+ export type StripePlansResolver<Feature extends string, LimitKey extends string, Plans extends readonly StripePlan<Feature, LimitKey>[] = readonly StripePlan<Feature, LimitKey>[]> = Plans | (() => Promise<Plans>);
259
260
  export type AuthSecurityRateLimitScope = "discover" | "register" | "authenticate" | "emailOtpRequest" | "magicLinkRequest" | "otpVerify";
260
261
  export interface AuthSecurityRateLimitPolicy {
261
262
  limit: number;
@@ -265,26 +266,33 @@ export interface AuthSecurityConfig {
265
266
  rateLimits?: Partial<Record<AuthSecurityRateLimitScope, AuthSecurityRateLimitPolicy>>;
266
267
  oauth2IdempotencyTtlSeconds?: number;
267
268
  }
268
- export type AnyMethodPlugin<U extends UserBase> = AuthMethodPlugin<string, any, any, U, any>;
269
- export type AnyDomainPlugin<U extends UserBase> = DomainPlugin<string, U, any>;
269
+ export type AnyMethodPlugin<U extends UserBase> = AuthMethodPlugin<string, any, any, U, any, boolean, boolean>;
270
+ export type AnyDomainPlugin<U extends UserBase> = DomainPlugin<string, U, any, boolean>;
270
271
  export type AnyPlugin<U extends UserBase> = AnyMethodPlugin<U> | AnyDomainPlugin<U>;
271
- type MethodPlugins<P extends readonly AnyPlugin<any>[]> = Extract<P[number], AnyMethodPlugin<any>>;
272
- export type RegisterInputFromPlugins<P extends readonly AnyPlugin<any>[]> = MethodPlugins<P> extends infer Pl ? Pl extends {
272
+ type MethodPlugins<P extends readonly AnyPlugin<any>[]> = Extract<P[number], {
273
+ kind: "auth_method";
274
+ }>;
275
+ type RegisterCapableMethodPlugins<P extends readonly AnyPlugin<any>[]> = Extract<MethodPlugins<P>, {
276
+ supports: {
277
+ register: true;
278
+ };
279
+ }>;
280
+ type PluginExposedApi<Plugin> = Plugin extends {
281
+ __pluginApiBrand?: infer ExposedApi;
282
+ } ? ExposedApi : never;
283
+ export type RegisterInputFromPlugins<P extends readonly AnyPlugin<any>[]> = RegisterCapableMethodPlugins<P> extends infer Pl ? Pl extends {
273
284
  supports: {
274
285
  register: true;
275
286
  };
276
- } ? Pl extends AuthMethodPlugin<any, infer R, any, any, any> ? R : never : never : never;
277
- export type AuthenticateInputFromPlugins<P extends readonly AnyPlugin<any>[]> = MethodPlugins<P> extends AuthMethodPlugin<any, any, infer A, any, any> ? A : never;
287
+ } ? Pl extends AuthMethodPlugin<any, infer R, any, any, any, true, any> ? R : never : never : never;
288
+ export type AuthenticateInputFromPlugins<P extends readonly AnyPlugin<any>[]> = MethodPlugins<P> extends infer Pl ? Pl extends AuthMethodPlugin<any, any, infer A, any, any, any, any> ? A : never : never;
289
+ export type PluginApiForMethod<P extends readonly AnyPlugin<any>[], M extends P[number]["method"]> = Exclude<PluginExposedApi<Extract<P[number], {
290
+ method: M;
291
+ }>>, null>;
292
+ export type PluginMethodsWithApi<P extends readonly AnyPlugin<any>[]> = P[number]["method"] extends infer Method ? Method extends P[number]["method"] ? [PluginApiForMethod<P, Method>] extends [never] ? never : Method : never : never;
278
293
  export type PluginApiMap<P extends readonly AnyPlugin<any>[]> = {
279
- [M in P[number]["method"]]: Extract<P[number], {
280
- method: M;
281
- }> extends {
282
- createApi: (...args: any[]) => infer Api;
283
- } ? Api : never;
294
+ [M in PluginMethodsWithApi<P>]: PluginApiForMethod<P, M>;
284
295
  };
285
- export type PluginMethodsWithApi<P extends readonly AnyPlugin<any>[]> = {
286
- [M in keyof PluginApiMap<P>]: PluginApiMap<P>[M] extends never ? never : M;
287
- }[keyof PluginApiMap<P>];
288
296
  export interface AuthConfig<U extends UserBase, P extends readonly AnyPlugin<U>[]> {
289
297
  adapters: CoreAdapters<U>;
290
298
  plugins: P;
@@ -304,7 +312,7 @@ export interface AuthPublicApi<U extends UserBase, P extends readonly AnyPlugin<
304
312
  discover(input: DiscoverAccountInput, request?: AuthRequestContext): Promise<OperationResult<DiscoverAccountDecision>>;
305
313
  authenticate(input: AuthenticateInputFromPlugins<P>, request?: AuthRequestContext): Promise<AuthResult<U>>;
306
314
  register(input: RegisterInputFromPlugins<P>, request?: AuthRequestContext): Promise<AuthResult<U>>;
307
- method<M extends PluginMethodsWithApi<P>>(method: M): PluginApiMap<P>[M];
315
+ method<M extends PluginMethodsWithApi<P>>(method: M): PluginApiForMethod<P, M>;
308
316
  verifySecondFactor(input: TwoFactorVerifyInput, request?: AuthRequestContext): Promise<AuthResult<U>>;
309
317
  completeProfile(input: CompleteProfileInput<U>, request?: AuthRequestContext): Promise<AuthResult<U>>;
310
318
  validateSession(sessionId: string, request?: AuthRequestContext): Promise<{
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oglofus/auth",
3
- "version": "1.1.1",
3
+ "version": "1.1.2",
4
4
  "description": "Type-safe, plugin-first authentication core",
5
5
  "homepage": "https://github.com/oglofus/auth#readme",
6
6
  "bugs": {