@spfn/auth 0.2.0-beta.45 → 0.2.0-beta.47

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/README.md CHANGED
@@ -77,72 +77,95 @@ export default defineServerConfig()
77
77
  .build();
78
78
  ```
79
79
 
80
- #### Register Router in `router.ts`
80
+ #### Register Router and Global Middleware in `router.ts`
81
81
 
82
82
  ```typescript
83
83
  import { defineRouter } from '@spfn/core/route';
84
- import { authRouter } from '@spfn/auth/server';
84
+ import { authRouter, authenticate } from '@spfn/auth/server';
85
+ import { getHealth } from './routes/health';
86
+ import { createOrder } from './routes/orders';
85
87
 
86
88
  export const appRouter = defineRouter({
87
- // Auth routes (fixed namespace)
88
- auth: authRouter,
89
-
89
+ getHealth,
90
+ createOrder,
90
91
  // ... your other routes
91
- });
92
+ })
93
+ .packages([authRouter]) // Auth routes (/_auth/* namespace)
94
+ .use([authenticate]); // Global auth middleware on all routes
95
+
96
+ export type AppRouter = typeof appRouter;
92
97
  ```
93
98
 
94
- ### 3. Configure Client (Next.js)
99
+ > **Important:** Public routes must explicitly skip auth with `.skip(['auth'])`.
100
+ > See the [Authentication Guide](https://spfn.dev/docs/guides/authentication) for details.
95
101
 
96
- #### Option A: Use the built-in `authApi` (Recommended)
102
+ ### 3. Configure Next.js Interceptor
103
+
104
+ Register the auth interceptor in your RPC proxy route. This handles session cookies, JWT signing, and key management automatically.
97
105
 
98
106
  ```typescript
99
- import { authApi } from '@spfn/auth';
107
+ // app/api/rpc/[routeName]/route.ts
108
+ import '@spfn/auth/nextjs/api'; // Must be first! Registers auth interceptor
109
+ import { appRouter } from '@/server/router';
110
+ import { createRpcProxy } from '@spfn/core/nextjs/server';
100
111
 
101
- // Type-safe API calls for auth routes
102
- const session = await authApi.getAuthSession.call({});
112
+ export const { GET, POST } = createRpcProxy({ router: appRouter });
103
113
  ```
104
114
 
105
- #### Option B: Register Error Registry in Custom API Client
115
+ Your API client needs no auth-specific configuration:
106
116
 
107
117
  ```typescript
118
+ // src/lib/api-client.ts
108
119
  import { createApi } from '@spfn/core/nextjs';
109
120
  import type { AppRouter } from '@/server/router';
110
- import { authErrorRegistry } from "@spfn/auth/errors";
111
- import { appMetadata } from '@/server/router.metadata';
112
- import { errorRegistry } from "@spfn/core/errors";
113
121
 
114
- export const api = createApi<AppRouter>({
115
- metadata: appMetadata,
116
- errorRegistry: errorRegistry.concat(authErrorRegistry),
117
- });
122
+ export const api = createApi<AppRouter>();
123
+ ```
124
+
125
+ The built-in `authApi` is also available for auth-only calls:
126
+
127
+ ```typescript
128
+ import { authApi } from '@spfn/auth';
129
+ const session = await authApi.getAuthSession.call({});
118
130
  ```
119
131
 
120
132
  ### 4. Environment Variables
121
133
 
134
+ Auth requires variables in **two separate files**: `.env.server` (SPFN backend) and `.env.local` (Next.js).
135
+
136
+ #### `.env.server` (SPFN Backend)
137
+
122
138
  ```bash
123
139
  # Required
124
- SPFN_AUTH_JWT_SECRET=your-secret-key
140
+ DATABASE_URL=postgresql://user:pass@localhost:5432/myapp_dev
125
141
  SPFN_AUTH_VERIFICATION_TOKEN_SECRET=your-verification-secret
