@spfn/auth 0.2.0-beta.46 → 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 +53 -30
- package/dist/{authenticate-CRDUKQbi.d.ts → authenticate-eucncHxN.d.ts} +26 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/server.d.ts +92 -4
- package/dist/server.js +88 -1
- package/dist/server.js.map +1 -1
- package/package.json +3 -3
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
|
-
|
|
88
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
102
|
-
const session = await authApi.getAuthSession.call({});
|
|
112
|
+
export const { GET, POST } = createRpcProxy({ router: appRouter });
|
|
103
113
|
```
|
|
104
114
|
|
|
105
|
-
|
|
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
|
-
|
|
116
|
-
|
|
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
|
-
|
|
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
|
-
#
|
|
129
|
-
|
|
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
|
-
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
#### `.env.local` (Next.js)
|
|
140
158
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
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 {
|
|
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-
|
|
3
|
-
export {
|
|
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" },
|