@oglofus/auth 1.1.0 → 1.1.1

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.
@@ -165,6 +165,76 @@ export type OrganizationEntitlementSnapshot<Feature extends string, LimitKey ext
165
165
  features: Partial<Record<Feature, boolean>>;
166
166
  limits: Partial<Record<LimitKey, number>>;
167
167
  };
168
+ export type StripeSubject = {
169
+ kind: "user";
170
+ userId: string;
171
+ } | {
172
+ kind: "organization";
173
+ organizationId: string;
174
+ };
175
+ export type StripeReference = `user:${string}` | `organization:${string}`;
176
+ export type StripeBillingCycle = "monthly" | "annual";
177
+ export type StripeSubscriptionStatus = "trialing" | "active" | "past_due" | "unpaid" | "paused" | "canceled" | "incomplete" | "incomplete_expired";
178
+ export type StripeEntitlementSnapshot<Feature extends string, LimitKey extends string> = {
179
+ planKey?: string;
180
+ status?: StripeSubscriptionStatus;
181
+ features: Partial<Record<Feature, boolean>>;
182
+ limits: Partial<Record<LimitKey, number>>;
183
+ };
184
+ export type StripePlan<Feature extends string, LimitKey extends string> = {
185
+ key: string;
186
+ displayName: string;
187
+ scope: StripeSubject["kind"];
188
+ prices: {
189
+ monthly?: {
190
+ priceId: string;
191
+ };
192
+ annual?: {
193
+ priceId: string;
194
+ };
195
+ };
196
+ trial?: {
197
+ days: number;
198
+ oncePerSubject?: boolean;
199
+ };
200
+ seats?: {
201
+ enabled: boolean;
202
+ minimum?: number;
203
+ maximum?: number;
204
+ limitKey?: LimitKey;
205
+ };
206
+ features?: Partial<Record<Feature, boolean>>;
207
+ limits?: Partial<Record<LimitKey, number>>;
208
+ metadata?: Record<string, string>;
209
+ };
210
+ export interface StripeCustomerRecord {
211
+ id: string;
212
+ subject: StripeSubject;
213
+ stripeCustomerId: string;
214
+ createdAt: Date;
215
+ updatedAt: Date;
216
+ }
217
+ export interface StripeSubscriptionSnapshot<Feature extends string = string, LimitKey extends string = string> {
218
+ id: string;
219
+ subject: StripeSubject;
220
+ stripeCustomerId: string;
221
+ stripeSubscriptionId: string;
222
+ stripePriceId: string;
223
+ planKey: string;
224
+ status: StripeSubscriptionStatus;
225
+ billingCycle: StripeBillingCycle;
226
+ seats?: number | null;
227
+ cancelAtPeriodEnd: boolean;
228
+ currentPeriodStart?: Date | null;
229
+ currentPeriodEnd?: Date | null;
230
+ trialStartedAt?: Date | null;
231
+ trialEndsAt?: Date | null;
232
+ canceledAt?: Date | null;
233
+ features: Partial<Record<Feature, boolean>>;
234
+ limits: Partial<Record<LimitKey, number>>;
235
+ metadata?: Record<string, string>;
236
+ updatedAt: Date;
237
+ }
168
238
  export interface AuthRequestContext {
169
239
  requestId?: string;
170
240
  ip?: string;
@@ -1,11 +1,12 @@
1
1
  import type { CoreAdapters, OrganizationsPluginHandlers } from "./adapters.js";
2
- import type { AccountDiscoveryMode, AuthRequestContext, CompleteProfileInput, DiscoverAccountInput, DiscoverAccountDecision, MembershipBase, OrganizationBase, OrganizationEntitlementSnapshot, ProfileCompletionState, SecondFactorMethod, TwoFactorVerifyInput, UserBase } from "./model.js";
2
+ import type { AccountDiscoveryMode, AuthRequestContext, CompleteProfileInput, DiscoverAccountDecision, DiscoverAccountInput, MembershipBase, OrganizationBase, OrganizationEntitlementSnapshot, ProfileCompletionState, SecondFactorMethod, StripeBillingCycle, StripeEntitlementSnapshot, StripePlan, StripeSubject, StripeSubscriptionSnapshot, TwoFactorVerifyInput, UserBase } from "./model.js";
3
3
  import type { AuthResult, OperationResult } from "./results.js";
4
4
  export interface AuthPluginContext<U extends UserBase> {
5
5
  adapters: CoreAdapters<U>;
6
6
  now(): Date;
7
7
  security?: AuthSecurityConfig;
8
8
  request?: AuthRequestContext;
9
+ getPluginApi?<T = unknown>(method: string): T | null;
9
10
  }
10
11
  export interface BasePlugin<Method extends string, U extends UserBase, ExposedApi extends object = {}> {
11
12
  kind: "auth_method" | "domain";
@@ -185,10 +186,76 @@ export interface OrganizationsPluginApi<O extends OrganizationBase, Role extends
185
186
  remaining?: number;
186
187
  }>>;
187
188
  }