126
- DATABASE_URL=postgresql://...
127
142
 
128
- # Next.js (required)
129
- SPFN_AUTH_SESSION_SECRET=your-32-char-secret
143
+ # Admin account (required — at least one format)
144
+ SPFN_AUTH_ADMIN_ACCOUNTS='[{"email":"admin@example.com","password":"Admin!@34","role":"superadmin"}]'
130
145
 
131
146
  # Optional
147
+ SPFN_AUTH_JWT_SECRET=your-jwt-secret
132
148
  SPFN_AUTH_JWT_EXPIRES_IN=7d
133
149
  SPFN_AUTH_BCRYPT_SALT_ROUNDS=10
134
150
  SPFN_AUTH_SESSION_TTL=7d
135
151
 
136
- # Google OAuth
152
+ # Google OAuth (optional)
137
153
  SPFN_AUTH_GOOGLE_CLIENT_ID=123456789-abc.apps.googleusercontent.com
138
154
  SPFN_AUTH_GOOGLE_CLIENT_SECRET=GOCSPX-...
139
- SPFN_APP_URL=http://localhost:3000
155
+ ```
156
+
157
+ #### `.env.local` (Next.js)
140
158
 
141
- # Google OAuth (Optional)
142
- SPFN_AUTH_GOOGLE_SCOPES=email,profile,https://www.googleapis.com/auth/gmail.readonly
143
- SPFN_AUTH_GOOGLE_REDIRECT_URI=http://localhost:8790/_auth/oauth/google/callback
144
- SPFN_AUTH_OAUTH_SUCCESS_URL=/auth/callback
145
- SPFN_AUTH_OAUTH_ERROR_URL=http://localhost:3000/auth/error?error={error}
159
+ ```bash
160
+ # Required
161
+ DATABASE_URL=postgresql://user:pass@localhost:5432/myapp_dev
162
+ SPFN_API_URL=http://localhost:8790
163
+
164
+ # Required for session cookies (minimum 32 characters)
165
+ SPFN_AUTH_SESSION_SECRET=my-super-secret-session-key-at-least-32-chars-long
166
+
167
+ # Optional
168
+ SPFN_AUTH_SESSION_TTL=7d
146
169
 
147
170
  # Email/SMS — configure via @spfn/notification
148
171
  # See @spfn/notification README for AWS SES/SNS settings
@@ -382,6 +382,30 @@ interface AuthInitOptions {
382
382
  sessionTtl?: string | number;
383
383
  }
384
384
 
385
+ /**
386
+ * One-Time Token Service
387
+ *
388
+ * Issues and verifies one-time tokens for direct API access.
389
+ */
390
+ interface IssueOneTimeTokenResult {
391
+ token: string;
392
+ expiresAt: string;
393
+ }
394
+ /**
395
+ * Issue a one-time token for the authenticated user
396
+ *
397
+ * @param userId - Authenticated user's ID
398
+ * @returns Token string and ISO expiration timestamp
399
+ */
400
+ declare function issueOneTimeTokenService(userId: string): Promise<IssueOneTimeTokenResult>;
401
+ /**
402
+ * Verify and consume a one-time token
403
+ *
404
+ * @param token - The one-time token to verify
405
+ * @returns userId if valid, null if invalid/expired/consumed
406
+ */
407
+ declare function verifyOneTimeTokenService(token: string): Promise<string | null>;
408
+
385
409
  /**
386
410
  * @spfn/auth - OAuth Service
387
411
  *
@@ -557,6 +581,7 @@ declare const mainAuthRouter: _spfn_core_route.Router<{
557
581
  emailVerified: boolean;
558
582
  phoneVerified: boolean;
559
583
  }>;
584
+ issueOneTimeToken: _spfn_core_route.RouteDef<{}, {}, IssueOneTimeTokenResult>;
560
585
  oauthGoogleStart: _spfn_core_route.RouteDef<{
561
586
  query: _sinclair_typebox.TObject<{
562
587
  state: _sinclair_typebox.TString;
@@ -912,4 +937,4 @@ declare const authenticate: _spfn_core_route.NamedMiddleware<"auth">;
912
937
  */
