@markwharton/pwa-core 3.4.2 → 4.0.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/dist/client.d.ts +47 -89
- package/dist/client.js +102 -252
- package/dist/server.d.ts +83 -53
- package/dist/server.js +235 -67
- package/dist/shared.d.ts +4 -4
- package/dist/shared.js +4 -4
- package/package.json +8 -1
package/dist/server.d.ts
CHANGED
|
@@ -23,12 +23,11 @@ export declare function initAuth(config: {
|
|
|
23
23
|
/**
|
|
24
24
|
* Initializes JWT authentication from environment variables.
|
|
25
25
|
* Reads JWT_SECRET from process.env.
|
|
26
|
-
* @param minLength - Minimum required secret length (default: 32)
|
|
27
26
|
* @throws Error if JWT_SECRET is missing or too short
|
|
28
27
|
* @example
|
|
29
28
|
* initAuthFromEnv(); // Uses process.env.JWT_SECRET
|
|
30
29
|
*/
|
|
31
|
-
export declare function initAuthFromEnv(
|
|
30
|
+
export declare function initAuthFromEnv(): void;
|
|
32
31
|
/**
|
|
33
32
|
* Gets the configured JWT secret.
|
|
34
33
|
* @returns The JWT secret string
|
|
@@ -75,50 +74,31 @@ export declare function generateToken<T extends object>(payload: T, expiresIn?:
|
|
|
75
74
|
* const apiToken = generateLongLivedToken({ machineId: 'server-1' });
|
|
76
75
|
*/
|
|
77
76
|
export declare function generateLongLivedToken<T extends object>(payload: T, expiresInDays?: number): string;
|
|
78
|
-
/**
|
|
79
|
-
* Successful auth result with typed payload.
|
|
80
|
-
*/
|
|
81
|
-
export interface AuthSuccess<T extends BaseJwtPayload> {
|
|
82
|
-
authorized: true;
|
|
83
|
-
payload: T;
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* Failed auth result with HTTP response.
|
|
87
|
-
*/
|
|
88
|
-
export interface AuthFailure {
|
|
89
|
-
authorized: false;
|
|
90
|
-
response: HttpResponseInit;
|
|
91
|
-
}
|
|
92
|
-
/**
|
|
93
|
-
* Discriminated union for auth results.
|
|
94
|
-
* Use `auth.authorized` to narrow the type.
|
|
95
|
-
*/
|
|
96
|
-
export type AuthResult<T extends BaseJwtPayload> = AuthSuccess<T> | AuthFailure;
|
|
97
77
|
/** Default token expiry string for generateToken (7 days) */
|
|
98
78
|
export declare const DEFAULT_TOKEN_EXPIRY = "7d";
|
|
99
79
|
/** Default token expiry in seconds (7 days = 604800 seconds) */
|
|
100
80
|
export declare const DEFAULT_TOKEN_EXPIRY_SECONDS: number;
|
|
101
81
|
/**
|
|
102
|
-
* Validates auth header and returns typed payload or error
|
|
82
|
+
* Validates auth header and returns typed payload or error result.
|
|
103
83
|
* @typeParam T - The expected payload type (extends BaseJwtPayload)
|
|
104
84
|
* @param authHeader - The Authorization header value
|
|
105
|
-
* @returns
|
|
85
|
+
* @returns Result with payload on success, or error with status on failure
|
|
106
86
|
* @example
|
|
107
87
|
* const auth = requireAuth<UsernameTokenPayload>(request.headers.get('Authorization'));
|
|
108
|
-
* if (!auth.
|
|
109
|
-
* console.log(auth.
|
|
88
|
+
* if (!auth.ok) return resultToResponse(auth);
|
|
89
|
+
* console.log(auth.data.username);
|
|
110
90
|
*/
|
|
111
|
-
export declare function requireAuth<T extends BaseJwtPayload>(authHeader: string | null):
|
|
91
|
+
export declare function requireAuth<T extends BaseJwtPayload>(authHeader: string | null): Result<T>;
|
|
112
92
|
/**
|
|
113
93
|
* Requires admin role. Use with RoleTokenPayload.
|
|
114
94
|
* @param authHeader - The Authorization header value
|
|
115
|
-
* @returns
|
|
95
|
+
* @returns Result with RoleTokenPayload on success, or error with status on failure
|
|
116
96
|
* @example
|
|
117
97
|
* const auth = requireAdmin(request.headers.get('Authorization'));
|
|
118
|
-
* if (!auth.
|
|
98
|
+
* if (!auth.ok) return resultToResponse(auth);
|
|
119
99
|
* // User is admin
|
|
120
100
|
*/
|
|
121
|
-
export declare function requireAdmin(authHeader: string | null):
|
|
101
|
+
export declare function requireAdmin(authHeader: string | null): Result<RoleTokenPayload>;
|
|
122
102
|
/**
|
|
123
103
|
* Extracts API key from the X-API-Key header.
|
|
124
104
|
* @param request - Request object with headers.get() method
|
|
@@ -259,12 +239,14 @@ export declare function initErrorHandling(config?: {
|
|
|
259
239
|
* Initializes error handling from environment variables.
|
|
260
240
|
* Currently a no-op but provides consistent API for future error config
|
|
261
241
|
* (e.g., ERROR_LOG_LEVEL, ERROR_INCLUDE_STACK).
|
|
262
|
-
* @param
|
|
242
|
+
* @param config - Optional config with onError callback invoked when handleFunctionError is called (fire-and-forget)
|
|
263
243
|
* @example
|
|
264
244
|
* initErrorHandlingFromEnv(); // Uses process.env automatically
|
|
265
|
-
* initErrorHandlingFromEnv((op, msg) => sendAlert(op, msg));
|
|
245
|
+
* initErrorHandlingFromEnv({ onError: (op, msg) => sendAlert(op, msg) });
|
|
266
246
|
*/
|
|
267
|
-
export declare function initErrorHandlingFromEnv(
|
|
247
|
+
export declare function initErrorHandlingFromEnv(config?: {
|
|
248
|
+
onError?: ErrorCallback;
|
|
249
|
+
}): void;
|
|
268
250
|
/**
|
|
269
251
|
* Handles unexpected errors safely by logging details and returning a generic message.
|
|
270
252
|
* Use in catch blocks to avoid exposing internal error details to clients.
|
|
@@ -397,15 +379,16 @@ export declare function upsertEntity<T extends {
|
|
|
397
379
|
}>(client: TableClient, entity: T): Promise<void>;
|
|
398
380
|
/**
|
|
399
381
|
* Deletes an entity from Azure Table Storage.
|
|
400
|
-
* Returns true
|
|
382
|
+
* Returns ok(true) if deleted, ok(false) if not found (not an error), err() on real failures.
|
|
401
383
|
* @param client - The TableClient instance
|
|
402
384
|
* @param partitionKey - The partition key
|
|
403
385
|
* @param rowKey - The row key
|
|
404
|
-
* @returns
|
|
386
|
+
* @returns Result with true if deleted, false if not found, or error on failure
|
|
405
387
|
* @example
|
|
406
|
-
* const
|
|
388
|
+
* const result = await deleteEntity(client, 'session', sessionId);
|
|
389
|
+
* if (!result.ok) console.error(result.error);
|
|
407
390
|
*/
|
|
408
|
-
export declare function deleteEntity(client: TableClient, partitionKey: string, rowKey: string): Promise<boolean
|
|
391
|
+
export declare function deleteEntity(client: TableClient, partitionKey: string, rowKey: string): Promise<Result<boolean>>;
|
|
409
392
|
/**
|
|
410
393
|
* Lists all entities in a partition.
|
|
411
394
|
* @typeParam T - The entity type
|
|
@@ -458,7 +441,8 @@ export interface SessionAuthConfig {
|
|
|
458
441
|
allowedDomain?: string;
|
|
459
442
|
/** Emails that get isAdmin=true */
|
|
460
443
|
adminEmails?: string[];
|
|
461
|
-
/**
|
|
444
|
+
/** Additional email validation. Called after built-in domain/admin checks reject.
|
|
445
|
+
* Can only widen access, never narrow it. Supports async for database lookups. */
|
|
462
446
|
isEmailAllowed?: (email: string) => boolean | Promise<boolean>;
|
|
463
447
|
/** Base URL for magic links and SWA preview URL validation */
|
|
464
448
|
appBaseUrl?: string;
|
|
@@ -480,16 +464,25 @@ export declare function initSessionAuth(config: SessionAuthConfig): void;
|
|
|
480
464
|
/**
|
|
481
465
|
* Initializes session auth from environment variables.
|
|
482
466
|
* Reads: SESSION_COOKIE_NAME, APP_BASE_URL, ALLOWED_EMAILS, ALLOWED_DOMAIN, ADMIN_EMAILS.
|
|
483
|
-
*
|
|
484
|
-
*
|
|
467
|
+
* Only callbacks go in the config object — data comes from env vars.
|
|
468
|
+
* Use initSessionAuth() directly for full control.
|
|
469
|
+
* @param config - Required config with sendEmail callback and optional isEmailAllowed
|
|
485
470
|
* @throws Error if sendEmail is not provided
|
|
486
471
|
* @example
|
|
487
|
-
* initSessionAuthFromEnv(
|
|
488
|
-
*
|
|
489
|
-
*
|
|
490
|
-
*
|
|
472
|
+
* initSessionAuthFromEnv({
|
|
473
|
+
* sendEmail: async (to, magicLink) => {
|
|
474
|
+
* await resend.emails.send({ to, html: `<a href="${magicLink}">Sign In</a>` });
|
|
475
|
+
* return true;
|
|
476
|
+
* },
|
|
477
|
+
* isEmailAllowed: async (email) => lookupInDatabase(email),
|
|
478
|
+
* });
|
|
491
479
|
*/
|
|
492
|
-
export declare function initSessionAuthFromEnv(
|
|
480
|
+
export declare function initSessionAuthFromEnv(config: {
|
|
481
|
+
sendEmail: (to: string, magicLink: string) => Promise<boolean>;
|
|
482
|
+
/** Additional email validation. Called after built-in domain/admin checks reject.
|
|
483
|
+
* Can only widen access, never narrow it. */
|
|
484
|
+
isEmailAllowed?: (email: string) => boolean | Promise<boolean>;
|
|
485
|
+
}): void;
|
|
493
486
|
/**
|
|
494
487
|
* Parses cookies from a request's Cookie header.
|
|
495
488
|
* @param request - Request object with headers.get() method
|
|
@@ -582,37 +575,37 @@ export declare function verifyMagicLink(token: string): Promise<Result<{
|
|
|
582
575
|
* Validates a session cookie and returns the user and session info.
|
|
583
576
|
* Performs sliding window refresh if the session is close to expiry.
|
|
584
577
|
* @param request - Request object with headers.get() method
|
|
585
|
-
* @returns
|
|
578
|
+
* @returns Result with user, session, and optional refreshed cookie
|
|
586
579
|
* @example
|
|
587
580
|
* const result = await validateSession(request);
|
|
588
|
-
* if (!result) return unauthorizedResponse();
|
|
581
|
+
* if (!result.ok) return unauthorizedResponse();
|
|
589
582
|
*/
|
|
590
583
|
export declare function validateSession(request: {
|
|
591
584
|
headers: {
|
|
592
585
|
get(name: string): string | null;
|
|
593
586
|
};
|
|
594
|
-
}): Promise<{
|
|
587
|
+
}): Promise<Result<{
|
|
595
588
|
user: SessionUser;
|
|
596
589
|
session: SessionInfo;
|
|
597
590
|
refreshedCookie?: string;
|
|
598
|
-
}
|
|
591
|
+
}>>;
|
|
599
592
|
/**
|
|
600
593
|
* Convenience function: validates session and returns user with optional refresh headers.
|
|
601
594
|
* @param request - Request object with headers.get() method
|
|
602
|
-
* @returns
|
|
595
|
+
* @returns Result with user and optional Set-Cookie headers
|
|
603
596
|
* @example
|
|
604
597
|
* const result = await getSessionUser(request);
|
|
605
|
-
* if (!result) return
|
|
606
|
-
*
|
|
598
|
+
* if (!result.ok) return resultToResponse(result);
|
|
599
|
+
* const { user, headers } = result.data!;
|
|
607
600
|
*/
|
|
608
601
|
export declare function getSessionUser(request: {
|
|
609
602
|
headers: {
|
|
610
603
|
get(name: string): string | null;
|
|
611
604
|
};
|
|
612
|
-
}): Promise<{
|
|
605
|
+
}): Promise<Result<{
|
|
613
606
|
user: SessionUser;
|
|
614
607
|
headers?: Record<string, string>;
|
|
615
|
-
}
|
|
608
|
+
}>>;
|
|
616
609
|
/**
|
|
617
610
|
* Destroys the current session and returns a logout cookie string.
|
|
618
611
|
* @param request - Request object with headers.get() method
|
|
@@ -676,4 +669,41 @@ export declare function deleteExpiredSessions(): Promise<number>;
|
|
|
676
669
|
* context.log(`Cleaned up ${deleted} expired magic links`);
|
|
677
670
|
*/
|
|
678
671
|
export declare function deleteExpiredMagicLinks(): Promise<number>;
|
|
672
|
+
/**
|
|
673
|
+
* Checks if any environment variables contain Key Vault references.
|
|
674
|
+
* Useful for skipping resolution in development environments.
|
|
675
|
+
* @returns True if any env vars match the @Microsoft.KeyVault pattern
|
|
676
|
+
* @example
|
|
677
|
+
* if (hasKeyVaultReferences()) {
|
|
678
|
+
* await resolveKeyVaultReferences();
|
|
679
|
+
* }
|
|
680
|
+
*/
|
|
681
|
+
export declare function hasKeyVaultReferences(): boolean;
|
|
682
|
+
/**
|
|
683
|
+
* Resolves all @Microsoft.KeyVault(SecretUri=...) references in process.env.
|
|
684
|
+
* Replaces env var values in-place with the resolved secret values.
|
|
685
|
+
* Uses DefaultAzureCredential for authentication (managed identity in Azure, az cli locally).
|
|
686
|
+
*
|
|
687
|
+
* Requires @azure/keyvault-secrets as a peer dependency.
|
|
688
|
+
*
|
|
689
|
+
* @returns Number of secrets resolved
|
|
690
|
+
* @throws Error if any secret resolution fails (fail-fast)
|
|
691
|
+
* @example
|
|
692
|
+
* // In sessionAuthInit.ts (before any other initialization):
|
|
693
|
+
* if (hasKeyVaultReferences()) {
|
|
694
|
+
* const count = await resolveKeyVaultReferences();
|
|
695
|
+
* console.log(`Resolved ${count} Key Vault secrets`);
|
|
696
|
+
* }
|
|
697
|
+
*/
|
|
698
|
+
export declare function resolveKeyVaultReferences(): Promise<number>;
|
|
699
|
+
/**
|
|
700
|
+
* Convert a failed Result to an HttpResponseInit.
|
|
701
|
+
* Use after checking `!result.ok` to return the error as an HTTP response.
|
|
702
|
+
* @param result - A failed Result (ok=false)
|
|
703
|
+
* @returns HttpResponseInit with the error status and message
|
|
704
|
+
* @example
|
|
705
|
+
* const auth = requireAuth<UsernameTokenPayload>(authHeader);
|
|
706
|
+
* if (!auth.ok) return resultToResponse(auth);
|
|
707
|
+
*/
|
|
708
|
+
export declare function resultToResponse(result: Result<unknown>): HttpResponseInit;
|
|
679
709
|
export { Result, ok, okVoid, err, getErrorMessage, BaseJwtPayload, UserTokenPayload, UsernameTokenPayload, RoleTokenPayload, hasUsername, hasRole, isAdmin, HTTP_STATUS, HttpStatus, ErrorResponse, SessionUser, SessionInfo, MagicLinkRequest, SessionAuthResponse } from './shared';
|