@ouim/logto-authkit 0.3.0
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 +823 -0
- package/dist/bundler-config.cjs +1 -0
- package/dist/bundler-config.d.ts +81 -0
- package/dist/bundler-config.js +31 -0
- package/dist/callback.d.ts +3 -0
- package/dist/components/signin-button.d.ts +53 -0
- package/dist/components/ui/alert.d.ts +8 -0
- package/dist/components/ui/avatar.d.ts +6 -0
- package/dist/components/ui/badge.d.ts +9 -0
- package/dist/components/ui/button.d.ts +11 -0
- package/dist/components/ui/card.d.ts +8 -0
- package/dist/components/ui/dialog.d.ts +19 -0
- package/dist/components/ui/dropdown-menu.d.ts +17 -0
- package/dist/components/ui/loading-spinner.d.ts +2 -0
- package/dist/components/ui/skeleton.d.ts +2 -0
- package/dist/components/ui/tooltip.d.ts +7 -0
- package/dist/components/utils/utils.d.ts +2 -0
- package/dist/context.d.ts +57 -0
- package/dist/index.cjs +129 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +9583 -0
- package/dist/navigation.d.ts +10 -0
- package/dist/server/authorization.d.ts +53 -0
- package/dist/server/csrf.d.ts +247 -0
- package/dist/server/index.cjs +1 -0
- package/dist/server/index.d.ts +4 -0
- package/dist/server/index.js +431 -0
- package/dist/server/types.d.ts +62 -0
- package/dist/server/verify-auth.d.ts +296 -0
- package/dist/signin.d.ts +42 -0
- package/dist/types.d.ts +81 -0
- package/dist/useAuth.d.ts +55 -0
- package/dist/usePermission.d.ts +9 -0
- package/dist/user-center.d.ts +49 -0
- package/dist/utils.d.ts +169 -0
- package/package.json +111 -0
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
import type { AuthContext, VerifyAuthOptions, ExpressRequest, ExpressResponse, ExpressNext, NextRequest } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Remove the cached JWKS entry for a specific Logto tenant.
|
|
4
|
+
*
|
|
5
|
+
* Useful after rotating signing keys, changing proxy/network configuration,
|
|
6
|
+
* or when an operator wants the next verification to force a fresh JWKS fetch.
|
|
7
|
+
*
|
|
8
|
+
* @param {string} logtoUrl - Logto server URL whose JWKS cache entry should be removed.
|
|
9
|
+
*/
|
|
10
|
+
export declare function invalidateJwksCache(logtoUrl: string): void;
|
|
11
|
+
/**
|
|
12
|
+
* Clear all cached JWKS entries held in this process.
|
|
13
|
+
*
|
|
14
|
+
* Useful in tests, long-lived worker processes, or admin/debug flows where
|
|
15
|
+
* you want the next verification for every tenant to fetch fresh keys.
|
|
16
|
+
*/
|
|
17
|
+
export declare function clearJwksCache(): void;
|
|
18
|
+
/**
|
|
19
|
+
* Verify JWT Token from Logto
|
|
20
|
+
*
|
|
21
|
+
* Verifies a Logto JWT token by:
|
|
22
|
+
* 1. Decoding the JWT header to extract key ID (kid) and algorithm
|
|
23
|
+
* 2. Fetching the JWKS (JSON Web Key Set) from Logto's OIDC endpoint (cached, default 5 min TTL)
|
|
24
|
+
* 3. Finding the matching public key
|
|
25
|
+
* 4. Verifying the token signature
|
|
26
|
+
* 5. Validating the payload shape (all required/typed fields present)
|
|
27
|
+
* 6. Validating all claims (issuer, audience, expiration, scope, etc.)
|
|
28
|
+
*
|
|
29
|
+
* Key-rotation resilience: if step 3 or 4 fails with a key-related error (e.g. Logto
|
|
30
|
+
* rotated its signing keys and the cached JWKS no longer contains the new `kid`), the
|
|
31
|
+
* cache entry is invalidated and a single retry is attempted with freshly fetched JWKS.
|
|
32
|
+
* Claims errors (wrong audience, expired token, etc.) are NOT retried.
|
|
33
|
+
*
|
|
34
|
+
* @param {string} token - The JWT token to verify (typically from Authorization header or cookie)
|
|
35
|
+
* @param {VerifyAuthOptions} options - Verification options
|
|
36
|
+
* @param {string} options.logtoUrl - Logto server URL (e.g., 'https://tenant.logto.app')
|
|
37
|
+
* @param {string | string[]} [options.audience] - Expected token audience or audiences (resource/API identifier)
|
|
38
|
+
* @param {string} [options.requiredScope] - Required scope that must be present in token
|
|
39
|
+
* @param {string} [options.cookieName] - Cookie name for token storage (default: 'logto_authtoken')
|
|
40
|
+
* @param {boolean} [options.allowGuest] - Allow unauthenticated guest access
|
|
41
|
+
* @param {number} [options.jwksCacheTtlMs=300000] - How long to cache fetched JWKS keys in memory per process
|
|
42
|
+
* @param {boolean} [options.skipJwksCache=false] - When true, bypass the in-memory JWKS cache for this verification call
|
|
43
|
+
*
|
|
44
|
+
* @returns {Promise<AuthContext>} Authentication context with user ID, authentication status, and token payload
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* try {
|
|
48
|
+
* const auth = await verifyLogtoToken(token, {
|
|
49
|
+
* logtoUrl: 'https://tenant.logto.app',
|
|
50
|
+
* audience: 'urn:logto:resource:api'
|
|
51
|
+
* });
|
|
52
|
+
* console.log(auth.userId); // User ID from token
|
|
53
|
+
* } catch (error) {
|
|
54
|
+
* console.error('Token verification failed:', error.message);
|
|
55
|
+
* }
|
|
56
|
+
*
|
|
57
|
+
* @throws {Error} If token format is invalid, signature verification fails, or claims validation fails
|
|
58
|
+
*/
|
|
59
|
+
export declare function verifyLogtoToken(token: string, options: VerifyAuthOptions): Promise<AuthContext>;
|
|
60
|
+
/**
|
|
61
|
+
* Create Express Middleware for Logto Authentication
|
|
62
|
+
*
|
|
63
|
+
* Creates Express middleware that automatically extracts and verifies Logto JWT tokens
|
|
64
|
+
* from incoming requests. Handles token extraction from cookies or Authorization headers,
|
|
65
|
+
* validates tokens, and attaches authentication context to the request object.
|
|
66
|
+
*
|
|
67
|
+
* @param {VerifyAuthOptions} options - Middleware configuration options
|
|
68
|
+
* @param {string} options.logtoUrl - Logto server URL
|
|
69
|
+
* @param {string | string[]} [options.audience] - Expected token audience or audiences
|
|
70
|
+
* @param {string} [options.requiredScope] - Required scope
|
|
71
|
+
* @param {string} [options.cookieName='logto_authtoken'] - Cookie name for token
|
|
72
|
+
* @param {boolean} [options.allowGuest=false] - Allow unauthenticated access as guest
|
|
73
|
+
*
|
|
74
|
+
* @returns {Function} Express middleware function
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* import express from 'express';
|
|
78
|
+
* import { createExpressAuthMiddleware } from '@ouim/logto-authkit/server';
|
|
79
|
+
*
|
|
80
|
+
* const app = express();
|
|
81
|
+
*
|
|
82
|
+
* // Apply middleware to all routes
|
|
83
|
+
* app.use(createExpressAuthMiddleware({
|
|
84
|
+
* logtoUrl: process.env.LOGTO_ENDPOINT,
|
|
85
|
+
* audience: 'urn:logto:resource:api'
|
|
86
|
+
* }));
|
|
87
|
+
*
|
|
88
|
+
* // Access authenticated user
|
|
89
|
+
* app.get('/api/me', (req, res) => {
|
|
90
|
+
* if (req.auth?.isAuthenticated) {
|
|
91
|
+
* res.json({ userId: req.auth.userId });
|
|
92
|
+
* } else {
|
|
93
|
+
* res.status(401).json({ error: 'Unauthorized' });
|
|
94
|
+
* }
|
|
95
|
+
* });
|
|
96
|
+
*
|
|
97
|
+
* @example
|
|
98
|
+
* // Allow guest access
|
|
99
|
+
* app.use(createExpressAuthMiddleware({
|
|
100
|
+
* logtoUrl: process.env.LOGTO_ENDPOINT,
|
|
101
|
+
* allowGuest: true
|
|
102
|
+
* }));
|
|
103
|
+
*
|
|
104
|
+
* // Distinguish authenticated vs guest users
|
|
105
|
+
* app.get('/api/data', (req, res) => {
|
|
106
|
+
* if (req.auth?.isGuest) {
|
|
107
|
+
* res.json({ data: 'limited data for guests' });
|
|
108
|
+
* } else {
|
|
109
|
+
* res.json({ data: 'full data for authenticated users' });
|
|
110
|
+
* }
|
|
111
|
+
* });
|
|
112
|
+
*/
|
|
113
|
+
export declare function createExpressAuthMiddleware(options: VerifyAuthOptions): (req: ExpressRequest, res: ExpressResponse, next: ExpressNext) => Promise<void>;
|
|
114
|
+
/**
|
|
115
|
+
* Verify Next.js Request Authentication
|
|
116
|
+
*
|
|
117
|
+
* Verifies Logto authentication for Next.js API routes and middleware.
|
|
118
|
+
* Extracts JWT from cookies or Authorization header, verifies the token,
|
|
119
|
+
* and returns authentication context.
|
|
120
|
+
*
|
|
121
|
+
* @param {NextRequest} request - Next.js request-like object. Supports both middleware-style requests with `cookies.get()`
|
|
122
|
+
* and App Router route-handler `Request` objects that only expose `headers.get()`.
|
|
123
|
+
* @param {VerifyAuthOptions} options - Verification options
|
|
124
|
+
* @param {string} options.logtoUrl - Logto server URL
|
|
125
|
+
* @param {string | string[]} [options.audience] - Expected token audience or audiences
|
|
126
|
+
* @param {string} [options.requiredScope] - Required scope
|
|
127
|
+
* @param {string} [options.cookieName='logto_authtoken'] - Cookie name
|
|
128
|
+
* @param {boolean} [options.allowGuest] - Allow unauthenticated guest access
|
|
129
|
+
*
|
|
130
|
+
* @returns {Promise<{success: true, auth: AuthContext} | {success: false, error: string, auth?: AuthContext}>}
|
|
131
|
+
* - `success: true` — token verified **or** a valid guest session (`allowGuest: true`).
|
|
132
|
+
* Always check `result.auth.isAuthenticated` (or `result.auth.isGuest`) to distinguish
|
|
133
|
+
* authenticated users from guests; do NOT rely on `success` alone as an auth gate.
|
|
134
|
+
* - `success: false` — no token found and guest mode is disabled, or an unrecoverable error.
|
|
135
|
+
*
|
|
136
|
+
* @example
|
|
137
|
+
* // In a Next.js API route — reject unauthenticated requests
|
|
138
|
+
* import { verifyNextAuth } from '@ouim/logto-authkit/server';
|
|
139
|
+
*
|
|
140
|
+
* export async function GET(request) {
|
|
141
|
+
* const result = await verifyNextAuth(request, {
|
|
142
|
+
* logtoUrl: process.env.LOGTO_ENDPOINT,
|
|
143
|
+
* audience: 'urn:logto:resource:api'
|
|
144
|
+
* });
|
|
145
|
+
*
|
|
146
|
+
* if (!result.success) {
|
|
147
|
+
* return new Response(JSON.stringify({ error: result.error }), { status: 401 });
|
|
148
|
+
* }
|
|
149
|
+
*
|
|
150
|
+
* return new Response(JSON.stringify({
|
|
151
|
+
* userId: result.auth.userId,
|
|
152
|
+
* authenticated: result.auth.isAuthenticated
|
|
153
|
+
* }));
|
|
154
|
+
* }
|
|
155
|
+
*
|
|
156
|
+
* @example
|
|
157
|
+
* // In Next.js middleware — allow guests, block fully unauthenticated requests
|
|
158
|
+
* import { NextRequest, NextResponse } from 'next/server';
|
|
159
|
+
* import { verifyNextAuth } from '@ouim/logto-authkit/server';
|
|
160
|
+
*
|
|
161
|
+
* export async function middleware(request: NextRequest) {
|
|
162
|
+
* const result = await verifyNextAuth(request, {
|
|
163
|
+
* logtoUrl: process.env.LOGTO_ENDPOINT,
|
|
164
|
+
* allowGuest: true
|
|
165
|
+
* });
|
|
166
|
+
*
|
|
167
|
+
* // success:true covers both authenticated users and guests when allowGuest is set.
|
|
168
|
+
* // Use auth.isAuthenticated (or auth.isGuest) to distinguish the two cases.
|
|
169
|
+
* if (result.success && result.auth.isAuthenticated) {
|
|
170
|
+
* return NextResponse.next();
|
|
171
|
+
* }
|
|
172
|
+
* if (result.success && result.auth.isGuest) {
|
|
173
|
+
* return NextResponse.next(); // allow guest through, or redirect to limited view
|
|
174
|
+
* }
|
|
175
|
+
*
|
|
176
|
+
* return NextResponse.redirect(new URL('/login', request.url));
|
|
177
|
+
* }
|
|
178
|
+
*/
|
|
179
|
+
export declare function verifyNextAuth(request: NextRequest, options: VerifyAuthOptions): Promise<{
|
|
180
|
+
success: true;
|
|
181
|
+
auth: AuthContext;
|
|
182
|
+
} | {
|
|
183
|
+
success: false;
|
|
184
|
+
error: string;
|
|
185
|
+
auth?: AuthContext;
|
|
186
|
+
}>;
|
|
187
|
+
/**
|
|
188
|
+
* Generic Token/Request Authentication Verification
|
|
189
|
+
*
|
|
190
|
+
* Universal verification function that works with any Node.js environment.
|
|
191
|
+
* Accepts either a JWT token string directly or a request object (Express, Next.js, etc.)
|
|
192
|
+
* and verifies the authentication.
|
|
193
|
+
*
|
|
194
|
+
* @param {string | {cookies?: any, headers?: any}} tokenOrRequest - Either:
|
|
195
|
+
* - A JWT token string to verify directly
|
|
196
|
+
* - A request-like object with cookies and headers properties
|
|
197
|
+
* @param {VerifyAuthOptions} options - Verification options
|
|
198
|
+
* @param {string} options.logtoUrl - Logto server URL
|
|
199
|
+
* @param {string | string[]} [options.audience] - Expected token audience or audiences
|
|
200
|
+
* @param {string} [options.requiredScope] - Required scope
|
|
201
|
+
* @param {string} [options.cookieName='logto_authtoken'] - Cookie name
|
|
202
|
+
* @param {boolean} [options.allowGuest] - Allow unauthenticated guest access
|
|
203
|
+
*
|
|
204
|
+
* @returns {Promise<AuthContext>} Authentication context
|
|
205
|
+
*
|
|
206
|
+
* @example
|
|
207
|
+
* // Verify a token directly
|
|
208
|
+
* const auth = await verifyAuth(jwtToken, {
|
|
209
|
+
* logtoUrl: 'https://tenant.logto.app',
|
|
210
|
+
* audience: 'urn:logto:resource:api'
|
|
211
|
+
* });
|
|
212
|
+
*
|
|
213
|
+
* @example
|
|
214
|
+
* // Verify from a request object
|
|
215
|
+
* const auth = await verifyAuth(request, {
|
|
216
|
+
* logtoUrl: process.env.LOGTO_ENDPOINT,
|
|
217
|
+
* allowGuest: true
|
|
218
|
+
* });
|
|
219
|
+
*
|
|
220
|
+
* @throws {Error} If token verification fails or no token found and guest mode disabled
|
|
221
|
+
*/
|
|
222
|
+
export declare function verifyAuth(tokenOrRequest: string | {
|
|
223
|
+
cookies?: unknown;
|
|
224
|
+
headers?: unknown;
|
|
225
|
+
}, options: VerifyAuthOptions): Promise<AuthContext>;
|
|
226
|
+
/**
|
|
227
|
+
* Build a `Set-Cookie` header string that sets the auth token as an `HttpOnly` cookie.
|
|
228
|
+
*
|
|
229
|
+
* ## Why this exists — the XSS / non-httpOnly problem
|
|
230
|
+
*
|
|
231
|
+
* The client-side `jwtCookieUtils.saveToken()` sets the auth token from JavaScript.
|
|
232
|
+
* Because `HttpOnly` can only be set by the **server** (via a `Set-Cookie` response
|
|
233
|
+
* header), the client-set cookie is readable by any same-origin JavaScript, including
|
|
234
|
+
* scripts injected by an XSS attack.
|
|
235
|
+
*
|
|
236
|
+
* If your deployment includes a backend (Express, Next.js, etc.) that handles the
|
|
237
|
+
* post-authentication callback, you can upgrade security by having the server re-set
|
|
238
|
+
* the cookie with `HttpOnly`. The browser will then attach it to every request
|
|
239
|
+
* automatically and JavaScript can no longer read it.
|
|
240
|
+
*
|
|
241
|
+
* ## Recommended flow
|
|
242
|
+
*
|
|
243
|
+
* ```
|
|
244
|
+
* 1. Frontend CallbackPage exchanges the auth code via Logto SDK (as normal).
|
|
245
|
+
* 2. Frontend sends the obtained JWT to a backend endpoint, e.g. POST /api/session.
|
|
246
|
+
* 3. Backend verifies the JWT with verifyLogtoToken(), then calls buildAuthCookieHeader()
|
|
247
|
+
* and sets it on the response.
|
|
248
|
+
* 4. The browser now holds an HttpOnly cookie — the frontend no longer needs to store
|
|
249
|
+
* the JWT in its own document.cookie.
|
|
250
|
+
* ```
|
|
251
|
+
*
|
|
252
|
+
* @param {string} token - The verified JWT string to store in the cookie.
|
|
253
|
+
* @param {object} [options]
|
|
254
|
+
* @param {string} [options.cookieName='logto_authtoken'] - Cookie name. Must match the
|
|
255
|
+
* `cookieName` used by the backend middleware so it finds the token on subsequent requests.
|
|
256
|
+
* @param {number} [options.maxAge=604800] - Cookie lifetime in **seconds** (default: 7 days).
|
|
257
|
+
* @param {string} [options.domain] - Cookie domain (omit to use the current host).
|
|
258
|
+
* @param {string} [options.path='/'] - Cookie path.
|
|
259
|
+
* @param {'Strict'|'Lax'|'None'} [options.sameSite='Strict'] - SameSite policy.
|
|
260
|
+
* Use `'None'` only if you need the cookie on cross-site requests (requires `Secure`).
|
|
261
|
+
*
|
|
262
|
+
* @returns {string} A complete `Set-Cookie` header value ready to pass to `res.setHeader`.
|
|
263
|
+
*
|
|
264
|
+
* @example
|
|
265
|
+
* // Express — upgrade to HttpOnly after verifying the token
|
|
266
|
+
* import express from 'express';
|
|
267
|
+
* import { verifyLogtoToken, buildAuthCookieHeader } from '@ouim/logto-authkit/server';
|
|
268
|
+
*
|
|
269
|
+
* app.post('/api/session', async (req, res) => {
|
|
270
|
+
* const token = req.body.token; // JWT sent from the frontend after Logto callback
|
|
271
|
+
* const auth = await verifyLogtoToken(token, { logtoUrl: process.env.LOGTO_ENDPOINT });
|
|
272
|
+
* const cookie = buildAuthCookieHeader(token);
|
|
273
|
+
* res.setHeader('Set-Cookie', cookie);
|
|
274
|
+
* res.json({ userId: auth.userId });
|
|
275
|
+
* });
|
|
276
|
+
*
|
|
277
|
+
* @example
|
|
278
|
+
* // Next.js Route Handler — same pattern
|
|
279
|
+
* import { verifyLogtoToken, buildAuthCookieHeader } from '@ouim/logto-authkit/server';
|
|
280
|
+
*
|
|
281
|
+
* export async function POST(request: Request) {
|
|
282
|
+
* const { token } = await request.json();
|
|
283
|
+
* const auth = await verifyLogtoToken(token, { logtoUrl: process.env.LOGTO_ENDPOINT });
|
|
284
|
+
* const cookie = buildAuthCookieHeader(token);
|
|
285
|
+
* return new Response(JSON.stringify({ userId: auth.userId }), {
|
|
286
|
+
* headers: { 'Content-Type': 'application/json', 'Set-Cookie': cookie },
|
|
287
|
+
* });
|
|
288
|
+
* }
|
|
289
|
+
*/
|
|
290
|
+
export declare function buildAuthCookieHeader(token: string, options?: {
|
|
291
|
+
cookieName?: string;
|
|
292
|
+
maxAge?: number;
|
|
293
|
+
domain?: string;
|
|
294
|
+
path?: string;
|
|
295
|
+
sameSite?: 'Strict' | 'Lax' | 'None';
|
|
296
|
+
}): string;
|
package/dist/signin.d.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { SignInPageProps } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* SignInPage Component
|
|
4
|
+
*
|
|
5
|
+
* Internal page component that auto-initiates the sign-in flow. This is a special route
|
|
6
|
+
* that automatically starts the Logto sign-in process when loaded.
|
|
7
|
+
*
|
|
8
|
+
* In redirect flow:
|
|
9
|
+
* - If user is not authenticated, initiates sign-in redirect to Logto
|
|
10
|
+
* - User is redirected back to /callback after Logto authentication
|
|
11
|
+
* - Redirects to home page on success
|
|
12
|
+
*
|
|
13
|
+
* In popup flow (when opened from parent with ?popup=true):
|
|
14
|
+
* - Detects it's running in a popup (via window.opener or sessionStorage flag)
|
|
15
|
+
* - Initiates sign-in without opening nested popups
|
|
16
|
+
* - Notifies parent window via postMessage when complete
|
|
17
|
+
* - Self-closes the popup
|
|
18
|
+
*
|
|
19
|
+
* @component
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* // Set up route for the sign-in page
|
|
23
|
+
* // In Next.js or React Router
|
|
24
|
+
* <Route path="/signin" component={SignInPage} />
|
|
25
|
+
*
|
|
26
|
+
* // AuthProvider with popup sign-in enabled
|
|
27
|
+
* <AuthProvider config={logtoConfig} enablePopupSignIn={true}>
|
|
28
|
+
* <App />
|
|
29
|
+
* </AuthProvider>
|
|
30
|
+
*
|
|
31
|
+
* @param {string} [className] - CSS classes to apply to the loading/error container
|
|
32
|
+
* @param {React.ReactNode} [loadingComponent] - Custom loading UI shown while auth state is resolving
|
|
33
|
+
* @param {React.ReactNode | ((error: Error) => React.ReactNode)} [errorComponent] - Custom error UI shown if sign-in initiation fails
|
|
34
|
+
*
|
|
35
|
+
* @returns {React.ReactElement|null} Loading spinner during auth, null otherwise
|
|
36
|
+
*
|
|
37
|
+
* @see {@link CallbackPage} for the callback handler page
|
|
38
|
+
* @see {@link SignInButton} for a button component to trigger sign-in
|
|
39
|
+
*
|
|
40
|
+
* @internal
|
|
41
|
+
*/
|
|
42
|
+
export declare function SignInPage({ className, loadingComponent, errorComponent }: SignInPageProps): import("react/jsx-runtime").JSX.Element | null;
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import type { LogtoConfig } from '@logto/react';
|
|
2
|
+
export type LogtoUser = {
|
|
3
|
+
id: string;
|
|
4
|
+
name?: string;
|
|
5
|
+
email?: string;
|
|
6
|
+
avatar?: string;
|
|
7
|
+
[key: string]: any;
|
|
8
|
+
};
|
|
9
|
+
export type AuthMiddleware = 'auth' | 'guest' | undefined;
|
|
10
|
+
export interface NavigationOptions {
|
|
11
|
+
replace?: boolean;
|
|
12
|
+
force?: boolean;
|
|
13
|
+
}
|
|
14
|
+
export interface AuthOptions {
|
|
15
|
+
middleware?: AuthMiddleware;
|
|
16
|
+
redirectTo?: string;
|
|
17
|
+
redirectIfAuthenticated?: string;
|
|
18
|
+
navigationOptions?: NavigationOptions;
|
|
19
|
+
}
|
|
20
|
+
export interface UsePermissionOptions {
|
|
21
|
+
claimKeys?: string[];
|
|
22
|
+
mode?: 'all' | 'any';
|
|
23
|
+
}
|
|
24
|
+
export interface AuthContextType {
|
|
25
|
+
user: LogtoUser | null;
|
|
26
|
+
isLoadingUser: boolean;
|
|
27
|
+
signIn: (callbackUrl?: string, usePopup?: boolean) => Promise<void>;
|
|
28
|
+
signOut: (options?: {
|
|
29
|
+
callbackUrl?: string;
|
|
30
|
+
global?: boolean;
|
|
31
|
+
}) => Promise<void>;
|
|
32
|
+
refreshAuth: () => Promise<void>;
|
|
33
|
+
enablePopupSignIn?: boolean;
|
|
34
|
+
}
|
|
35
|
+
export type AuthSignOutReason = 'user' | 'auth_error' | 'missing_access_token' | 'transient_error_limit';
|
|
36
|
+
export interface AuthTokenRefreshEvent {
|
|
37
|
+
user: LogtoUser;
|
|
38
|
+
accessToken: string;
|
|
39
|
+
expiresAt?: number;
|
|
40
|
+
previousExpiresAt?: number;
|
|
41
|
+
}
|
|
42
|
+
export interface AuthErrorEvent {
|
|
43
|
+
error: Error;
|
|
44
|
+
isTransient: boolean;
|
|
45
|
+
willSignOut: boolean;
|
|
46
|
+
}
|
|
47
|
+
export interface AuthSignOutEvent {
|
|
48
|
+
reason: AuthSignOutReason;
|
|
49
|
+
global: boolean;
|
|
50
|
+
callbackUrl?: string;
|
|
51
|
+
error?: Error;
|
|
52
|
+
}
|
|
53
|
+
export interface AuthProviderProps {
|
|
54
|
+
children: React.ReactNode;
|
|
55
|
+
config: LogtoConfig;
|
|
56
|
+
callbackUrl?: string;
|
|
57
|
+
customNavigate?: (url: string, options?: NavigationOptions) => void;
|
|
58
|
+
enablePopupSignIn?: boolean;
|
|
59
|
+
onTokenRefresh?: (event: AuthTokenRefreshEvent) => void;
|
|
60
|
+
onAuthError?: (event: AuthErrorEvent) => void;
|
|
61
|
+
onSignOut?: (event: AuthSignOutEvent) => void;
|
|
62
|
+
}
|
|
63
|
+
export interface CallbackPageProps {
|
|
64
|
+
className?: string;
|
|
65
|
+
loadingComponent?: React.ReactNode;
|
|
66
|
+
successComponent?: React.ReactNode;
|
|
67
|
+
onSuccess?: () => void;
|
|
68
|
+
onError?: (error: Error) => void;
|
|
69
|
+
/** URL to redirect to after successful authentication. Defaults to `'/'`. */
|
|
70
|
+
redirectTo?: string;
|
|
71
|
+
}
|
|
72
|
+
export interface SignInPageProps {
|
|
73
|
+
className?: string;
|
|
74
|
+
loadingComponent?: React.ReactNode;
|
|
75
|
+
errorComponent?: React.ReactNode | ((error: Error) => React.ReactNode);
|
|
76
|
+
}
|
|
77
|
+
export interface AdditionalPage {
|
|
78
|
+
link: string;
|
|
79
|
+
text: string;
|
|
80
|
+
icon?: React.ReactNode;
|
|
81
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { AuthOptions, AuthContextType } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* useAuth Hook
|
|
4
|
+
*
|
|
5
|
+
* Main hook to access authentication state and functions. Provides user information,
|
|
6
|
+
* loading state, and methods for sign-in/sign-out. Automatically handles route protection
|
|
7
|
+
* based on middleware configuration.
|
|
8
|
+
*
|
|
9
|
+
* @param {AuthOptions} [options] - Configuration options for auth behavior
|
|
10
|
+
* @param {AuthMiddleware} [options.middleware] - Route protection mode:
|
|
11
|
+
* - `'auth'` - Protect route - redirects unauthenticated users to `redirectTo` URL
|
|
12
|
+
* - `'guest'` - Guest-only route - redirects authenticated users to `redirectIfAuthenticated` URL
|
|
13
|
+
* - `undefined` - No protection
|
|
14
|
+
* @param {string} [options.redirectTo] - URL to redirect to when middleware='auth' and user is not authenticated (default: '/signin')
|
|
15
|
+
* @param {string} [options.redirectIfAuthenticated] - URL to redirect to when middleware='guest' and user is authenticated
|
|
16
|
+
* @param {NavigationOptions} [options.navigationOptions] - Navigation behavior options
|
|
17
|
+
*
|
|
18
|
+
* @returns {AuthContextType} Object containing:
|
|
19
|
+
* - `user` - Current user object or null if not authenticated
|
|
20
|
+
* - `isLoadingUser` - Whether user data is still loading
|
|
21
|
+
* - `signIn` - Function to initiate sign-in flow
|
|
22
|
+
* - `signOut` - Function to sign out user
|
|
23
|
+
* - `refreshAuth` - Function to manually refresh authentication state
|
|
24
|
+
* - `enablePopupSignIn` - Whether popup sign-in is enabled
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* // Access user data and sign-in/sign-out functions
|
|
28
|
+
* function Dashboard() {
|
|
29
|
+
* const { user, isLoadingUser, signOut } = useAuth({ middleware: 'auth' })
|
|
30
|
+
*
|
|
31
|
+
* if (isLoadingUser) return <div>Loading...</div>
|
|
32
|
+
* if (!user) return null // Would have redirected by middleware
|
|
33
|
+
*
|
|
34
|
+
* return (
|
|
35
|
+
* <div>
|
|
36
|
+
* Welcome, {user.name}!
|
|
37
|
+
* <button onClick={() => signOut()}>Sign Out</button>
|
|
38
|
+
* </div>
|
|
39
|
+
* )
|
|
40
|
+
* }
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* // Protect a guest-only login page
|
|
44
|
+
* function LoginPage() {
|
|
45
|
+
* const { user } = useAuth({
|
|
46
|
+
* middleware: 'guest',
|
|
47
|
+
* redirectIfAuthenticated: '/dashboard'
|
|
48
|
+
* })
|
|
49
|
+
*
|
|
50
|
+
* return <div>Sign in form...</div>
|
|
51
|
+
* }
|
|
52
|
+
*
|
|
53
|
+
* @throws {Error} If used outside of AuthProvider context
|
|
54
|
+
*/
|
|
55
|
+
export declare const useAuth: (options?: AuthOptions) => AuthContextType;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { UsePermissionOptions } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Return `true` when the current frontend auth user contains the requested permission claim.
|
|
4
|
+
*
|
|
5
|
+
* Reads the client-side `user` object exposed by `AuthProvider`, which is built from
|
|
6
|
+
* Logto's frontend claims. This is intended for conditional rendering only. Use the
|
|
7
|
+
* backend verifier helpers for authoritative server-side authorization decisions.
|
|
8
|
+
*/
|
|
9
|
+
export declare function usePermission(permission: string | string[], options?: UsePermissionOptions): boolean;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { AdditionalPage } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* UserCenter Component
|
|
5
|
+
*
|
|
6
|
+
* User profile and account management dropdown component. Displays the current user's
|
|
7
|
+
* avatar and name in a dropdown menu with sign-out and additional custom pages.
|
|
8
|
+
*
|
|
9
|
+
* Features:
|
|
10
|
+
* - Displays user avatar with fallback initials
|
|
11
|
+
* - Dropdown menu with user options
|
|
12
|
+
* - Sign-out functionality with configurable redirect
|
|
13
|
+
* - Support for additional custom pages/links
|
|
14
|
+
* - Dark mode support
|
|
15
|
+
* - Prevents hydration issues with client-only rendering
|
|
16
|
+
*
|
|
17
|
+
* @component
|
|
18
|
+
* @param {string} [className] - CSS classes for the container element
|
|
19
|
+
* @param {boolean} [globalSignOut=false] - Whether to perform global sign-out (logs out of entire Logto ecosystem) or local only
|
|
20
|
+
* @param {string} [signoutCallbackUrl] - URL to redirect to after sign-out (default: current page)
|
|
21
|
+
* @param {AdditionalPage[]} [additionalPages] - Array of custom pages/links to show in dropdown
|
|
22
|
+
* @param {string} [themeClassnames] - Tailwind classnames for theming (light/dark mode)
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* // Basic user center
|
|
26
|
+
* <UserCenter />
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* // With custom pages and dark mode
|
|
30
|
+
* <UserCenter
|
|
31
|
+
* globalSignOut={false}
|
|
32
|
+
* signoutCallbackUrl="/"
|
|
33
|
+
* additionalPages={[
|
|
34
|
+
* { link: '/settings', text: 'Settings', icon: <Settings /> },
|
|
35
|
+
* { link: '/profile', text: 'Profile' }
|
|
36
|
+
* ]}
|
|
37
|
+
* themeClassnames="dark:bg-slate-900 dark:text-white bg-gray-50 text-gray-900"
|
|
38
|
+
* />
|
|
39
|
+
*
|
|
40
|
+
* @returns {React.ReactElement} Dropdown component with user profile
|
|
41
|
+
*/
|
|
42
|
+
export interface UserCenterProps {
|
|
43
|
+
className?: string;
|
|
44
|
+
globalSignOut?: boolean;
|
|
45
|
+
themeClassnames?: string;
|
|
46
|
+
signoutCallbackUrl?: string;
|
|
47
|
+
additionalPages?: AdditionalPage[];
|
|
48
|
+
}
|
|
49
|
+
export declare const UserCenter: React.FC<UserCenterProps>;
|