913
938
  declare const optionalAuth: _spfn_core_route.NamedMiddleware<"optionalAuth">;
914
939
 
915
- export { getEnabledOAuthProviders as $, type AuthSession as A, type ChangePasswordParams as B, type CheckAccountExistsResult as C, sendVerificationCodeService as D, verifyCodeService as E, type SendVerificationCodeParams as F, type VerifyCodeParams as G, type VerifyCodeResult as H, INVITATION_STATUSES as I, registerPublicKeyService as J, KEY_ALGORITHM as K, type LoginResult as L, rotateKeyService as M, revokeKeyService as N, type OAuthStartResult as O, type PermissionConfig as P, type RegisterPublicKeyParams as Q, type RoleConfig as R, type SendVerificationCodeResult as S, type RotateKeyParams as T, type UserProfile as U, type VerificationTargetType as V, type RevokeKeyParams as W, oauthStartService as X, oauthCallbackService as Y, buildOAuthErrorUrl as Z, isOAuthProviderEnabled as _, type RegisterResult as a, getGoogleAccessToken as a0, type OAuthStartParams as a1, type OAuthCallbackParams as a2, type OAuthCallbackResult as a3, authenticate as a4, optionalAuth as a5, EmailSchema as a6, PhoneSchema as a7, PasswordSchema as a8, TargetTypeSchema as a9, VerificationPurposeSchema as aa, type RotateKeyResult as b, type ProfileInfo as c, USER_STATUSES as d, SOCIAL_PROVIDERS as e, type VerificationPurpose as f, VERIFICATION_TARGET_TYPES as g, VERIFICATION_PURPOSES as h, PERMISSION_CATEGORIES as i, type PermissionCategory as j, type AuthInitOptions as k, type KeyAlgorithmType as l, mainAuthRouter as m, type InvitationStatus as n, type UserStatus as o, type SocialProvider as p, type AuthContext as q, checkAccountExistsService as r, registerService as s, loginService as t, logoutService as u, changePasswordService as v, type CheckAccountExistsParams as w, type RegisterParams as x, type LoginParams as y, type LogoutParams as z };
940
+ export { oauthCallbackService as $, type AuthSession as A, type LogoutParams as B, type CheckAccountExistsResult as C, type ChangePasswordParams as D, sendVerificationCodeService as E, verifyCodeService as F, type SendVerificationCodeParams as G, type VerifyCodeParams as H, type IssueOneTimeTokenResult as I, type VerifyCodeResult as J, KEY_ALGORITHM as K, type LoginResult as L, registerPublicKeyService as M, rotateKeyService as N, type OAuthStartResult as O, type PermissionConfig as P, revokeKeyService as Q, type RoleConfig as R, type SendVerificationCodeResult as S, type RegisterPublicKeyParams as T, type UserProfile as U, type VerificationTargetType as V, type RotateKeyParams as W, type RevokeKeyParams as X, issueOneTimeTokenService as Y, verifyOneTimeTokenService as Z, oauthStartService as _, type RegisterResult as a, buildOAuthErrorUrl as a0, isOAuthProviderEnabled as a1, getEnabledOAuthProviders as a2, getGoogleAccessToken as a3, type OAuthStartParams as a4, type OAuthCallbackParams as a5, type OAuthCallbackResult as a6, authenticate as a7, optionalAuth as a8, EmailSchema as a9, PhoneSchema as aa, PasswordSchema as ab, TargetTypeSchema as ac, VerificationPurposeSchema as ad, type RotateKeyResult as b, type ProfileInfo as c, INVITATION_STATUSES as d, USER_STATUSES as e, SOCIAL_PROVIDERS as f, type VerificationPurpose as g, VERIFICATION_TARGET_TYPES as h, VERIFICATION_PURPOSES as i, PERMISSION_CATEGORIES as j, type PermissionCategory as k, type AuthInitOptions as l, mainAuthRouter as m, type KeyAlgorithmType as n, type InvitationStatus as o, type UserStatus as p, type SocialProvider as q, type AuthContext as r, checkAccountExistsService as s, registerService as t, loginService as u, logoutService as v, changePasswordService as w, type CheckAccountExistsParams as x, type RegisterParams as y, type LoginParams as z };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as _spfn_core_nextjs from '@spfn/core/nextjs';
2
- import { R as RoleConfig, P as PermissionConfig, C as CheckAccountExistsResult, S as SendVerificationCodeResult, a as RegisterResult, L as LoginResult, b as RotateKeyResult, O as OAuthStartResult, U as UserProfile, c as ProfileInfo, m as mainAuthRouter } from './authenticate-CRDUKQbi.js';
3
- export { k as AuthInitOptions, A as AuthSession, I as INVITATION_STATUSES, n as InvitationStatus, K as KEY_ALGORITHM, l as KeyAlgorithmType, i as PERMISSION_CATEGORIES, j as PermissionCategory, e as SOCIAL_PROVIDERS, p as SocialProvider, d as USER_STATUSES, o as UserStatus, h as VERIFICATION_PURPOSES, g as VERIFICATION_TARGET_TYPES, f as VerificationPurpose, V as VerificationTargetType } from './authenticate-CRDUKQbi.js';
2
+ import { R as RoleConfig, P as PermissionConfig, C as CheckAccountExistsResult, S as SendVerificationCodeResult, a as RegisterResult, L as LoginResult, b as RotateKeyResult, I as IssueOneTimeTokenResult, O as OAuthStartResult, U as UserProfile, c as ProfileInfo, m as mainAuthRouter } from './authenticate-eucncHxN.js';
3
+ export { l as AuthInitOptions, A as AuthSession, d as INVITATION_STATUSES, o as InvitationStatus, K as KEY_ALGORITHM, n as KeyAlgorithmType, j as PERMISSION_CATEGORIES, k as PermissionCategory, f as SOCIAL_PROVIDERS, q as SocialProvider, e as USER_STATUSES, p as UserStatus, i as VERIFICATION_PURPOSES, h as VERIFICATION_TARGET_TYPES, g as VerificationPurpose, V as VerificationTargetType } from './authenticate-eucncHxN.js';
4
4
  import * as _spfn_core_route from '@spfn/core/route';
