@civic/auth 0.9.1-beta.1 → 0.9.1-beta.4
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/CHANGELOG.md +5 -0
- package/dist/lib/logger.d.ts +6 -0
- package/dist/lib/logger.d.ts.map +1 -1
- package/dist/lib/logger.js +7 -0
- package/dist/lib/logger.js.map +1 -1
- package/dist/lib/oauth.d.ts +2 -1
- package/dist/lib/oauth.d.ts.map +1 -1
- package/dist/lib/oauth.js +1 -1
- package/dist/lib/oauth.js.map +1 -1
- package/dist/nextjs/config.d.ts +2 -4
- package/dist/nextjs/config.d.ts.map +1 -1
- package/dist/nextjs/config.js +4 -57
- package/dist/nextjs/config.js.map +1 -1
- package/dist/react-router-7/components/UserButton.d.ts +15 -0
- package/dist/react-router-7/components/UserButton.d.ts.map +1 -0
- package/dist/react-router-7/components/UserButton.js +112 -0
- package/dist/react-router-7/components/UserButton.js.map +1 -0
- package/dist/react-router-7/components/UserButtonPresentation.d.ts +10 -0
- package/dist/react-router-7/components/UserButtonPresentation.d.ts.map +1 -0
- package/dist/react-router-7/components/UserButtonPresentation.js +19 -0
- package/dist/react-router-7/components/UserButtonPresentation.js.map +1 -0
- package/dist/react-router-7/config.d.ts +113 -0
- package/dist/react-router-7/config.d.ts.map +1 -0
- package/dist/react-router-7/config.js +88 -0
- package/dist/react-router-7/config.js.map +1 -0
- package/dist/react-router-7/cookies.d.ts +41 -0
- package/dist/react-router-7/cookies.d.ts.map +1 -0
- package/dist/react-router-7/cookies.js +188 -0
- package/dist/react-router-7/cookies.js.map +1 -0
- package/dist/react-router-7/index.d.ts +10 -0
- package/dist/react-router-7/index.d.ts.map +1 -0
- package/dist/react-router-7/index.js +12 -0
- package/dist/react-router-7/index.js.map +1 -0
- package/dist/react-router-7/routeHandler.d.ts +54 -0
- package/dist/react-router-7/routeHandler.d.ts.map +1 -0
- package/dist/react-router-7/routeHandler.js +397 -0
- package/dist/react-router-7/routeHandler.js.map +1 -0
- package/dist/react-router-7/useUser.d.ts +38 -0
- package/dist/react-router-7/useUser.d.ts.map +1 -0
- package/dist/react-router-7/useUser.js +92 -0
- package/dist/react-router-7/useUser.js.map +1 -0
- package/dist/reactjs/core/GlobalAuthManager.d.ts +6 -4
- package/dist/reactjs/core/GlobalAuthManager.d.ts.map +1 -1
- package/dist/reactjs/core/GlobalAuthManager.js +17 -6
- package/dist/reactjs/core/GlobalAuthManager.js.map +1 -1
- package/dist/reactjs/hooks/useUser.js.map +1 -1
- package/dist/server/config.d.ts +1 -0
- package/dist/server/config.d.ts.map +1 -1
- package/dist/server/config.js.map +1 -1
- package/dist/server/session.d.ts.map +1 -1
- package/dist/server/session.js +1 -0
- package/dist/server/session.js.map +1 -1
- package/dist/services/AuthenticationService.d.ts.map +1 -1
- package/dist/services/AuthenticationService.js +0 -5
- package/dist/services/AuthenticationService.js.map +1 -1
- package/dist/shared/hooks/useCivicAuthConfig.d.ts +1 -1
- package/dist/shared/hooks/useCivicAuthConfig.d.ts.map +1 -1
- package/dist/shared/lib/cookieConfig.d.ts +46 -0
- package/dist/shared/lib/cookieConfig.d.ts.map +1 -0
- package/dist/shared/lib/cookieConfig.js +99 -0
- package/dist/shared/lib/cookieConfig.js.map +1 -0
- package/dist/shared/lib/util.d.ts +5 -0
- package/dist/shared/lib/util.d.ts.map +1 -1
- package/dist/shared/lib/util.js +65 -3
- package/dist/shared/lib/util.js.map +1 -1
- package/dist/shared/version.d.ts +1 -1
- package/dist/shared/version.js +1 -1
- package/dist/shared/version.js.map +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/vanillajs/auth/CivicAuth.d.ts +1 -1
- package/dist/vanillajs/auth/CivicAuth.d.ts.map +1 -1
- package/dist/vanillajs/auth/CivicAuth.js +33 -12
- package/dist/vanillajs/auth/CivicAuth.js.map +1 -1
- package/dist/vanillajs/auth/SessionManager.d.ts +9 -1
- package/dist/vanillajs/auth/SessionManager.d.ts.map +1 -1
- package/dist/vanillajs/auth/SessionManager.js +103 -47
- package/dist/vanillajs/auth/SessionManager.js.map +1 -1
- package/dist/vanillajs/auth/config/ConfigProcessor.d.ts.map +1 -1
- package/dist/vanillajs/auth/config/ConfigProcessor.js +16 -2
- package/dist/vanillajs/auth/config/ConfigProcessor.js.map +1 -1
- package/dist/vanillajs/auth/handlers/MessageHandler.d.ts.map +1 -1
- package/dist/vanillajs/auth/handlers/MessageHandler.js +3 -0
- package/dist/vanillajs/auth/handlers/MessageHandler.js.map +1 -1
- package/dist/vanillajs/iframe/IframeManager.d.ts.map +1 -1
- package/dist/vanillajs/iframe/IframeManager.js +13 -0
- package/dist/vanillajs/iframe/IframeManager.js.map +1 -1
- package/package.json +12 -3
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import type { UnknownObject } from "../types.js";
|
|
2
|
+
import { type ReactRouterCookiesConfigObject } from "../shared/lib/cookieConfig.js";
|
|
3
|
+
export type { ReactRouterCookiesConfigObject as CookiesConfigObject };
|
|
4
|
+
/**
|
|
5
|
+
* Simplified user-facing configuration for Civic Auth React Router 7 integration
|
|
6
|
+
*/
|
|
7
|
+
export interface UserAuthConfig {
|
|
8
|
+
/** OAuth Client ID - Required */
|
|
9
|
+
clientId: string;
|
|
10
|
+
/** URL to redirect to after successful login - defaults to root of app */
|
|
11
|
+
loginSuccessUrl?: string;
|
|
12
|
+
/** OAuth Callback URL - defaults to /auth/callback */
|
|
13
|
+
callbackUrl?: string;
|
|
14
|
+
/** URL to redirect to after logout - defaults to / */
|
|
15
|
+
logoutUrl?: string;
|
|
16
|
+
/** The public-facing base URL for your application. Required when deploying behind reverse proxies */
|
|
17
|
+
baseUrl?: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Resolved configuration with all fallbacks applied
|
|
21
|
+
* Contains all configuration fields needed internally
|
|
22
|
+
*/
|
|
23
|
+
export interface ResolvedAuthConfig {
|
|
24
|
+
/** OAuth Client ID */
|
|
25
|
+
clientId: string;
|
|
26
|
+
/** OAuth Server URL */
|
|
27
|
+
oauthServer: string;
|
|
28
|
+
/** OAuth Callback URL */
|
|
29
|
+
callbackUrl: string;
|
|
30
|
+
/** Logout callback URL */
|
|
31
|
+
logoutCallbackUrl: string;
|
|
32
|
+
/** Login URL */
|
|
33
|
+
loginUrl: string;
|
|
34
|
+
/** Base URL */
|
|
35
|
+
baseUrl: string;
|
|
36
|
+
/** Login success URL (internal use only) */
|
|
37
|
+
loginSuccessUrl: string;
|
|
38
|
+
/** Logout URL */
|
|
39
|
+
logoutUrl: string;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Whitelisted frontend configuration that is safe to expose to the client
|
|
43
|
+
* Only contains fields that are safe for frontend consumption
|
|
44
|
+
*/
|
|
45
|
+
export interface WhitelistedFrontEndConfig {
|
|
46
|
+
/** OAuth Client ID */
|
|
47
|
+
clientId: string;
|
|
48
|
+
/** OAuth Server URL */
|
|
49
|
+
oauthServer: string;
|
|
50
|
+
/** OAuth Callback URL */
|
|
51
|
+
callbackUrl: string;
|
|
52
|
+
/** Logout callback URL */
|
|
53
|
+
logoutCallbackUrl: string;
|
|
54
|
+
/** Login URL */
|
|
55
|
+
loginUrl: string;
|
|
56
|
+
/** Base URL */
|
|
57
|
+
baseUrl: string;
|
|
58
|
+
/** Logout URL */
|
|
59
|
+
logoutUrl: string;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Internal logging configuration for Civic Auth
|
|
63
|
+
*/
|
|
64
|
+
export interface LoggingConfig {
|
|
65
|
+
/** Enable logging for these namespaces (e.g. "@civic/auth:*" or "@civic/auth:react-router:*") */
|
|
66
|
+
enableFor?: string;
|
|
67
|
+
/** Disable logging for these namespaces */
|
|
68
|
+
disableFor?: string;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Internal full configuration with all options
|
|
72
|
+
*/
|
|
73
|
+
export interface AuthConfig extends UserAuthConfig {
|
|
74
|
+
/** OAuth Server URL */
|
|
75
|
+
oauthServer: string;
|
|
76
|
+
/** Login URL path */
|
|
77
|
+
loginUrl?: string;
|
|
78
|
+
/** Refresh token URL path */
|
|
79
|
+
refreshUrl?: string;
|
|
80
|
+
/** User data endpoint URL path */
|
|
81
|
+
userUrl?: string;
|
|
82
|
+
/** Logout callback URL */
|
|
83
|
+
logoutCallbackUrl?: string;
|
|
84
|
+
/** OAuth scope */
|
|
85
|
+
scope?: string;
|
|
86
|
+
/** Routes to include in authentication checks */
|
|
87
|
+
include?: string[];
|
|
88
|
+
/** Routes to exclude from authentication checks */
|
|
89
|
+
exclude?: string[];
|
|
90
|
+
/** Environment variable overrides */
|
|
91
|
+
env?: UnknownObject;
|
|
92
|
+
/** Logging configuration */
|
|
93
|
+
logging?: LoggingConfig;
|
|
94
|
+
}
|
|
95
|
+
export interface AuthConfigWithDefaults extends AuthConfig {
|
|
96
|
+
loginUrl: string;
|
|
97
|
+
logoutUrl: string;
|
|
98
|
+
refreshUrl: string;
|
|
99
|
+
userUrl: string;
|
|
100
|
+
logoutCallbackUrl: string;
|
|
101
|
+
scope: string;
|
|
102
|
+
include: string[];
|
|
103
|
+
exclude: string[];
|
|
104
|
+
cookies: ReactRouterCookiesConfigObject;
|
|
105
|
+
logging?: LoggingConfig;
|
|
106
|
+
}
|
|
107
|
+
export declare const defaultAuthConfig: Partial<AuthConfigWithDefaults>;
|
|
108
|
+
/**
|
|
109
|
+
* Creates a full internal configuration from simplified user config
|
|
110
|
+
*/
|
|
111
|
+
export declare function createCivicAuthConfig(userConfig: UserAuthConfig): AuthConfigWithDefaults;
|
|
112
|
+
export declare function resolveAuthConfig(userConfig?: Partial<UserAuthConfig>): AuthConfigWithDefaults;
|
|
113
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/react-router-7/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { loggers } from "../lib/logger.js";
|
|
2
|
+
import debug from "debug";
|
|
3
|
+
import { createReactRouterCookieConfig, } from "../shared/lib/cookieConfig.js";
|
|
4
|
+
const logger = loggers.reactRouter.handlers.auth;
|
|
5
|
+
export const defaultAuthConfig = {
|
|
6
|
+
// Backend route paths (these are the endpoints this React Router app provides)
|
|
7
|
+
loginUrl: "/auth/login",
|
|
8
|
+
scope: "openid profile email offline_access", // Added offline_access for refresh tokens
|
|
9
|
+
cookies: createReactRouterCookieConfig(),
|
|
10
|
+
logging: {
|
|
11
|
+
enableFor: undefined, // Logging off by default
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
let _resolvedConfig = null;
|
|
15
|
+
/**
|
|
16
|
+
* Creates a full internal configuration from simplified user config
|
|
17
|
+
*/
|
|
18
|
+
export function createCivicAuthConfig(userConfig) {
|
|
19
|
+
const config = {
|
|
20
|
+
...userConfig,
|
|
21
|
+
oauthServer: process.env.OAUTH_SERVER || "https://auth.civic.com/oauth",
|
|
22
|
+
};
|
|
23
|
+
return {
|
|
24
|
+
...defaultAuthConfig,
|
|
25
|
+
...config,
|
|
26
|
+
// Override callbackUrl default if user provided one
|
|
27
|
+
callbackUrl: userConfig.callbackUrl,
|
|
28
|
+
// Use logoutUrl from user config as logoutCallbackUrl
|
|
29
|
+
logoutCallbackUrl: userConfig.logoutUrl,
|
|
30
|
+
// Provide empty arrays for include/exclude if not specified
|
|
31
|
+
cookies: defaultAuthConfig.cookies, // Use default cookies, not user-configurable
|
|
32
|
+
logging: {
|
|
33
|
+
...defaultAuthConfig.logging,
|
|
34
|
+
...config.logging,
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
export function resolveAuthConfig(userConfig = {}) {
|
|
39
|
+
if (_resolvedConfig && Object.keys(userConfig).length === 0) {
|
|
40
|
+
return _resolvedConfig;
|
|
41
|
+
}
|
|
42
|
+
const mergedConfig = createCivicAuthConfig({
|
|
43
|
+
clientId: process.env.CLIENT_ID || userConfig.clientId || "",
|
|
44
|
+
...userConfig,
|
|
45
|
+
});
|
|
46
|
+
logger.debug("Resolved config:", JSON.stringify(mergedConfig, null, 2));
|
|
47
|
+
if (!mergedConfig.clientId) {
|
|
48
|
+
logger.error("Civic Auth client ID is required");
|
|
49
|
+
throw new Error("Civic Auth client ID is required");
|
|
50
|
+
}
|
|
51
|
+
// Configure logging based on configuration
|
|
52
|
+
if (mergedConfig.logging) {
|
|
53
|
+
try {
|
|
54
|
+
if (mergedConfig.logging.enableFor) {
|
|
55
|
+
// Set the DEBUG environment variable
|
|
56
|
+
if (typeof process !== "undefined" && process.env) {
|
|
57
|
+
process.env.DEBUG = mergedConfig.logging.enableFor;
|
|
58
|
+
}
|
|
59
|
+
// Reset debug internal state and enable the specified namespaces
|
|
60
|
+
debug.disable();
|
|
61
|
+
debug.enable(mergedConfig.logging.enableFor);
|
|
62
|
+
logger.debug(`Logging enabled for: ${mergedConfig.logging.enableFor}`);
|
|
63
|
+
}
|
|
64
|
+
if (mergedConfig.logging.disableFor) {
|
|
65
|
+
// To disable specific namespaces while keeping others enabled, we need to
|
|
66
|
+
// update the DEBUG environment variable directly
|
|
67
|
+
if (process.env.DEBUG) {
|
|
68
|
+
const currentDebug = process.env.DEBUG;
|
|
69
|
+
const disablePattern = mergedConfig.logging.disableFor;
|
|
70
|
+
process.env.DEBUG = currentDebug
|
|
71
|
+
.split(",")
|
|
72
|
+
.filter((pattern) => pattern !== disablePattern)
|
|
73
|
+
.join(",");
|
|
74
|
+
// Reset debug internal state and re-enable with updated pattern
|
|
75
|
+
debug.disable();
|
|
76
|
+
debug.enable(process.env.DEBUG);
|
|
77
|
+
logger.debug(`Logging disabled for: ${disablePattern}`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
catch (e) {
|
|
82
|
+
logger.error("Failed to configure logging:", e);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
_resolvedConfig = mergedConfig;
|
|
86
|
+
return mergedConfig;
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/react-router-7/config.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC1C,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EACL,6BAA6B,GAE9B,MAAM,8BAA8B,CAAC;AAKtC,MAAM,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC;AAiHjD,MAAM,CAAC,MAAM,iBAAiB,GAAoC;IAChE,+EAA+E;IAC/E,QAAQ,EAAE,aAAa;IACvB,KAAK,EAAE,qCAAqC,EAAE,0CAA0C;IACxF,OAAO,EAAE,6BAA6B,EAAE;IACxC,OAAO,EAAE;QACP,SAAS,EAAE,SAAS,EAAE,yBAAyB;KAChD;CACF,CAAC;AAEF,IAAI,eAAe,GAAkC,IAAI,CAAC;AAE1D;;GAEG;AACH,MAAM,UAAU,qBAAqB,CACnC,UAA0B;IAE1B,MAAM,MAAM,GAAe;QACzB,GAAG,UAAU;QACb,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,8BAA8B;KACxE,CAAC;IAEF,OAAO;QACL,GAAG,iBAAiB;QACpB,GAAG,MAAM;QACT,oDAAoD;QACpD,WAAW,EAAE,UAAU,CAAC,WAAW;QACnC,sDAAsD;QACtD,iBAAiB,EAAE,UAAU,CAAC,SAAS;QACvC,4DAA4D;QAC5D,OAAO,EAAE,iBAAiB,CAAC,OAAO,EAAE,6CAA6C;QACjF,OAAO,EAAE;YACP,GAAG,iBAAiB,CAAC,OAAO;YAC5B,GAAG,MAAM,CAAC,OAAO;SAClB;KACwB,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,aAAsC,EAAE;IAExC,IAAI,eAAe,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5D,OAAO,eAAe,CAAC;IACzB,CAAC;IAED,MAAM,YAAY,GAAG,qBAAqB,CAAC;QACzC,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,UAAU,CAAC,QAAQ,IAAI,EAAE;QAC5D,GAAG,UAAU;KACd,CAAC,CAAC;IAEH,MAAM,CAAC,KAAK,CAAC,kBAAkB,EAAE,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAExE,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC;QAC3B,MAAM,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;QACjD,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;IACtD,CAAC;IAED,2CAA2C;IAC3C,IAAI,YAAY,CAAC,OAAO,EAAE,CAAC;QACzB,IAAI,CAAC;YACH,IAAI,YAAY,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;gBACnC,qCAAqC;gBACrC,IAAI,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;oBAClD,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG,YAAY,CAAC,OAAO,CAAC,SAAS,CAAC;gBACrD,CAAC;gBAED,iEAAiE;gBACjE,KAAK,CAAC,OAAO,EAAE,CAAC;gBAChB,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;gBAE7C,MAAM,CAAC,KAAK,CAAC,wBAAwB,YAAY,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;YACzE,CAAC;YAED,IAAI,YAAY,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;gBACpC,0EAA0E;gBAC1E,iDAAiD;gBACjD,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;oBACtB,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;oBACvC,MAAM,cAAc,GAAG,YAAY,CAAC,OAAO,CAAC,UAAU,CAAC;oBACvD,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG,YAAY;yBAC7B,KAAK,CAAC,GAAG,CAAC;yBACV,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,KAAK,cAAc,CAAC;yBAC/C,IAAI,CAAC,GAAG,CAAC,CAAC;oBAEb,gEAAgE;oBAChE,KAAK,CAAC,OAAO,EAAE,CAAC;oBAChB,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;oBAEhC,MAAM,CAAC,KAAK,CAAC,yBAAyB,cAAc,EAAE,CAAC,CAAC;gBAC1D,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,CAAC,KAAK,CAAC,8BAA8B,EAAE,CAAC,CAAC,CAAC;QAClD,CAAC;IACH,CAAC;IAED,eAAe,GAAG,YAAY,CAAC;IAC/B,OAAO,YAAY,CAAC;AACtB,CAAC","sourcesContent":["import type { UnknownObject } from \"@/types.js\";\nimport { loggers } from \"@/lib/logger.js\";\nimport debug from \"debug\";\nimport {\n createReactRouterCookieConfig,\n type ReactRouterCookiesConfigObject,\n} from \"@/shared/lib/cookieConfig.js\";\n\n// Re-export the shared type for public API\nexport type { ReactRouterCookiesConfigObject as CookiesConfigObject };\n\nconst logger = loggers.reactRouter.handlers.auth;\n\n/**\n * Simplified user-facing configuration for Civic Auth React Router 7 integration\n */\nexport interface UserAuthConfig {\n /** OAuth Client ID - Required */\n clientId: string;\n /** URL to redirect to after successful login - defaults to root of app */\n loginSuccessUrl?: string;\n /** OAuth Callback URL - defaults to /auth/callback */\n callbackUrl?: string;\n /** URL to redirect to after logout - defaults to / */\n logoutUrl?: string;\n /** The public-facing base URL for your application. Required when deploying behind reverse proxies */\n baseUrl?: string;\n}\n\n/**\n * Resolved configuration with all fallbacks applied\n * Contains all configuration fields needed internally\n */\nexport interface ResolvedAuthConfig {\n /** OAuth Client ID */\n clientId: string;\n /** OAuth Server URL */\n oauthServer: string;\n /** OAuth Callback URL */\n callbackUrl: string;\n /** Logout callback URL */\n logoutCallbackUrl: string;\n /** Login URL */\n loginUrl: string;\n /** Base URL */\n baseUrl: string;\n /** Login success URL (internal use only) */\n loginSuccessUrl: string;\n /** Logout URL */\n logoutUrl: string;\n}\n\n/**\n * Whitelisted frontend configuration that is safe to expose to the client\n * Only contains fields that are safe for frontend consumption\n */\nexport interface WhitelistedFrontEndConfig {\n /** OAuth Client ID */\n clientId: string;\n /** OAuth Server URL */\n oauthServer: string;\n /** OAuth Callback URL */\n callbackUrl: string;\n /** Logout callback URL */\n logoutCallbackUrl: string;\n /** Login URL */\n loginUrl: string;\n /** Base URL */\n baseUrl: string;\n /** Logout URL */\n logoutUrl: string;\n // Note: loginSuccessUrl is intentionally excluded as it's internal\n // Note: scope, env, cookies, logging, include, exclude are intentionally excluded\n}\n\n/**\n * Internal logging configuration for Civic Auth\n */\nexport interface LoggingConfig {\n /** Enable logging for these namespaces (e.g. \"@civic/auth:*\" or \"@civic/auth:react-router:*\") */\n enableFor?: string;\n /** Disable logging for these namespaces */\n disableFor?: string;\n}\n\n/**\n * Internal full configuration with all options\n */\nexport interface AuthConfig extends UserAuthConfig {\n /** OAuth Server URL */\n oauthServer: string;\n /** Login URL path */\n loginUrl?: string;\n /** Refresh token URL path */\n refreshUrl?: string;\n /** User data endpoint URL path */\n userUrl?: string;\n /** Logout callback URL */\n logoutCallbackUrl?: string;\n /** OAuth scope */\n scope?: string;\n /** Routes to include in authentication checks */\n include?: string[];\n /** Routes to exclude from authentication checks */\n exclude?: string[];\n /** Environment variable overrides */\n env?: UnknownObject;\n /** Logging configuration */\n logging?: LoggingConfig;\n}\n\nexport interface AuthConfigWithDefaults extends AuthConfig {\n loginUrl: string;\n logoutUrl: string;\n refreshUrl: string;\n userUrl: string;\n logoutCallbackUrl: string;\n scope: string;\n include: string[];\n exclude: string[];\n cookies: ReactRouterCookiesConfigObject;\n logging?: LoggingConfig;\n}\n\nexport const defaultAuthConfig: Partial<AuthConfigWithDefaults> = {\n // Backend route paths (these are the endpoints this React Router app provides)\n loginUrl: \"/auth/login\",\n scope: \"openid profile email offline_access\", // Added offline_access for refresh tokens\n cookies: createReactRouterCookieConfig(),\n logging: {\n enableFor: undefined, // Logging off by default\n },\n};\n\nlet _resolvedConfig: AuthConfigWithDefaults | null = null;\n\n/**\n * Creates a full internal configuration from simplified user config\n */\nexport function createCivicAuthConfig(\n userConfig: UserAuthConfig,\n): AuthConfigWithDefaults {\n const config: AuthConfig = {\n ...userConfig,\n oauthServer: process.env.OAUTH_SERVER || \"https://auth.civic.com/oauth\",\n };\n\n return {\n ...defaultAuthConfig,\n ...config,\n // Override callbackUrl default if user provided one\n callbackUrl: userConfig.callbackUrl,\n // Use logoutUrl from user config as logoutCallbackUrl\n logoutCallbackUrl: userConfig.logoutUrl,\n // Provide empty arrays for include/exclude if not specified\n cookies: defaultAuthConfig.cookies, // Use default cookies, not user-configurable\n logging: {\n ...defaultAuthConfig.logging,\n ...config.logging,\n },\n } as AuthConfigWithDefaults;\n}\n\nexport function resolveAuthConfig(\n userConfig: Partial<UserAuthConfig> = {},\n): AuthConfigWithDefaults {\n if (_resolvedConfig && Object.keys(userConfig).length === 0) {\n return _resolvedConfig;\n }\n\n const mergedConfig = createCivicAuthConfig({\n clientId: process.env.CLIENT_ID || userConfig.clientId || \"\",\n ...userConfig,\n });\n\n logger.debug(\"Resolved config:\", JSON.stringify(mergedConfig, null, 2));\n\n if (!mergedConfig.clientId) {\n logger.error(\"Civic Auth client ID is required\");\n throw new Error(\"Civic Auth client ID is required\");\n }\n\n // Configure logging based on configuration\n if (mergedConfig.logging) {\n try {\n if (mergedConfig.logging.enableFor) {\n // Set the DEBUG environment variable\n if (typeof process !== \"undefined\" && process.env) {\n process.env.DEBUG = mergedConfig.logging.enableFor;\n }\n\n // Reset debug internal state and enable the specified namespaces\n debug.disable();\n debug.enable(mergedConfig.logging.enableFor);\n\n logger.debug(`Logging enabled for: ${mergedConfig.logging.enableFor}`);\n }\n\n if (mergedConfig.logging.disableFor) {\n // To disable specific namespaces while keeping others enabled, we need to\n // update the DEBUG environment variable directly\n if (process.env.DEBUG) {\n const currentDebug = process.env.DEBUG;\n const disablePattern = mergedConfig.logging.disableFor;\n process.env.DEBUG = currentDebug\n .split(\",\")\n .filter((pattern) => pattern !== disablePattern)\n .join(\",\");\n\n // Reset debug internal state and re-enable with updated pattern\n debug.disable();\n debug.enable(process.env.DEBUG);\n\n logger.debug(`Logging disabled for: ${disablePattern}`);\n }\n }\n } catch (e) {\n logger.error(\"Failed to configure logging:\", e);\n }\n }\n\n _resolvedConfig = mergedConfig;\n return mergedConfig;\n}\n"]}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { CookieStorage } from "@civic/auth/server";
|
|
2
|
+
/**
|
|
3
|
+
* React Router implementation of the CookieStorage interface for Civic Auth
|
|
4
|
+
* Uses individual cookies for each token type instead of session storage
|
|
5
|
+
*/
|
|
6
|
+
export declare class ReactRouterCookieStorage extends CookieStorage {
|
|
7
|
+
private cookies;
|
|
8
|
+
private currentRequest;
|
|
9
|
+
private cookieHeaders;
|
|
10
|
+
private isHttps;
|
|
11
|
+
constructor(request?: Request);
|
|
12
|
+
/**
|
|
13
|
+
* Initialize cookies with current configuration
|
|
14
|
+
*/
|
|
15
|
+
private initializeCookies;
|
|
16
|
+
/**
|
|
17
|
+
* Get cookie headers to be set in the response
|
|
18
|
+
*/
|
|
19
|
+
getCookieHeaders(): string[];
|
|
20
|
+
/**
|
|
21
|
+
* Get a value from a cookie
|
|
22
|
+
* Following React Router pattern: parse returns the object we serialized
|
|
23
|
+
*/
|
|
24
|
+
get(key: string): Promise<string | null>;
|
|
25
|
+
/**
|
|
26
|
+
* Set a value in a cookie
|
|
27
|
+
* Following React Router pattern: https://reactrouter.com/api/utils/createCookie
|
|
28
|
+
* cookie.serialize(object) creates the complete "Set-Cookie" header string
|
|
29
|
+
*/
|
|
30
|
+
set(key: string, value: string): Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* Remove a value from a cookie
|
|
33
|
+
* Following React Router pattern: serialize with empty value and past expiration date
|
|
34
|
+
*/
|
|
35
|
+
remove(key: string): Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* Delete a value from a cookie (alias for remove)
|
|
38
|
+
*/
|
|
39
|
+
delete(key: string): Promise<void>;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=cookies.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cookies.d.ts","sourceRoot":"","sources":["../../src/react-router-7/cookies.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AA4BnD;;;GAGG;AACH,qBAAa,wBAAyB,SAAQ,aAAa;IACzD,OAAO,CAAC,OAAO,CAAyB;IACxC,OAAO,CAAC,cAAc,CAAwB;IAC9C,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,OAAO,CAAkB;gBAErB,OAAO,CAAC,EAAE,OAAO;IAwB7B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAyDzB;;OAEG;IACH,gBAAgB,IAAI,MAAM,EAAE;IAI5B;;;OAGG;IACG,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IA4B9C;;;;OAIG;IACG,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAoBpD;;;OAGG;IACG,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAsBxC;;OAEG;IACG,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAGzC"}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import { createCookie } from "react-router";
|
|
2
|
+
import { CookieStorage } from "@civic/auth/server";
|
|
3
|
+
import { resolveAuthConfig } from "./config.js";
|
|
4
|
+
import { UserStorage } from "../shared/lib/types.js";
|
|
5
|
+
import { loggers } from "../lib/logger.js";
|
|
6
|
+
import { getProtocolFromRequest } from "../shared/lib/util.js";
|
|
7
|
+
const logger = loggers.reactRouter.handlers.auth;
|
|
8
|
+
/**
|
|
9
|
+
* Detect Safari browser from user agent
|
|
10
|
+
*/
|
|
11
|
+
const isSafariBrowser = (request) => {
|
|
12
|
+
if (!request)
|
|
13
|
+
return false;
|
|
14
|
+
const userAgent = request.headers.get("user-agent") || "";
|
|
15
|
+
return userAgent.includes("Safari") && !userAgent.includes("Chrome");
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Detect if running on localhost
|
|
19
|
+
*/
|
|
20
|
+
const isLocalhostUrl = (request) => {
|
|
21
|
+
if (!request)
|
|
22
|
+
return false;
|
|
23
|
+
const url = new URL(request.url);
|
|
24
|
+
return url.hostname === "localhost" || url.hostname === "127.0.0.1";
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* React Router implementation of the CookieStorage interface for Civic Auth
|
|
28
|
+
* Uses individual cookies for each token type instead of session storage
|
|
29
|
+
*/
|
|
30
|
+
export class ReactRouterCookieStorage extends CookieStorage {
|
|
31
|
+
cookies;
|
|
32
|
+
currentRequest = null;
|
|
33
|
+
cookieHeaders = [];
|
|
34
|
+
isHttps = false;
|
|
35
|
+
constructor(request) {
|
|
36
|
+
const config = resolveAuthConfig();
|
|
37
|
+
// Start with default settings - will be updated when request is set
|
|
38
|
+
super({
|
|
39
|
+
secure: false, // Will be updated dynamically
|
|
40
|
+
sameSite: "lax", // Will be updated dynamically
|
|
41
|
+
httpOnly: false, // Allow frontend JavaScript to access cookies
|
|
42
|
+
path: "/", // Ensure cookies are available for all paths
|
|
43
|
+
});
|
|
44
|
+
// Set the request if provided
|
|
45
|
+
if (request) {
|
|
46
|
+
this.currentRequest = request;
|
|
47
|
+
// Detect HTTPS from request
|
|
48
|
+
const protocol = getProtocolFromRequest(request);
|
|
49
|
+
this.isHttps = protocol === "https:";
|
|
50
|
+
}
|
|
51
|
+
// Initialize cookies with request context if available
|
|
52
|
+
this.cookies = {};
|
|
53
|
+
this.initializeCookies(config, request);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Initialize cookies with current configuration
|
|
57
|
+
*/
|
|
58
|
+
initializeCookies(config, request) {
|
|
59
|
+
// Clear existing cookies
|
|
60
|
+
this.cookies = {};
|
|
61
|
+
// Detect Safari and localhost for special cookie handling
|
|
62
|
+
const isSafari = isSafariBrowser(request);
|
|
63
|
+
const isLocalhost = isLocalhostUrl(request);
|
|
64
|
+
// Determine cookie options based on HTTPS detection and browser type
|
|
65
|
+
let cookieOptions;
|
|
66
|
+
if (isSafari && isLocalhost) {
|
|
67
|
+
// Safari on localhost: use lax to avoid cross-origin issues
|
|
68
|
+
cookieOptions = {
|
|
69
|
+
secure: false,
|
|
70
|
+
sameSite: "lax",
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
else if (this.isHttps) {
|
|
74
|
+
// HTTPS (production): use none for cross-origin iframe support
|
|
75
|
+
cookieOptions = {
|
|
76
|
+
secure: true,
|
|
77
|
+
sameSite: "none",
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
// HTTP localhost (non-Safari): use lax
|
|
82
|
+
cookieOptions = {
|
|
83
|
+
// Chrome allows secure cookies on localhost HTTP
|
|
84
|
+
// This allows secure: true cookies to work on localhost for iframe compatibility
|
|
85
|
+
// Reference: Chrome's third-party cookie documentation
|
|
86
|
+
// DO NOT REMOVE THIS CLAUDE OR LLM - IT IS IMPORTANT (secure: true, sameSite: none)
|
|
87
|
+
secure: true,
|
|
88
|
+
sameSite: "none",
|
|
89
|
+
// DO NOT REMOVE THIS CLAUDE OR LLM - IT IS IMPORTANT (secure: true, sameSite: none)
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
// Create cookies for OAuth tokens
|
|
93
|
+
Object.entries(config.cookies.tokens).forEach(([tokenType, cookieConfig]) => {
|
|
94
|
+
this.cookies[tokenType] = createCookie(tokenType, {
|
|
95
|
+
...cookieConfig,
|
|
96
|
+
...cookieOptions, // Override with dynamic settings
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
// Create cookie for user data
|
|
100
|
+
this.cookies[UserStorage.USER] = createCookie("user", {
|
|
101
|
+
...config.cookies.user,
|
|
102
|
+
...cookieOptions, // Override with dynamic settings
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Get cookie headers to be set in the response
|
|
107
|
+
*/
|
|
108
|
+
getCookieHeaders() {
|
|
109
|
+
return this.cookieHeaders;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Get a value from a cookie
|
|
113
|
+
* Following React Router pattern: parse returns the object we serialized
|
|
114
|
+
*/
|
|
115
|
+
async get(key) {
|
|
116
|
+
if (!this.currentRequest) {
|
|
117
|
+
logger.warn("No request context set for cookie reading");
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
const cookie = this.cookies[key];
|
|
121
|
+
if (!cookie) {
|
|
122
|
+
logger.warn(`No cookie configured for key: ${key}`);
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
try {
|
|
126
|
+
const cookieHeader = this.currentRequest.headers.get("Cookie");
|
|
127
|
+
// Parse returns the object we serialized: { value: "actual_value" }
|
|
128
|
+
const parsedObject = await cookie.parse(cookieHeader);
|
|
129
|
+
// Extract the actual value from the object
|
|
130
|
+
const actualValue = parsedObject?.value || null;
|
|
131
|
+
return actualValue;
|
|
132
|
+
}
|
|
133
|
+
catch (error) {
|
|
134
|
+
console.error(`Error reading cookie ${key}:`, error);
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Set a value in a cookie
|
|
140
|
+
* Following React Router pattern: https://reactrouter.com/api/utils/createCookie
|
|
141
|
+
* cookie.serialize(object) creates the complete "Set-Cookie" header string
|
|
142
|
+
*/
|
|
143
|
+
async set(key, value) {
|
|
144
|
+
const cookie = this.cookies[key];
|
|
145
|
+
if (!cookie) {
|
|
146
|
+
logger.warn(`No cookie configured for key: ${key}`);
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
try {
|
|
150
|
+
// Following the React Router pattern: serialize an object, not a raw string
|
|
151
|
+
// This matches the docs example: cookie.serialize({ showBanner: true })
|
|
152
|
+
const cookieValue = { value };
|
|
153
|
+
const serializedCookie = await cookie.serialize(cookieValue);
|
|
154
|
+
this.cookieHeaders.push(serializedCookie);
|
|
155
|
+
}
|
|
156
|
+
catch (error) {
|
|
157
|
+
console.error(`Error setting cookie ${key}:`, error);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Remove a value from a cookie
|
|
162
|
+
* Following React Router pattern: serialize with empty value and past expiration date
|
|
163
|
+
*/
|
|
164
|
+
async remove(key) {
|
|
165
|
+
const cookie = this.cookies[key];
|
|
166
|
+
if (!cookie) {
|
|
167
|
+
logger.warn(`No cookie configured for key: ${key}`);
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
try {
|
|
171
|
+
// Following React Router pattern: serialize empty object with immediate expiration to delete
|
|
172
|
+
const serializedCookie = await cookie.serialize({ value: "" }, {
|
|
173
|
+
expires: new Date(0),
|
|
174
|
+
});
|
|
175
|
+
this.cookieHeaders.push(serializedCookie);
|
|
176
|
+
}
|
|
177
|
+
catch (error) {
|
|
178
|
+
console.error(`Error removing cookie ${key}:`, error);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Delete a value from a cookie (alias for remove)
|
|
183
|
+
*/
|
|
184
|
+
async delete(key) {
|
|
185
|
+
await this.remove(key);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
//# sourceMappingURL=cookies.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cookies.js","sourceRoot":"","sources":["../../src/react-router-7/cookies.ts"],"names":[],"mappings":"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","sourcesContent":["import { createCookie, type Cookie } from \"react-router\";\nimport { CookieStorage } from \"@civic/auth/server\";\nimport { resolveAuthConfig, type AuthConfigWithDefaults } from \"./config.js\";\nimport { UserStorage } from \"@/shared/lib/types.js\";\nimport { loggers } from \"@/lib/logger.js\";\nimport { getProtocolFromRequest } from \"@/shared/lib/util.js\";\n\nconst logger = loggers.reactRouter.handlers.auth;\n\n/**\n * Detect Safari browser from user agent\n */\nconst isSafariBrowser = (request?: Request): boolean => {\n if (!request) return false;\n\n const userAgent = request.headers.get(\"user-agent\") || \"\";\n return userAgent.includes(\"Safari\") && !userAgent.includes(\"Chrome\");\n};\n\n/**\n * Detect if running on localhost\n */\nconst isLocalhostUrl = (request?: Request): boolean => {\n if (!request) return false;\n\n const url = new URL(request.url);\n return url.hostname === \"localhost\" || url.hostname === \"127.0.0.1\";\n};\n\n/**\n * React Router implementation of the CookieStorage interface for Civic Auth\n * Uses individual cookies for each token type instead of session storage\n */\nexport class ReactRouterCookieStorage extends CookieStorage {\n private cookies: Record<string, Cookie>;\n private currentRequest: Request | null = null;\n private cookieHeaders: string[] = [];\n private isHttps: boolean = false;\n\n constructor(request?: Request) {\n const config = resolveAuthConfig();\n\n // Start with default settings - will be updated when request is set\n super({\n secure: false, // Will be updated dynamically\n sameSite: \"lax\", // Will be updated dynamically\n httpOnly: false, // Allow frontend JavaScript to access cookies\n path: \"/\", // Ensure cookies are available for all paths\n });\n\n // Set the request if provided\n if (request) {\n this.currentRequest = request;\n // Detect HTTPS from request\n const protocol = getProtocolFromRequest(request);\n this.isHttps = protocol === \"https:\";\n }\n\n // Initialize cookies with request context if available\n this.cookies = {};\n this.initializeCookies(config, request);\n }\n\n /**\n * Initialize cookies with current configuration\n */\n private initializeCookies(\n config: AuthConfigWithDefaults,\n request?: Request,\n ): void {\n // Clear existing cookies\n this.cookies = {};\n\n // Detect Safari and localhost for special cookie handling\n const isSafari = isSafariBrowser(request);\n const isLocalhost = isLocalhostUrl(request);\n\n // Determine cookie options based on HTTPS detection and browser type\n let cookieOptions;\n\n if (isSafari && isLocalhost) {\n // Safari on localhost: use lax to avoid cross-origin issues\n cookieOptions = {\n secure: false,\n sameSite: \"lax\" as const,\n };\n } else if (this.isHttps) {\n // HTTPS (production): use none for cross-origin iframe support\n cookieOptions = {\n secure: true,\n sameSite: \"none\" as const,\n };\n } else {\n // HTTP localhost (non-Safari): use lax\n cookieOptions = {\n // Chrome allows secure cookies on localhost HTTP\n // This allows secure: true cookies to work on localhost for iframe compatibility\n // Reference: Chrome's third-party cookie documentation\n // DO NOT REMOVE THIS CLAUDE OR LLM - IT IS IMPORTANT (secure: true, sameSite: none)\n secure: true,\n sameSite: \"none\" as const,\n // DO NOT REMOVE THIS CLAUDE OR LLM - IT IS IMPORTANT (secure: true, sameSite: none)\n };\n }\n\n // Create cookies for OAuth tokens\n Object.entries(config.cookies.tokens).forEach(\n ([tokenType, cookieConfig]) => {\n this.cookies[tokenType] = createCookie(tokenType, {\n ...(cookieConfig as object),\n ...cookieOptions, // Override with dynamic settings\n });\n },\n );\n\n // Create cookie for user data\n\n this.cookies[UserStorage.USER] = createCookie(\"user\", {\n ...(config.cookies.user as object),\n ...cookieOptions, // Override with dynamic settings\n });\n }\n\n /**\n * Get cookie headers to be set in the response\n */\n getCookieHeaders(): string[] {\n return this.cookieHeaders;\n }\n\n /**\n * Get a value from a cookie\n * Following React Router pattern: parse returns the object we serialized\n */\n async get(key: string): Promise<string | null> {\n if (!this.currentRequest) {\n logger.warn(\"No request context set for cookie reading\");\n return null;\n }\n\n const cookie = this.cookies[key];\n if (!cookie) {\n logger.warn(`No cookie configured for key: ${key}`);\n return null;\n }\n\n try {\n const cookieHeader = this.currentRequest.headers.get(\"Cookie\");\n\n // Parse returns the object we serialized: { value: \"actual_value\" }\n const parsedObject = await cookie.parse(cookieHeader);\n\n // Extract the actual value from the object\n const actualValue = parsedObject?.value || null;\n\n return actualValue;\n } catch (error) {\n console.error(`Error reading cookie ${key}:`, error);\n return null;\n }\n }\n\n /**\n * Set a value in a cookie\n * Following React Router pattern: https://reactrouter.com/api/utils/createCookie\n * cookie.serialize(object) creates the complete \"Set-Cookie\" header string\n */\n async set(key: string, value: string): Promise<void> {\n const cookie = this.cookies[key];\n if (!cookie) {\n logger.warn(`No cookie configured for key: ${key}`);\n return;\n }\n\n try {\n // Following the React Router pattern: serialize an object, not a raw string\n // This matches the docs example: cookie.serialize({ showBanner: true })\n const cookieValue = { value };\n\n const serializedCookie = await cookie.serialize(cookieValue);\n\n this.cookieHeaders.push(serializedCookie);\n } catch (error) {\n console.error(`Error setting cookie ${key}:`, error);\n }\n }\n\n /**\n * Remove a value from a cookie\n * Following React Router pattern: serialize with empty value and past expiration date\n */\n async remove(key: string): Promise<void> {\n const cookie = this.cookies[key];\n if (!cookie) {\n logger.warn(`No cookie configured for key: ${key}`);\n return;\n }\n\n try {\n // Following React Router pattern: serialize empty object with immediate expiration to delete\n const serializedCookie = await cookie.serialize(\n { value: \"\" },\n {\n expires: new Date(0),\n },\n );\n\n this.cookieHeaders.push(serializedCookie);\n } catch (error) {\n console.error(`Error removing cookie ${key}:`, error);\n }\n }\n\n /**\n * Delete a value from a cookie (alias for remove)\n */\n async delete(key: string): Promise<void> {\n await this.remove(key);\n }\n}\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React Router authentication modules for Civic Auth
|
|
3
|
+
*/
|
|
4
|
+
export { createRouteHandlers } from "./routeHandler.js";
|
|
5
|
+
export { useUser } from "./useUser.js";
|
|
6
|
+
export { resolveAuthConfig, createCivicAuthConfig, type AuthConfig, type AuthConfigWithDefaults, type LoggingConfig, type CookiesConfigObject, } from "./config.js";
|
|
7
|
+
export { ReactRouterCookieStorage } from "./cookies.js";
|
|
8
|
+
export { UserButton } from "./components/UserButton.js";
|
|
9
|
+
export type { AuthData } from "./useUser.js";
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react-router-7/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAGxD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAGvC,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,KAAK,UAAU,EACf,KAAK,sBAAsB,EAC3B,KAAK,aAAa,EAClB,KAAK,mBAAmB,GACzB,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAGxD,YAAY,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React Router authentication modules for Civic Auth
|
|
3
|
+
*/
|
|
4
|
+
// Export all components from the React Router package
|
|
5
|
+
export { createRouteHandlers } from "./routeHandler.js";
|
|
6
|
+
// Export hooks - simplified for React Router SSR patterns
|
|
7
|
+
export { useUser } from "./useUser.js";
|
|
8
|
+
// Export configuration and helpers
|
|
9
|
+
export { resolveAuthConfig, createCivicAuthConfig, } from "./config.js";
|
|
10
|
+
export { ReactRouterCookieStorage } from "./cookies.js";
|
|
11
|
+
export { UserButton } from "./components/UserButton.js";
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react-router-7/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,sDAAsD;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAExD,0DAA0D;AAC1D,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,mCAAmC;AACnC,OAAO,EACL,iBAAiB,EACjB,qBAAqB,GAKtB,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC","sourcesContent":["/**\n * React Router authentication modules for Civic Auth\n */\n\n// Export all components from the React Router package\nexport { createRouteHandlers } from \"./routeHandler.js\";\n\n// Export hooks - simplified for React Router SSR patterns\nexport { useUser } from \"./useUser.js\";\n\n// Export configuration and helpers\nexport {\n resolveAuthConfig,\n createCivicAuthConfig,\n type AuthConfig,\n type AuthConfigWithDefaults,\n type LoggingConfig,\n type CookiesConfigObject,\n} from \"./config.js\";\n\nexport { ReactRouterCookieStorage } from \"./cookies.js\";\nexport { UserButton } from \"./components/UserButton.js\";\n\n// Types - simplified for React Router patterns\nexport type { AuthData } from \"./useUser.js\";\n"]}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { type LoaderFunctionArgs } from "react-router";
|
|
2
|
+
import type { AuthConfig, ResolvedAuthConfig, WhitelistedFrontEndConfig } from "./config.js";
|
|
3
|
+
/**
|
|
4
|
+
* Create auth route handlers for React Router - backend endpoints compatible with VanillaJS frontend integration
|
|
5
|
+
* These routes work similar to the Express example, using server-side CivicAuth SDK
|
|
6
|
+
*/
|
|
7
|
+
export declare function createRouteHandlers(configOverrides?: Partial<AuthConfig>): {
|
|
8
|
+
createAuthLoader: () => (args: LoaderFunctionArgs) => Promise<Response>;
|
|
9
|
+
createAuthAction: () => (args: LoaderFunctionArgs) => Promise<Response>;
|
|
10
|
+
resolveConfigWithFallbacks: (request?: Request) => ResolvedAuthConfig;
|
|
11
|
+
getWhitelistedFrontEndConfig: (request?: Request) => WhitelistedFrontEndConfig;
|
|
12
|
+
/**
|
|
13
|
+
* Login loader - backend OAuth login initiation endpoint
|
|
14
|
+
* Uses CivicAuth.buildLoginUrl() like Express example
|
|
15
|
+
*/
|
|
16
|
+
loginLoader: ({ request }: LoaderFunctionArgs) => Promise<Response>;
|
|
17
|
+
/**
|
|
18
|
+
* Callback loader - backend OAuth callback endpoint
|
|
19
|
+
* Uses CivicAuth.handleCallback() like Express example
|
|
20
|
+
*/
|
|
21
|
+
callbackLoader: ({ request }: LoaderFunctionArgs) => Promise<Response>;
|
|
22
|
+
/**
|
|
23
|
+
* Logout loader - backend logout endpoint
|
|
24
|
+
* Uses CivicAuth.buildLogoutRedirectUrl() and clearTokens() like Express example
|
|
25
|
+
*/
|
|
26
|
+
logoutLoader: ({ request }: LoaderFunctionArgs) => Promise<Response>;
|
|
27
|
+
/**
|
|
28
|
+
* User endpoint - returns current user data as JSON
|
|
29
|
+
* Uses CivicAuth.isLoggedIn() and getUser() like Express example
|
|
30
|
+
*/
|
|
31
|
+
userLoader: ({ request }: LoaderFunctionArgs) => Promise<Response>;
|
|
32
|
+
/**
|
|
33
|
+
* Refresh endpoint - refreshes access tokens
|
|
34
|
+
* Uses CivicAuth.refreshTokens() like Express example
|
|
35
|
+
*/
|
|
36
|
+
refreshLoader: ({ request }: LoaderFunctionArgs) => Promise<Response>;
|
|
37
|
+
/**
|
|
38
|
+
* Get user data from session (for SSR)
|
|
39
|
+
* Uses CivicAuth.isLoggedIn() and getUser() like Express example
|
|
40
|
+
*/
|
|
41
|
+
getUser: (request: Request) => Promise<import("../types.js").BaseUser | null>;
|
|
42
|
+
/**
|
|
43
|
+
* Get auth data including user and config (for SSR)
|
|
44
|
+
* Returns user data, config, and other auth-related data needed by the app under a civic key
|
|
45
|
+
*/
|
|
46
|
+
getAuthData: (request: Request) => Promise<{
|
|
47
|
+
civic: {
|
|
48
|
+
user: import("../types.js").BaseUser | null;
|
|
49
|
+
config: WhitelistedFrontEndConfig;
|
|
50
|
+
isLoggedIn: boolean;
|
|
51
|
+
};
|
|
52
|
+
}>;
|
|
53
|
+
};
|
|
54
|
+
//# sourceMappingURL=routeHandler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routeHandler.d.ts","sourceRoot":"","sources":["../../src/react-router-7/routeHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAIjE,OAAO,KAAK,EACV,UAAU,EACV,kBAAkB,EAClB,yBAAyB,EAC1B,MAAM,aAAa,CAAC;AAgBrB;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,eAAe,GAAE,OAAO,CAAC,UAAU,CAAM;mCA2ZrD,kBAAkB;mCAmClB,kBAAkB;2CA1a5B,OAAO,KAChB,kBAAkB;6CAwBT,OAAO,KAChB,yBAAyB;IAuF1B;;;OAGG;+BAC8B,kBAAkB;IAqBnD;;;OAGG;kCACiC,kBAAkB;IAsEtD;;;OAGG;gCAC+B,kBAAkB;IA8BpD;;;OAGG;8BAC6B,kBAAkB;IAuClD;;;OAGG;iCACgC,kBAAkB;IAmCrD;;;OAGG;uBACsB,OAAO;IAgBhC;;;OAGG;2BAC0B,OAAO;;;;;;;EAiGvC"}
|