@zitadel/astro-auth 1.2.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/LICENSE +201 -0
- package/README.md +254 -0
- package/dist/api/[...auth].js +41 -0
- package/dist/api/[...auth].js.map +1 -0
- package/dist/client.d.ts +91 -0
- package/dist/client.js +157 -0
- package/dist/client.js.map +1 -0
- package/dist/components/Auth.astro +38 -0
- package/dist/components/SignIn.astro +133 -0
- package/dist/components/SignOut.astro +99 -0
- package/dist/components/index.d.ts +9 -0
- package/dist/components/index.js +10 -0
- package/dist/components/index.js.map +1 -0
- package/dist/config-lAdfi49m.d.ts +104 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.js +152 -0
- package/dist/index.js.map +1 -0
- package/dist/server.d.ts +50 -0
- package/dist/server.js +84 -0
- package/dist/server.js.map +1 -0
- package/dist/types-Bvas30QH.d.ts +66 -0
- package/package.json +107 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
// src/config.ts
|
|
2
|
+
var getEnvVars = (envOverride) => {
|
|
3
|
+
if (envOverride) {
|
|
4
|
+
return envOverride;
|
|
5
|
+
} else if (typeof import.meta !== "undefined" && import.meta.env) {
|
|
6
|
+
const env = import.meta.env;
|
|
7
|
+
return {
|
|
8
|
+
AUTH_SECRET: env.AUTH_SECRET,
|
|
9
|
+
AUTH_TRUST_HOST: env.AUTH_TRUST_HOST,
|
|
10
|
+
VERCEL: env.VERCEL,
|
|
11
|
+
CF_PAGES: env.CF_PAGES,
|
|
12
|
+
NODE_ENV: env.NODE_ENV
|
|
13
|
+
};
|
|
14
|
+
} else {
|
|
15
|
+
return {
|
|
16
|
+
AUTH_SECRET: void 0,
|
|
17
|
+
AUTH_TRUST_HOST: void 0,
|
|
18
|
+
VERCEL: void 0,
|
|
19
|
+
CF_PAGES: void 0,
|
|
20
|
+
NODE_ENV: void 0
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
var parseBool = (value) => {
|
|
25
|
+
if (!value) {
|
|
26
|
+
return false;
|
|
27
|
+
} else {
|
|
28
|
+
return /^(1|true|yes|on)$/i.test(value);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
var defineConfig = (config, envOverride) => {
|
|
32
|
+
const { AUTH_SECRET, AUTH_TRUST_HOST, VERCEL, CF_PAGES, NODE_ENV } = getEnvVars(envOverride);
|
|
33
|
+
const prefix = typeof config.prefix === "string" && config.prefix.length > 0 ? config.prefix : "/api/auth";
|
|
34
|
+
const secret = typeof config.secret === "string" && config.secret.length > 0 ? config.secret : AUTH_SECRET;
|
|
35
|
+
const hasExplicitTrustHost = Object.prototype.hasOwnProperty.call(
|
|
36
|
+
config,
|
|
37
|
+
"trustHost"
|
|
38
|
+
);
|
|
39
|
+
let trustHost;
|
|
40
|
+
if (hasExplicitTrustHost) {
|
|
41
|
+
trustHost = Boolean(config.trustHost);
|
|
42
|
+
} else if (parseBool(AUTH_TRUST_HOST)) {
|
|
43
|
+
trustHost = true;
|
|
44
|
+
} else if (parseBool(VERCEL)) {
|
|
45
|
+
trustHost = true;
|
|
46
|
+
} else if (parseBool(CF_PAGES)) {
|
|
47
|
+
trustHost = true;
|
|
48
|
+
} else {
|
|
49
|
+
trustHost = NODE_ENV !== "production";
|
|
50
|
+
}
|
|
51
|
+
return {
|
|
52
|
+
...config,
|
|
53
|
+
prefix,
|
|
54
|
+
basePath: prefix,
|
|
55
|
+
secret,
|
|
56
|
+
trustHost
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
var virtualConfigModule = (configFile = "./auth.config") => {
|
|
60
|
+
const virtualModuleId = "auth:config";
|
|
61
|
+
const resolvedId = "\0" + virtualModuleId;
|
|
62
|
+
const resolveConfig = async function() {
|
|
63
|
+
const r = await this.resolve(configFile);
|
|
64
|
+
if (r && r.id) {
|
|
65
|
+
return r.id;
|
|
66
|
+
} else {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
return {
|
|
71
|
+
name: "astro-auth-config",
|
|
72
|
+
enforce: "pre",
|
|
73
|
+
resolveId: (id) => {
|
|
74
|
+
if (id === virtualModuleId) {
|
|
75
|
+
return resolvedId;
|
|
76
|
+
} else {
|
|
77
|
+
return void 0;
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
load: async function(id) {
|
|
81
|
+
if (id === resolvedId) {
|
|
82
|
+
const cfg = await resolveConfig.call(this);
|
|
83
|
+
if (!cfg) {
|
|
84
|
+
throw new Error(`[astro-auth] Cannot resolve ${configFile}`);
|
|
85
|
+
} else {
|
|
86
|
+
return `export { default as default } from ${JSON.stringify(cfg)};`;
|
|
87
|
+
}
|
|
88
|
+
} else {
|
|
89
|
+
return void 0;
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
buildStart: async function() {
|
|
93
|
+
const cfg = await resolveConfig.call(this);
|
|
94
|
+
if (cfg) {
|
|
95
|
+
this.addWatchFile(cfg);
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
handleHotUpdate: async function(ctx) {
|
|
99
|
+
const resolved = await ctx.server.pluginContainer.resolveId(configFile);
|
|
100
|
+
const configPath = resolved && resolved.id ? resolved.id : null;
|
|
101
|
+
if (configPath && ctx.file === configPath) {
|
|
102
|
+
const mod = ctx.server.moduleGraph.getModuleById(resolvedId);
|
|
103
|
+
if (mod) {
|
|
104
|
+
ctx.server.moduleGraph.invalidateModule(mod);
|
|
105
|
+
}
|
|
106
|
+
return [ctx.server.moduleGraph.getModuleById(configPath)].filter(
|
|
107
|
+
Boolean
|
|
108
|
+
);
|
|
109
|
+
} else {
|
|
110
|
+
return void 0;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
// src/integration.ts
|
|
117
|
+
import { fileURLToPath } from "url";
|
|
118
|
+
var integration_default = (config = {}) => ({
|
|
119
|
+
name: "astro-auth",
|
|
120
|
+
hooks: {
|
|
121
|
+
"astro:config:setup": async ({
|
|
122
|
+
config: astroConfig,
|
|
123
|
+
injectRoute,
|
|
124
|
+
updateConfig
|
|
125
|
+
}) => {
|
|
126
|
+
updateConfig({
|
|
127
|
+
vite: {
|
|
128
|
+
plugins: [virtualConfigModule(config.configFile)],
|
|
129
|
+
// IMPORTANT: never pre-bundle the virtual module
|
|
130
|
+
optimizeDeps: { exclude: ["auth:config"] }
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
config.prefix ??= "/api/auth";
|
|
134
|
+
if (config.injectEndpoints !== false) {
|
|
135
|
+
const entrypoint = fileURLToPath(
|
|
136
|
+
new URL("./api/[...auth].js", import.meta.url)
|
|
137
|
+
);
|
|
138
|
+
injectRoute({ pattern: `${config.prefix}/[...auth]`, entrypoint });
|
|
139
|
+
}
|
|
140
|
+
if (!astroConfig.adapter) {
|
|
141
|
+
throw new Error(
|
|
142
|
+
"No adapter found. Authentication requires server-side rendering. Please add an adapter to your Astro config."
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
export {
|
|
149
|
+
integration_default as default,
|
|
150
|
+
defineConfig
|
|
151
|
+
};
|
|
152
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/config.ts","../src/integration.ts"],"sourcesContent":["import type { AuthConfig } from '@auth/core/types';\nimport type { PluginContext } from 'rollup';\nimport type { ViteUserConfig } from 'astro';\n\ntype PluginOption = NonNullable<ViteUserConfig['plugins']>[number];\n\n/**\n * Configuration options specific to the Astro integration.\n *\n * @public\n */\nexport interface AstroIntegrationOptions {\n /**\n * Base path for authentication routes.\n *\n * @defaultValue '/api/auth'\n *\n * @example\n * ```js\n * authAstro({ prefix: '/auth' })\n * // Routes will be available at /auth/signin, /auth/signout, etc.\n * ```\n */\n prefix?: string;\n\n /**\n * Whether the integration should automatically inject authentication\n * endpoints.\n *\n * Set to `false` if you want to manually define authentication routes.\n *\n * @defaultValue true\n */\n injectEndpoints?: boolean;\n\n /**\n * Path to the authentication configuration file.\n *\n * @defaultValue './auth.config'\n *\n * @example\n * ```js\n * authAstro({ configFile: './config/authentication.ts' })\n * ```\n */\n configFile?: string;\n}\n\n/**\n * Complete authentication configuration merging Astro-specific options\n * with Auth.js core configuration.\n *\n * @public\n */\nexport interface FullAuthConfig\n extends AstroIntegrationOptions,\n Omit<AuthConfig, 'raw'> {}\n\n/**\n * Environment variables structure used by Auth.js configuration.\n *\n * @public\n */\nexport interface AuthEnvVars {\n AUTH_SECRET?: string;\n AUTH_TRUST_HOST?: string;\n VERCEL?: string;\n CF_PAGES?: string;\n NODE_ENV?: string;\n}\n\n/**\n * Retrieves environment variables from the runtime environment.\n *\n * This function provides a safe way to access Vite's `import.meta.env` object,\n * which may not be available in all contexts (e.g., during Jest testing).\n * By extracting this logic into a separate function with a parameter override,\n * we enable easy testing while maintaining the same behavior in production.\n *\n * @param envOverride - Optional environment variables to use instead of import.meta.env\n * @returns Object containing Auth.js-related environment variables\n *\n * @internal\n *\n * @remarks\n * This function accepts an optional parameter for testing purposes. In production\n * code, it reads from `import.meta.env`. In tests, callers can pass a mock\n * environment object to control the values without complex mocking.\n *\n * @example Production usage\n * ```ts\n * const env = getEnvVars()\n * console.log(env.AUTH_SECRET)\n * ```\n *\n * @example Test usage\n * ```ts\n * const env = getEnvVars({ AUTH_SECRET: 'test-secret' })\n * ```\n */\nconst getEnvVars = (envOverride?: AuthEnvVars): AuthEnvVars => {\n if (envOverride) {\n return envOverride;\n } else if (\n typeof import.meta !== 'undefined' &&\n (import.meta as { env: Record<string, string | undefined> }).env\n ) {\n const env = (import.meta as { env: Record<string, string | undefined> })\n .env;\n return {\n AUTH_SECRET: env.AUTH_SECRET,\n AUTH_TRUST_HOST: env.AUTH_TRUST_HOST,\n VERCEL: env.VERCEL,\n CF_PAGES: env.CF_PAGES,\n NODE_ENV: env.NODE_ENV,\n };\n } else {\n return {\n AUTH_SECRET: undefined,\n AUTH_TRUST_HOST: undefined,\n VERCEL: undefined,\n CF_PAGES: undefined,\n NODE_ENV: undefined,\n };\n }\n};\n\n/**\n * Parses a string value as a boolean.\n *\n * Only treats explicit truthy values as true: \"1\", \"true\", \"yes\", \"on\" (case-insensitive).\n * All other values including \"0\", \"false\", undefined, etc. return false.\n *\n * @param value - The string value to parse\n * @returns true if the value is explicitly truthy, false otherwise\n *\n * @internal\n */\nconst parseBool = (value?: string): boolean => {\n if (!value) {\n return false;\n } else {\n return /^(1|true|yes|on)$/i.test(value);\n }\n};\n\n/**\n * Helper function to define authentication configuration with type safety.\n *\n * This function applies default values and reads environment variables to\n * provide a complete configuration object. Environment variables are only\n * used as fallbacks when values are not explicitly provided in the config.\n *\n * Environment variables read (in order of precedence for `trustHost`):\n * - `config.trustHost`: Explicit config value (highest priority)\n * - `AUTH_TRUST_HOST`: Whether to trust the X-Forwarded-Host header (\"1\"/\"true\"/\"yes\"/\"on\")\n * - `VERCEL`: Automatically set by Vercel (any truthy value enables trustHost)\n * - `CF_PAGES`: Automatically set by Cloudflare Pages (any truthy value enables trustHost)\n * - `NODE_ENV`: Node environment (trustHost enabled if not 'production')\n *\n * For `secret`:\n * - `config.secret`: Explicit config value (highest priority)\n * - `AUTH_SECRET`: Environment variable fallback\n *\n * @param config - Authentication configuration object\n * @param envOverride - Optional environment variables for testing\n * @returns Configuration with defaults applied\n *\n * @example\n * ```ts\n * import { defineConfig } from 'astro-auth'\n * import GitHub from '@auth/core/providers/github'\n *\n * export default defineConfig({\n * providers: [\n * GitHub({\n * clientId: process.env.GITHUB_ID,\n * clientSecret: process.env.GITHUB_SECRET\n * })\n * ],\n * secret: process.env.AUTH_SECRET\n * })\n * ```\n *\n * @public\n */\nexport const defineConfig = (\n config: Readonly<FullAuthConfig>,\n envOverride?: AuthEnvVars,\n): FullAuthConfig => {\n const { AUTH_SECRET, AUTH_TRUST_HOST, VERCEL, CF_PAGES, NODE_ENV } =\n getEnvVars(envOverride);\n\n const prefix =\n typeof config.prefix === 'string' && config.prefix.length > 0\n ? config.prefix\n : '/api/auth';\n const secret =\n typeof config.secret === 'string' && config.secret.length > 0\n ? config.secret\n : AUTH_SECRET;\n\n const hasExplicitTrustHost = Object.prototype.hasOwnProperty.call(\n config,\n 'trustHost',\n );\n let trustHost: boolean;\n if (hasExplicitTrustHost) {\n trustHost = Boolean((config as { trustHost?: unknown }).trustHost);\n } else if (parseBool(AUTH_TRUST_HOST)) {\n trustHost = true;\n } else if (parseBool(VERCEL)) {\n trustHost = true;\n } else if (parseBool(CF_PAGES)) {\n trustHost = true;\n } else {\n trustHost = NODE_ENV !== 'production';\n }\n\n return {\n ...config,\n prefix,\n basePath: prefix,\n secret,\n trustHost,\n };\n};\n\n/**\n * Creates a Vite virtual module plugin for auth configuration.\n *\n * Allows importing user configuration via the `auth:config` virtual module\n * regardless of the actual file location specified in the integration\n * configuration.\n *\n * @param configFile - Path to the configuration file\n * @returns Vite plugin for handling the virtual module\n *\n * @internal\n */\nexport const virtualConfigModule = (\n configFile: string = './auth.config',\n): PluginOption => {\n const virtualModuleId = 'auth:config';\n const resolvedId = '\\0' + virtualModuleId;\n\n const resolveConfig = async function (\n this: PluginContext,\n ): Promise<string | null> {\n const r = await this.resolve(configFile);\n if (r && r.id) {\n return r.id;\n } else {\n return null;\n }\n };\n\n return {\n name: 'astro-auth-config',\n enforce: 'pre',\n resolveId: (id) => {\n if (id === virtualModuleId) {\n return resolvedId;\n } else {\n return undefined;\n }\n },\n load: async function (id) {\n if (id === resolvedId) {\n const cfg = await resolveConfig.call(this);\n if (!cfg) {\n throw new Error(`[astro-auth] Cannot resolve ${configFile}`);\n } else {\n return `export { default as default } from ${JSON.stringify(cfg)};`;\n }\n } else {\n return undefined;\n }\n },\n buildStart: async function () {\n const cfg = await resolveConfig.call(this);\n if (cfg) {\n this.addWatchFile(cfg);\n }\n },\n handleHotUpdate: async function (ctx) {\n const resolved = await ctx.server.pluginContainer.resolveId(configFile);\n const configPath = resolved && resolved.id ? resolved.id : null;\n if (configPath && ctx.file === configPath) {\n const mod = ctx.server.moduleGraph.getModuleById(resolvedId);\n if (mod) {\n ctx.server.moduleGraph.invalidateModule(mod);\n }\n return [ctx.server.moduleGraph.getModuleById(configPath)!].filter(\n Boolean,\n );\n } else {\n return undefined;\n }\n },\n };\n};\n","import type { AstroIntegration } from 'astro';\nimport { type AstroIntegrationOptions, virtualConfigModule } from './config.js';\nimport { fileURLToPath } from 'node:url';\n\n/**\n * Creates an Astro integration for authentication using Auth.js.\n *\n * This integration handles:\n * - Virtual module configuration for auth settings\n * - Automatic route injection for authentication endpoints\n * - Vite configuration for proper module resolution\n *\n * @param config - Configuration options for the integration\n * @returns Configured Astro integration\n * @throws {Error} When no adapter is configured (server-side rendering is required).\n *\n * @remarks\n * This integration requires server-side rendering. Ensure you have\n * configured an Astro adapter (e.g., `@astrojs/node`, `@astrojs/vercel`)\n * in your Astro config.\n *\n * @public\n */\nexport default (config: AstroIntegrationOptions = {}): AstroIntegration => ({\n name: 'astro-auth',\n hooks: {\n 'astro:config:setup': async ({\n config: astroConfig,\n injectRoute,\n updateConfig,\n }) => {\n updateConfig({\n vite: {\n plugins: [virtualConfigModule(config.configFile)],\n // IMPORTANT: never pre-bundle the virtual module\n optimizeDeps: { exclude: ['auth:config'] },\n },\n });\n\n config.prefix ??= '/api/auth';\n\n if (config.injectEndpoints !== false) {\n const entrypoint = fileURLToPath(\n new URL('./api/[...auth].js', import.meta.url),\n );\n injectRoute({ pattern: `${config.prefix}/[...auth]`, entrypoint });\n }\n\n if (!astroConfig.adapter) {\n throw new Error(\n 'No adapter found. Authentication requires server-side rendering. Please add an adapter to your Astro config.',\n );\n }\n },\n },\n});\n"],"mappings":"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","names":[]}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { F as FullAuthConfig } from './config-lAdfi49m.js';
|
|
2
|
+
import { APIContext } from 'astro';
|
|
3
|
+
import { b as AstroAuthConfig } from './types-Bvas30QH.js';
|
|
4
|
+
import { Session } from '@auth/core/types';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Creates a set of Astro endpoints for authentication.
|
|
8
|
+
*
|
|
9
|
+
* @param options - The configuration for authentication providers and other options.
|
|
10
|
+
* @returns An object with `GET` and `POST` methods that can be exported in an Astro endpoint.
|
|
11
|
+
* @throws {Error} When auth configuration is not found or not properly configured.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* export const { GET, POST } = AstroAuth({
|
|
16
|
+
* providers: [
|
|
17
|
+
* GitHub({
|
|
18
|
+
* clientId: process.env.GITHUB_ID!,
|
|
19
|
+
* clientSecret: process.env.GITHUB_SECRET!,
|
|
20
|
+
* }),
|
|
21
|
+
* ],
|
|
22
|
+
* debug: false,
|
|
23
|
+
* })
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
declare function AstroAuth(options?: FullAuthConfig): {
|
|
27
|
+
GET(context: APIContext): Promise<Response>;
|
|
28
|
+
POST(context: APIContext): Promise<Response>;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Retrieves the current session for a Request.
|
|
32
|
+
*
|
|
33
|
+
* This function extracts session information from the request cookies and
|
|
34
|
+
* validates it against the Auth.js configuration. It returns the session
|
|
35
|
+
* object if valid or null if no valid session exists.
|
|
36
|
+
*
|
|
37
|
+
* @param req - The Request object
|
|
38
|
+
* @param config - The authentication configuration
|
|
39
|
+
* @returns Promise resolving to session data or null
|
|
40
|
+
* @throws {Error} When session validation fails or Auth.js returns an error
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```ts
|
|
44
|
+
* const session = await getSession(request, authConfig)
|
|
45
|
+
* if (!session) throw new Error ("Not authenticated")
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
declare function getSession(req: Request, config: AstroAuthConfig): Promise<Session | null>;
|
|
49
|
+
|
|
50
|
+
export { AstroAuth, getSession };
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
// src/server.ts
|
|
2
|
+
import { Auth, createActionURL, setEnvDefaults } from "@auth/core";
|
|
3
|
+
import authConfig from "auth:config";
|
|
4
|
+
function AstroAuthHandler(prefix, options = authConfig) {
|
|
5
|
+
const normalizedPrefix = prefix.endsWith("/") ? prefix.slice(0, -1) : prefix;
|
|
6
|
+
return async ({ request }) => {
|
|
7
|
+
const url = new URL(request.url);
|
|
8
|
+
if (!url.pathname.startsWith(normalizedPrefix + "/")) {
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
return await Auth(request, options);
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
function AstroAuth(options = authConfig) {
|
|
15
|
+
const config = options ?? authConfig;
|
|
16
|
+
if (!config) {
|
|
17
|
+
throw new Error(
|
|
18
|
+
"Auth configuration not found. Please ensure auth.config is properly configured."
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
const { prefix = "/api/auth", ...authOptions } = config;
|
|
22
|
+
const handler = AstroAuthHandler(prefix, authOptions);
|
|
23
|
+
return {
|
|
24
|
+
async GET(context) {
|
|
25
|
+
return await handler(context);
|
|
26
|
+
},
|
|
27
|
+
async POST(context) {
|
|
28
|
+
return await handler(context);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
async function getSession(req, config) {
|
|
33
|
+
setEnvDefaults(process.env, config);
|
|
34
|
+
const url = createActionURL(
|
|
35
|
+
"session",
|
|
36
|
+
new URL(req.url).protocol.replace(":", ""),
|
|
37
|
+
new Headers(req.headers),
|
|
38
|
+
process.env,
|
|
39
|
+
config
|
|
40
|
+
);
|
|
41
|
+
const headers = new Headers(req.headers);
|
|
42
|
+
const response = await Auth(
|
|
43
|
+
new Request(url, {
|
|
44
|
+
headers
|
|
45
|
+
}),
|
|
46
|
+
config
|
|
47
|
+
);
|
|
48
|
+
const status = response.status ?? 200;
|
|
49
|
+
const data = await response.json();
|
|
50
|
+
if (!data || !Object.keys(data).length) {
|
|
51
|
+
return null;
|
|
52
|
+
} else {
|
|
53
|
+
const astroGlobal = globalThis;
|
|
54
|
+
const target = astroGlobal.Astro && astroGlobal.Astro.response ? astroGlobal.Astro.response.headers : void 0;
|
|
55
|
+
if (target) {
|
|
56
|
+
const h = response.headers;
|
|
57
|
+
if (h && typeof h.getSetCookie === "function") {
|
|
58
|
+
const cookies = h.getSetCookie();
|
|
59
|
+
if (Array.isArray(cookies)) {
|
|
60
|
+
for (const c of cookies) {
|
|
61
|
+
target.append("Set-Cookie", c);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
} else {
|
|
65
|
+
const single = response.headers.get("set-cookie");
|
|
66
|
+
if (single) {
|
|
67
|
+
target.append("Set-Cookie", single);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
if (status === 200) {
|
|
72
|
+
return data;
|
|
73
|
+
} else {
|
|
74
|
+
throw new Error(
|
|
75
|
+
`[astro-auth] getSession failed: ${status} ${JSON.stringify(data)}`
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
export {
|
|
81
|
+
AstroAuth,
|
|
82
|
+
getSession
|
|
83
|
+
};
|
|
84
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/server.ts"],"sourcesContent":["/**\n * > **caution**\n * > `astro-auth` is currently experimental. Be aware of breaking changes between versions.\n *\n *\n * Astro Auth is the unofficial Astro integration for Auth.js.\n * It provides a simple way to add authentication to your Astro site in a few lines of code.\n *\n * ## Installation\n *\n * `astro-auth` requires building your site in `server` mode with a platform adaper like `@astrojs/node`.\n * ```js\n * // astro.config.mjs\n * export default defineConfig({\n * output: \"server\",\n * adapter: node({\n * mode: 'standalone'\n * })\n * });\n * ```\n *\n * ```bash npm2yarn2pnpm\n * npm install @auth/core @zitadel/astro-auth\n * ```\n */\nimport { Auth, createActionURL, setEnvDefaults } from '@auth/core';\nimport type { APIContext } from 'astro';\nimport authConfig from 'auth:config';\nimport type { AstroAuthConfig } from './types.js';\nimport type { Session } from '@auth/core/types';\n\nfunction AstroAuthHandler(prefix: string, options = authConfig) {\n const normalizedPrefix = prefix.endsWith('/') ? prefix.slice(0, -1) : prefix;\n return async ({ request }: APIContext) => {\n const url = new URL(request.url);\n // Only handle requests that match our prefix path\n // Non-matching paths return undefined because this handler is mounted as [...auth]\n if (!url.pathname.startsWith(normalizedPrefix + '/')) {\n return;\n }\n\n return await Auth(request, options);\n };\n}\n\n/**\n * Creates a set of Astro endpoints for authentication.\n *\n * @param options - The configuration for authentication providers and other options.\n * @returns An object with `GET` and `POST` methods that can be exported in an Astro endpoint.\n * @throws {Error} When auth configuration is not found or not properly configured.\n *\n * @example\n * ```ts\n * export const { GET, POST } = AstroAuth({\n * providers: [\n * GitHub({\n * clientId: process.env.GITHUB_ID!,\n * clientSecret: process.env.GITHUB_SECRET!,\n * }),\n * ],\n * debug: false,\n * })\n * ```\n */\nexport function AstroAuth(options = authConfig) {\n const config = options ?? authConfig;\n if (!config) {\n throw new Error(\n 'Auth configuration not found. Please ensure auth.config is properly configured.',\n );\n }\n const { prefix = '/api/auth', ...authOptions } = config;\n\n const handler = AstroAuthHandler(prefix, authOptions);\n return {\n async GET(context: APIContext) {\n return await handler(context);\n },\n async POST(context: APIContext) {\n return await handler(context);\n },\n };\n}\n\n/**\n * Retrieves the current session for a Request.\n *\n * This function extracts session information from the request cookies and\n * validates it against the Auth.js configuration. It returns the session\n * object if valid or null if no valid session exists.\n *\n * @param req - The Request object\n * @param config - The authentication configuration\n * @returns Promise resolving to session data or null\n * @throws {Error} When session validation fails or Auth.js returns an error\n *\n * @example\n * ```ts\n * const session = await getSession(request, authConfig)\n * if (!session) throw new Error (\"Not authenticated\")\n * ```\n */\nexport async function getSession(\n req: Request,\n config: AstroAuthConfig,\n): Promise<Session | null> {\n setEnvDefaults(process.env, config);\n const url = createActionURL(\n 'session',\n new URL(req.url).protocol.replace(':', ''),\n new Headers(req.headers),\n process.env,\n config,\n );\n const headers = new Headers(req.headers);\n const response = await Auth(\n new Request(url, {\n headers,\n }),\n config,\n );\n const status = response.status ?? 200;\n const data = await response.json();\n if (!data || !Object.keys(data).length) {\n return null;\n } else {\n const astroGlobal = globalThis as unknown as {\n Astro?: { response?: { headers?: Headers } };\n };\n const target =\n astroGlobal.Astro && astroGlobal.Astro.response\n ? astroGlobal.Astro.response.headers\n : undefined;\n if (target) {\n const h = response.headers as unknown as {\n getSetCookie?: () => string[];\n };\n if (h && typeof h.getSetCookie === 'function') {\n const cookies = h.getSetCookie();\n if (Array.isArray(cookies)) {\n for (const c of cookies) {\n target.append('Set-Cookie', c);\n }\n }\n } else {\n const single = response.headers.get('set-cookie');\n if (single) {\n target.append('Set-Cookie', single);\n }\n }\n }\n if (status === 200) {\n return data as Session;\n } else {\n throw new Error(\n `[astro-auth] getSession failed: ${status} ${JSON.stringify(data)}`,\n );\n }\n }\n}\n"],"mappings":";AAyBA,SAAS,MAAM,iBAAiB,sBAAsB;AAEtD,OAAO,gBAAgB;AAIvB,SAAS,iBAAiB,QAAgB,UAAU,YAAY;AAC9D,QAAM,mBAAmB,OAAO,SAAS,GAAG,IAAI,OAAO,MAAM,GAAG,EAAE,IAAI;AACtE,SAAO,OAAO,EAAE,QAAQ,MAAkB;AACxC,UAAM,MAAM,IAAI,IAAI,QAAQ,GAAG;AAG/B,QAAI,CAAC,IAAI,SAAS,WAAW,mBAAmB,GAAG,GAAG;AACpD;AAAA,IACF;AAEA,WAAO,MAAM,KAAK,SAAS,OAAO;AAAA,EACpC;AACF;AAsBO,SAAS,UAAU,UAAU,YAAY;AAC9C,QAAM,SAAS,WAAW;AAC1B,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,QAAM,EAAE,SAAS,aAAa,GAAG,YAAY,IAAI;AAEjD,QAAM,UAAU,iBAAiB,QAAQ,WAAW;AACpD,SAAO;AAAA,IACL,MAAM,IAAI,SAAqB;AAC7B,aAAO,MAAM,QAAQ,OAAO;AAAA,IAC9B;AAAA,IACA,MAAM,KAAK,SAAqB;AAC9B,aAAO,MAAM,QAAQ,OAAO;AAAA,IAC9B;AAAA,EACF;AACF;AAoBA,eAAsB,WACpB,KACA,QACyB;AACzB,iBAAe,QAAQ,KAAK,MAAM;AAClC,QAAM,MAAM;AAAA,IACV;AAAA,IACA,IAAI,IAAI,IAAI,GAAG,EAAE,SAAS,QAAQ,KAAK,EAAE;AAAA,IACzC,IAAI,QAAQ,IAAI,OAAO;AAAA,IACvB,QAAQ;AAAA,IACR;AAAA,EACF;AACA,QAAM,UAAU,IAAI,QAAQ,IAAI,OAAO;AACvC,QAAM,WAAW,MAAM;AAAA,IACrB,IAAI,QAAQ,KAAK;AAAA,MACf;AAAA,IACF,CAAC;AAAA,IACD;AAAA,EACF;AACA,QAAM,SAAS,SAAS,UAAU;AAClC,QAAM,OAAO,MAAM,SAAS,KAAK;AACjC,MAAI,CAAC,QAAQ,CAAC,OAAO,KAAK,IAAI,EAAE,QAAQ;AACtC,WAAO;AAAA,EACT,OAAO;AACL,UAAM,cAAc;AAGpB,UAAM,SACJ,YAAY,SAAS,YAAY,MAAM,WACnC,YAAY,MAAM,SAAS,UAC3B;AACN,QAAI,QAAQ;AACV,YAAM,IAAI,SAAS;AAGnB,UAAI,KAAK,OAAO,EAAE,iBAAiB,YAAY;AAC7C,cAAM,UAAU,EAAE,aAAa;AAC/B,YAAI,MAAM,QAAQ,OAAO,GAAG;AAC1B,qBAAW,KAAK,SAAS;AACvB,mBAAO,OAAO,cAAc,CAAC;AAAA,UAC/B;AAAA,QACF;AAAA,MACF,OAAO;AACL,cAAM,SAAS,SAAS,QAAQ,IAAI,YAAY;AAChD,YAAI,QAAQ;AACV,iBAAO,OAAO,cAAc,MAAM;AAAA,QACpC;AAAA,MACF;AAAA,IACF;AACA,QAAI,WAAW,KAAK;AAClB,aAAO;AAAA,IACT,OAAO;AACL,YAAM,IAAI;AAAA,QACR,mCAAmC,MAAM,IAAI,KAAK,UAAU,IAAI,CAAC;AAAA,MACnE;AAAA,IACF;AAAA,EACF;AACF;","names":[]}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { AuthConfig } from '@auth/core/types';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Utility type for string literals with autocomplete support.
|
|
5
|
+
*
|
|
6
|
+
* @internal
|
|
7
|
+
*/
|
|
8
|
+
type LiteralUnion<T extends U, U = string> = T | (U & Record<never, never>);
|
|
9
|
+
/**
|
|
10
|
+
* Options for the sign-in flow.
|
|
11
|
+
*
|
|
12
|
+
* @public
|
|
13
|
+
*/
|
|
14
|
+
interface SignInOptions {
|
|
15
|
+
/** URL to redirect to after successful sign-in */
|
|
16
|
+
callbackUrl?: string;
|
|
17
|
+
/** Whether to redirect after sign-in */
|
|
18
|
+
redirect?: boolean;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Authorization parameters passed to the OAuth provider.
|
|
22
|
+
*
|
|
23
|
+
* @public
|
|
24
|
+
*/
|
|
25
|
+
interface SignInAuthorizationParams {
|
|
26
|
+
[key: string]: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Astro-specific sign-in options extending base options.
|
|
30
|
+
*
|
|
31
|
+
* @public
|
|
32
|
+
*/
|
|
33
|
+
interface AstroSignInOptions extends SignInOptions {
|
|
34
|
+
/** Custom auth endpoint prefix */
|
|
35
|
+
prefix?: string;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Options for the sign-out flow.
|
|
39
|
+
*
|
|
40
|
+
* @public
|
|
41
|
+
*/
|
|
42
|
+
interface SignOutParams {
|
|
43
|
+
/** URL to redirect to after sign-out */
|
|
44
|
+
callbackUrl?: string;
|
|
45
|
+
/** Whether to redirect after sign-out */
|
|
46
|
+
redirect?: boolean;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Astro-specific sign-out options extending base options.
|
|
50
|
+
*
|
|
51
|
+
* @public
|
|
52
|
+
*/
|
|
53
|
+
interface AstroSignOutParams extends SignOutParams {
|
|
54
|
+
/** Custom auth endpoint prefix */
|
|
55
|
+
prefix?: string;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Authentication configuration for Astro integration.
|
|
59
|
+
*
|
|
60
|
+
* Excludes internal Auth.js properties not relevant to Astro usage.
|
|
61
|
+
*
|
|
62
|
+
* @public
|
|
63
|
+
*/
|
|
64
|
+
type AstroAuthConfig = Omit<AuthConfig, 'raw'>;
|
|
65
|
+
|
|
66
|
+
export type { AstroSignInOptions as A, LiteralUnion as L, SignInAuthorizationParams as S, AstroSignOutParams as a, AstroAuthConfig as b };
|
package/package.json
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@zitadel/astro-auth",
|
|
3
|
+
"description": "A comprehensive Auth.js integration for Astro applications with TypeScript support, framework-agnostic HTTP adapters, and role-based access control",
|
|
4
|
+
"version": "1.2.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./client": {
|
|
14
|
+
"types": "./dist/client.d.ts",
|
|
15
|
+
"import": "./dist/client.js"
|
|
16
|
+
},
|
|
17
|
+
"./server": {
|
|
18
|
+
"types": "./dist/server.d.ts",
|
|
19
|
+
"import": "./dist/server.js"
|
|
20
|
+
},
|
|
21
|
+
"./components": {
|
|
22
|
+
"types": "./dist/components/index.d.ts",
|
|
23
|
+
"import": "./dist/components/index.js"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"dist"
|
|
28
|
+
],
|
|
29
|
+
"engines": {
|
|
30
|
+
"node": ">=22.0.0"
|
|
31
|
+
},
|
|
32
|
+
"license": "Apache-2.0",
|
|
33
|
+
"repository": {
|
|
34
|
+
"type": "git",
|
|
35
|
+
"url": "git+https://github.com/zitadel/astro-auth.git"
|
|
36
|
+
},
|
|
37
|
+
"author": {
|
|
38
|
+
"name": "Mridang Agarwalla",
|
|
39
|
+
"email": "mridang@zitadel.com",
|
|
40
|
+
"url": "https://github.com/zitadel"
|
|
41
|
+
},
|
|
42
|
+
"scripts": {
|
|
43
|
+
"prepack": "tsc",
|
|
44
|
+
"prepare": "npm run build",
|
|
45
|
+
"build": "tsup",
|
|
46
|
+
"test": "jest --verbose --config=jest.config.mjs --runInBand",
|
|
47
|
+
"test:watch": "npm run test -- --watch",
|
|
48
|
+
"test:debug": "jest --verbose --config=jest.config.mjs --runInBand --detectOpenHandles",
|
|
49
|
+
"format": "prettier --write .",
|
|
50
|
+
"format:check": "prettier --check .",
|
|
51
|
+
"lint": "npx eslint .",
|
|
52
|
+
"lint:fix": "npx eslint . --fix",
|
|
53
|
+
"depcheck": "npx knip"
|
|
54
|
+
},
|
|
55
|
+
"peerDependencies": {
|
|
56
|
+
"@auth/core": ">=0.40.0",
|
|
57
|
+
"astro": ">=5.0.0"
|
|
58
|
+
},
|
|
59
|
+
"devDependencies": {
|
|
60
|
+
"@auth/core": "^0.40.0",
|
|
61
|
+
"@jest/globals": "^30.0.5",
|
|
62
|
+
"@mridang/eslint-defaults": "^1.5.0",
|
|
63
|
+
"@semantic-release/commit-analyzer": "^13.0.1",
|
|
64
|
+
"@semantic-release/git": "^10.0.1",
|
|
65
|
+
"@semantic-release/github": "^12.0.0",
|
|
66
|
+
"@semantic-release/npm": "^13.1.1",
|
|
67
|
+
"@semantic-release/release-notes-generator": "^14.1.0",
|
|
68
|
+
"@types/jest": "^30.0.0",
|
|
69
|
+
"@types/node": "^22.18.13",
|
|
70
|
+
"astro": "^5.0.0",
|
|
71
|
+
"eslint": "9.32.0",
|
|
72
|
+
"eslint-plugin-astro": "^1.4.0",
|
|
73
|
+
"jest": "30.0.5",
|
|
74
|
+
"jest-environment-jsdom": "^30.2.0",
|
|
75
|
+
"jest-fetch-mock": "^3.0.3",
|
|
76
|
+
"jest-junit": "^16.0.0",
|
|
77
|
+
"knip": "^5.66.4",
|
|
78
|
+
"prettier": "3.6.2",
|
|
79
|
+
"prettier-plugin-astro": "^0.14.1",
|
|
80
|
+
"rollup": "^4.52.5",
|
|
81
|
+
"semantic-release": "^25.0.1",
|
|
82
|
+
"ts-jest": "29.4.0",
|
|
83
|
+
"tsup": "^8.5.0",
|
|
84
|
+
"typescript": "^5.9.3"
|
|
85
|
+
},
|
|
86
|
+
"keywords": [
|
|
87
|
+
"astro",
|
|
88
|
+
"auth",
|
|
89
|
+
"authentication",
|
|
90
|
+
"integration",
|
|
91
|
+
"@auth",
|
|
92
|
+
"@auth/core",
|
|
93
|
+
"authjs",
|
|
94
|
+
"jwt",
|
|
95
|
+
"oauth",
|
|
96
|
+
"astro-auth",
|
|
97
|
+
"astro-integration",
|
|
98
|
+
"astro-component",
|
|
99
|
+
"withastro"
|
|
100
|
+
],
|
|
101
|
+
"private": false,
|
|
102
|
+
"homepage": "https://github.com/zitadel/astro-auth",
|
|
103
|
+
"bugs": "https://github.com/zitadel/astro-auth/issues",
|
|
104
|
+
"publishConfig": {
|
|
105
|
+
"access": "public"
|
|
106
|
+
}
|
|
107
|
+
}
|