189
+ export interface StripePluginApi<Feature extends string, LimitKey extends string> {
190
+ createCheckoutSession(input: {
191
+ subject: StripeSubject;
192
+ planKey: string;
193
+ billingCycle: StripeBillingCycle;
194
+ successUrl: string;
195
+ cancelUrl: string;
196
+ seats?: number;
197
+ locale?: string;
198
+ metadata?: Record<string, string>;
199
+ }): Promise<OperationResult<{
200
+ url: string;
201
+ checkoutSessionId: string;
202
+ }>>;
203
+ createBillingPortalSession(input: {
204
+ subject: StripeSubject;
205
+ returnUrl: string;
206
+ locale?: string;
207
+ }): Promise<OperationResult<{
208
+ url: string;
209
+ }>>;
210
+ getSubscription(input: {
211
+ subject: StripeSubject;
212
+ }): Promise<OperationResult<{
213
+ subscription: StripeSubscriptionSnapshot<Feature, LimitKey> | null;
214
+ }>>;
215
+ listSubscriptions(input: {
216
+ subject: StripeSubject;
217
+ }): Promise<OperationResult<{
218
+ subscriptions: StripeSubscriptionSnapshot<Feature, LimitKey>[];
219
+ }>>;
220
+ cancelSubscription(input: {
221
+ subject: StripeSubject;
222
+ subscriptionId?: string;
223
+ atPeriodEnd?: boolean;
224
+ }): Promise<OperationResult<{
225
+ subscription: StripeSubscriptionSnapshot<Feature, LimitKey>;
226
+ }>>;
227
+ resumeSubscription(input: {
228
+ subject: StripeSubject;
229
+ subscriptionId?: string;
230
+ }): Promise<OperationResult<{
231
+ subscription: StripeSubscriptionSnapshot<Feature, LimitKey>;
232
+ }>>;
233
+ changePlan(input: {
234
+ subject: StripeSubject;
235
+ planKey: string;
236
+ billingCycle: StripeBillingCycle;
237
+ subscriptionId?: string;
238
+ seats?: number;
239
+ scheduleAtPeriodEnd?: boolean;
240
+ }): Promise<OperationResult<{
241
+ subscription: StripeSubscriptionSnapshot<Feature, LimitKey>;
242
+ }>>;
243
+ getEntitlements(input: {
244
+ subject: StripeSubject;
245
+ }): Promise<OperationResult<StripeEntitlementSnapshot<Feature, LimitKey>>>;
246
+ handleWebhook(input: {
247
+ rawBody: string | Uint8Array;
248
+ stripeSignature: string;
249
+ }): Promise<OperationResult<{
250
+ processed: true;
251
+ eventId: string;
252
+ }>>;
253
+ }
188
254
  export interface OrganizationsPluginConfig<O extends OrganizationBase, Role extends string, M extends MembershipBase<Role>, Permission extends string, Feature extends string, LimitKey extends string, RequiredOrgFields extends keyof O = never> {
189
255
  organizationRequiredFields?: readonly Extract<RequiredOrgFields, string>[];
190
256
  handlers: OrganizationsPluginHandlers<O, Role, M, Permission, Feature, LimitKey>;
191
257
  }
258
+ export type StripePlansResolver<Feature extends string, LimitKey extends string> = readonly StripePlan<Feature, LimitKey>[] | (() => Promise<readonly StripePlan<Feature, LimitKey>[]>);
192
259
  export type AuthSecurityRateLimitScope = "discover" | "register" | "authenticate" | "emailOtpRequest" | "magicLinkRequest" | "otpVerify";
193
260
  export interface AuthSecurityRateLimitPolicy {
194
261
  limit: number;
@@ -1,5 +1,5 @@
1
+ import type { AuthError, ProfileCompletionRequiredError, TwoFactorRequiredError } from "../errors/index.js";
1
2
  import type { Issue } from "../issues/index.js";
2
- import type { ProfileCompletionRequiredError, TwoFactorRequiredError, AuthError } from "../errors/index.js";
3
3
  import type { UserBase } from "./model.js";
4
4
  export type OperationResult<TData> = {
5
5
  ok: true;
@@ -1,4 +1,13 @@
1
- export const successResult = (user, sessionId, issues = []) => ({ ok: true, user, sessionId, issues });
1
+ export const successResult = (user, sessionId, issues = []) => ({
2
+ ok: true,
3
+ user,
4
+ sessionId,
5
+ issues,
6
+ });
2
7
  export const errorResult = (error, issues = error.issues) => ({ ok: false, error, issues });
3
- export const successOperation = (data, issues = []) => ({ ok: true, data, issues });
8
+ export const successOperation = (data, issues = []) => ({
9
+ ok: true,
10
+ data,
11
+ issues,
12
+ });
4
13
  export const errorOperation = (error, issues = error.issues) => ({ ok: false, error, issues });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oglofus/auth",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "Type-safe, plugin-first authentication core",
5
5
  "homepage": "https://github.com/oglofus/auth#readme",
6
6
  "bugs": {
@@ -18,7 +18,8 @@
18
18
  "build": "tsc -p tsconfig.json",
19
19
  "typecheck": "tsc -p tsconfig.test.json",
20
20
  "test": "tsx --test test/**/*.test.ts",
21
- "prepublishOnly": "npm run build"
21
+ "prepublishOnly": "npm run build",
22
+ "format": "prettier --write ."
22
23
  },
23
24
  "files": [
24
25
  "dist",
@@ -27,6 +28,9 @@
27
28
  ],
28
29
  "devDependencies": {
29
30
  "@types/node": "^25.3.5",
31
+ "prettier": "^3.8.1",
32
+ "prettier-plugin-organize-imports": "^4.3.0",
33
+ "stripe": "^20.4.1",
30
34
  "tsx": "^4.21.0",
31
35
  "typescript": "^5.9.3"
32
36
  },
@@ -42,6 +46,9 @@
42
46
  "@oslojs/otp": "^1.1.0",
43
47
  "arctic": "^3.7.0"
44
48
  },
49
+ "peerDependencies": {
50
+ "stripe": "^20.4.1"
51
+ },
45
52
  "publishConfig": {
46
53
  "access": "public"
47
54
  }