5
5
  import { HttpMethod } from '@spfn/core/route';
6
6
  import * as _sinclair_typebox from '@sinclair/typebox';
@@ -177,6 +177,7 @@ declare const authApi: _spfn_core_nextjs.Client<_spfn_core_route.Router<{
177
177
  emailVerified: boolean;
178
178
  phoneVerified: boolean;
179
179
  }>;
180
+ issueOneTimeToken: _spfn_core_route.RouteDef<{}, {}, IssueOneTimeTokenResult>;
180
181
  oauthGoogleStart: _spfn_core_route.RouteDef<{
181
182
  query: _sinclair_typebox.TObject<{
182
183
  state: _sinclair_typebox.TString;
package/dist/index.js CHANGED
@@ -172,6 +172,7 @@ var routeMap = {
172
172
  rotateKey: { method: "POST", path: "/_auth/keys/rotate" },
173
173
  changePassword: { method: "PUT", path: "/_auth/password" },
174
174
  getAuthSession: { method: "GET", path: "/_auth/session" },
175
+ issueOneTimeToken: { method: "POST", path: "/_auth/tokens" },
175
176
  getInvitation: { method: "GET", path: "/_auth/invitations/:token" },
176
177
  acceptInvitation: { method: "POST", path: "/_auth/invitations/accept" },
177
178
  createInvitation: { method: "POST", path: "/_auth/invitations" },