@fonderie/auth 1.3.0 → 1.3.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.
@@ -0,0 +1,137 @@
1
+ <!-- GENERATED — do not edit. Regenerate with: npm run docs:signatures -->
2
+
3
+ # @fonderie/auth — outcomes
4
+
5
+ What this package does to a running app: tables its migrations create,
6
+ rows it seeds, routes it registers. Generated from the migration SQL and
7
+ route tables in source — trust this file instead of reading `dist/` or
8
+ downloading tarballs.
9
+
10
+ ## Database tables (after all migrations)
11
+
12
+ ### `fonderie_email_verifications`
13
+
14
+ ```sql
15
+ token TEXT PRIMARY KEY
16
+ user_id UUID NOT NULL REFERENCES fonderie_users(id) ON DELETE CASCADE
17
+ expires_at TIMESTAMPTZ NOT NULL
18
+ created_at TIMESTAMPTZ NOT NULL DEFAULT now()
19
+ PRIMARY KEY (user_id)
20
+ ```
21
+
22
+ ### `fonderie_mfa_backup_codes`
23
+
24
+ ```sql
25
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid()
26
+ user_id UUID NOT NULL REFERENCES fonderie_users(id) ON DELETE CASCADE
27
+ code_hash TEXT NOT NULL
28
+ used_at TIMESTAMPTZ
29
+ created_at TIMESTAMPTZ NOT NULL DEFAULT now()
30
+ ```
31
+
32
+ ### `fonderie_mfa_challenges`
33
+
34
+ ```sql
35
+ token TEXT PRIMARY KEY
36
+ user_id UUID NOT NULL REFERENCES fonderie_users(id) ON DELETE CASCADE
37
+ expires_at TIMESTAMPTZ NOT NULL
38
+ used_at TIMESTAMPTZ
39
+ created_at TIMESTAMPTZ NOT NULL DEFAULT now()
40
+ -- INDEX idx_fonderie_mfa_challenges_expires_at (expires_at)
41
+ ```
42
+
43
+ ### `fonderie_password_resets`
44
+
45
+ ```sql
46
+ user_id UUID PRIMARY KEY REFERENCES fonderie_users(id) ON DELETE CASCADE
47
+ expires_at TIMESTAMPTZ NOT NULL
48
+ created_at TIMESTAMPTZ NOT NULL DEFAULT now()
49
+ pin TEXT NOT NULL UNIQUE
50
+ -- INDEX idx_fonderie_password_resets_pin (pin)
51
+ ```
52
+
53
+ ### `fonderie_phone_verifications`
54
+
55
+ ```sql
56
+ phone TEXT PRIMARY KEY
57
+ otp TEXT NOT NULL
58
+ expires_at TIMESTAMPTZ NOT NULL
59
+ created_at TIMESTAMPTZ NOT NULL DEFAULT now()
60
+ user_id UUID REFERENCES fonderie_users(id) ON DELETE CASCADE
61
+ ```
62
+
63
+ ### `fonderie_sessions`
64
+
65
+ ```sql
66
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid()
67
+ user_id UUID NOT NULL REFERENCES fonderie_users(id) ON DELETE CASCADE
68
+ token TEXT NOT NULL UNIQUE
69
+ user_agent TEXT
70
+ ip_address TEXT
71
+ expires_at TIMESTAMPTZ NOT NULL
72
+ created_at TIMESTAMPTZ NOT NULL DEFAULT now()
73
+ sid UUID
74
+ -- INDEX idx_fonderie_sessions_expires_at (expires_at)
75
+ -- INDEX idx_fonderie_sessions_sid (sid)
76
+ ```
77
+
78
+ ### `fonderie_users`
79
+
80
+ ```sql
81
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid()
82
+ email TEXT UNIQUE
83
+ password_hash TEXT
84
+ first_name TEXT
85
+ last_name TEXT
86
+ phone TEXT
87
+ profile_image_url TEXT
88
+ locale TEXT NOT NULL DEFAULT 'en-US'
89
+ timezone TEXT NOT NULL DEFAULT 'UTC'
90
+ provider TEXT
91
+ provider_id TEXT
92
+ is_active BOOLEAN NOT NULL DEFAULT true
93
+ last_login TIMESTAMPTZ
94
+ preferences JSONB NOT NULL DEFAULT '{"notifications":{"email":true
95
+ suspended BOOLEAN NOT NULL DEFAULT false
96
+ whitelist BOOLEAN NOT NULL DEFAULT false
97
+ ip_whitelist JSONB NOT NULL DEFAULT '[]'
98
+ mfa_enabled BOOLEAN NOT NULL DEFAULT false
99
+ mfa_secret TEXT
100
+ email_verified_at TIMESTAMPTZ
101
+ deleted_at TIMESTAMPTZ
102
+ created_at TIMESTAMPTZ NOT NULL DEFAULT now()
103
+ updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
104
+ IF NOT EXISTS phone_verified_at TIMESTAMPTZ
105
+ CONSTRAINT fonderie_users_phone_unique UNIQUE (phone)
106
+ mfa_secret_pending TEXT
107
+ mfa_secret_pending_expires_at TIMESTAMPTZ
108
+ -- INDEX idx_fonderie_users_email (email)
109
+ ```
110
+
111
+ Raw SQL ships in `node_modules/@fonderie/auth/dist/migrations/sql/` — read it there if you must; never download tarballs.
112
+
113
+ ## HTTP routes registered
114
+
115
+ | Method | Path | Middleware chain (auth / validation / handler) |
116
+ |---|---|---|
117
+ | POST | `/auth/email/forgot` | `ipLimit('forgot') → validate(forgotPasswordSchema) → acctLimit('forgot') → auth.forgotPassword` |
118
+ | POST | `/auth/email/reset` | `validate(resetPasswordSchema) → auth.resetPassword` |
119
+ | GET | `/auth/google` | `oauth.googleInit` |
120
+ | GET | `/auth/google/callback` | `oauth.googleCallback` |
121
+ | POST | `/auth/login` | `ipLimit('login') → validate(loginSchema) → acctLimit('login') → auth.login` |
122
+ | POST | `/auth/logout` | `requireAuth → validate(refreshSchema) → auth.logout` |
123
+ | POST | `/auth/mfa/backup-codes` | `requireAuth → requireEmailLogin → requireVerified → validate(mfaTokenSchema) → mfa.regenerateBackupCodes` |
124
+ | POST | `/auth/mfa/disable` | `requireAuth → requireEmailLogin → requireVerified → validate(mfaTokenSchema) → mfa.disable` |
125
+ | POST | `/auth/mfa/setup` | `requireAuth → requireEmailLogin → requireVerified → mfa.setup` |
126
+ | POST | `/auth/mfa/verify` | `ipLimit('mfaVerify') → requireAnyAuth → requireEmailLogin → requireVerified → validate(mfaTokenSchema) → mfa.verify` |
127
+ | POST | `/auth/refresh` | `validate(refreshSchema) → auth.refresh` |
128
+ | POST | `/auth/register` | `ipLimit('register') → validate(registerSchema) → auth.register` |
129
+ | GET | `/auth/send-verification` | `requireAuth → auth.sendVerification` |
130
+ | POST | `/auth/verify` | `requireAuth → validate(verifySchema) → auth.verify` |
131
+ | DELETE | `/users` | `requireAuth → verifyGate → user.deleteMe` |
132
+ | GET | `/users` | `requireAuth → user.me` |
133
+ | PUT | `/users/email` | `requireAuth → verifyGate → validate(updateEmailSchema) → user.updateEmail` |
134
+ | PUT | `/users/password` | `requireAuth → validate(changePasswordSchema) → user.changePassword` |
135
+ | PUT | `/users/phone` | `requireAuth → verifyGate → validate(updatePhoneSchema) → user.updatePhone` |
136
+ | PUT | `/users/preferences` | `requireAuth → verifyGate → validate(updatePreferencesSchema) → user.updatePreferences` |
137
+ | PUT | `/users/profile` | `requireAuth → verifyGate → validate(updateProfileSchema) → user.updateProfile` |
@@ -0,0 +1,139 @@
1
+ <!-- GENERATED — do not edit. Regenerate with: npm run docs:signatures -->
2
+
3
+ # @fonderie/auth — signatures
4
+
5
+ ## @fonderie/auth
6
+
7
+ Subpath exports: `@fonderie/auth/types`, `@fonderie/auth/middleware`, `@fonderie/auth/migrations`
8
+
9
+ ```ts
10
+ interface IUser {
11
+ id: string;
12
+ email: string | null;
13
+ firstName: string | null;
14
+ lastName: string | null;
15
+ phone: string | null;
16
+ profileImageUrl: string | null;
17
+ locale: string;
18
+ timezone: string;
19
+ isActive: boolean;
20
+ lastLogin: Date | null;
21
+ preferences: IUserPreferences;
22
+ suspended: boolean;
23
+ whitelist: boolean;
24
+ ipWhitelist: string[];
25
+ deletedAt: Date | null;
26
+ createdAt: Date;
27
+ updatedAt: Date;
28
+ mfaEnabled: boolean;
29
+ passwordHash: string | null;
30
+ emailVerifiedAt: Date | null;
31
+ }
32
+
33
+ interface ISession {
34
+ id: string;
35
+ token: string;
36
+ userId: string;
37
+ userAgent: string | null;
38
+ ipAddress: string | null;
39
+ expiresAt: Date;
40
+ createdAt: Date;
41
+ }
42
+
43
+ interface IMfaChallenge {
44
+ token: string;
45
+ userId: string;
46
+ expiresAt: Date;
47
+ usedAt: Date | null;
48
+ }
49
+
50
+ new AuthModule(store: IStoreAdapter, config: IAuthConfig, bus?: EventBus | undefined): AuthModule
51
+ .name: "@fonderie/auth"
52
+ .install(app: IFonderieApp): void
53
+
54
+ interface IAuthConfig extends IAuthSecrets, IAuthRuntimeConfig {
55
+ secureCookies?: boolean;
56
+ rateLimit?: IAuthRateLimitConfig | false;
57
+ accessTokenDuration?: string;
58
+ providers: ('email' | 'phone' | 'google' | 'github')[];
59
+ appName?: string;
60
+ resolve?: (ctx: {
61
+ meta: Record<string, unknown>;
62
+ }) => Partial<IAuthRuntimeConfig>;
63
+ }
64
+
65
+ interface IAuthSecrets {
66
+ jwtSecret: string;
67
+ google?: {
68
+ clientId: string;
69
+ clientSecret: string;
70
+ redirectUri: string;
71
+ };
72
+ }
73
+
74
+ interface IAuthRuntimeConfig {
75
+ sessionDuration?: string;
76
+ verificationCooldown?: number;
77
+ mfa?: boolean;
78
+ requireVerification?: boolean;
79
+ }
80
+
81
+ const AUTH_CONFIG_KEYS: { sessionDuration: string; verificationCooldown: string; mfa: string; requireVerification: string; }
82
+
83
+ const MESSAGE_KEYS: { readonly emailRegistration: "email-registration"; readonly emailVerification: "email-verification"; readonly passwordReset: "password-reset"; readonly phoneOtp: "phone-otp"; readonly mfaEnabled: "mfa-enabled"; readonly mfaDisabled: "mfa-disabled"; readonly mfaBackupCodesRegenerated: "mfa-backup-codes-regenerated"; readonly emailChanged: "email-changed"; readonly phoneChanged: "phone-changed"; }
84
+
85
+ type AuthMessageKey = (typeof MESSAGE_KEYS)[keyof typeof MESSAGE_KEYS];
86
+
87
+ interface IUserDTO {
88
+ id: string;
89
+ email: string;
90
+ firstName: string;
91
+ lastName: string;
92
+ phone: string;
93
+ profileImageUrl: string;
94
+ isActive: boolean;
95
+ lastLogin: string;
96
+ preferences: IUserPreferences;
97
+ isEmailVerified: boolean;
98
+ isPhoneVerified: boolean;
99
+ mfaEnabled: boolean;
100
+ suspended: boolean;
101
+ whitelist: boolean;
102
+ ipWhitelist: string[];
103
+ createdAt: string;
104
+ updatedAt: string;
105
+ }
106
+
107
+ function toUserDTO(user: IUser, phoneVerified?: boolean): IUserDTO
108
+
109
+ function validate(schema: IRequestSchema): Middleware
110
+
111
+ namespace schemas — exports: ChangePasswordInput, LoginInput, RegisterInput, ResetPasswordInput, changePasswordSchema, forgotPasswordSchema, loginSchema, mfaTokenSchema, refreshSchema, registerSchema, resetPasswordSchema, updateEmailSchema, updatePhoneSchema, updatePreferencesSchema, updateProfileSchema, verifySchema
112
+
113
+ type RegisterInput = z.infer<typeof registerSchema>;
114
+
115
+ type LoginInput = z.infer<typeof loginSchema>;
116
+
117
+ type ResetPasswordInput = z.infer<typeof resetPasswordSchema>;
118
+
119
+ type ChangePasswordInput = z.infer<typeof changePasswordSchema>;
120
+
121
+ function withSession(store: IStoreAdapter, config: IAuthConfig): Middleware
122
+
123
+ function requireAuth(ctx: IFonderieContext, next: () => Promise<Response>): Promise<Response>
124
+
125
+ function normalizeEmail(email: string): string
126
+
127
+ function normalizeEmailSafe(email: string): string | null
128
+
129
+ function buildAuthIpLimiter(route: AuthLimitedRoute, store: IStoreAdapter, config: false | IAuthRateLimitConfig | undefined): Middleware | null
130
+
131
+ function buildAuthAccountLimiter(route: AuthLimitedRoute, store: IStoreAdapter, config: false | IAuthRateLimitConfig | undefined): Middleware | null
132
+
133
+ interface IAuthRateLimitConfig {
134
+ store?: IRateLimitStore;
135
+ rules?: Partial<Record<AuthLimitedRoute, IRateLimitRule | false>>;
136
+ }
137
+
138
+ type AuthLimitedRoute = 'login' | 'register' | 'forgot' | 'mfaVerify';
139
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fonderie/auth",
3
- "version": "1.3.0",
3
+ "version": "1.3.1",
4
4
  "description": "Drop-in auth for SaaS — email/password, phone OTP, Google OAuth, stateless JWT sessions, TOTP-based MFA with backup codes, and self-service password recovery.",
5
5
  "keywords": [
6
6
  "fonderie-js",
@@ -88,16 +88,17 @@
88
88
  },
89
89
  "files": [
90
90
  "dist",
91
+ "brain",
91
92
  "LICENSE",
92
93
  "README.md"
93
94
  ],
94
95
  "repository": {
95
96
  "type": "git",
96
- "url": "git+https://github.com/fonderie-js/sdk.git",
97
+ "url": "git+https://github.com/fonderiejs/sdk.git",
97
98
  "directory": "packages/auth"
98
99
  },
99
- "homepage": "https://github.com/fonderie-js/sdk/tree/main/packages/auth#readme",
100
+ "homepage": "https://github.com/fonderiejs/sdk/tree/main/packages/auth#readme",
100
101
  "bugs": {
101
- "url": "https://github.com/fonderie-js/sdk/issues"
102
+ "url": "https://github.com/fonderiejs/sdk/issues"
102
103
  }
103
104
  }