@augmenting-integrations/auth 3.0.1 → 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/index.cjs +10 -16
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +33 -20
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -16
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -36,18 +36,9 @@ module.exports = __toCommonJS(index_exports);
|
|
|
36
36
|
var import_next_auth = __toESM(require("next-auth"));
|
|
37
37
|
var import_credentials = __toESM(require("next-auth/providers/credentials"));
|
|
38
38
|
var import_cognito = __toESM(require("next-auth/providers/cognito"));
|
|
39
|
-
var VALID_ROLES = [
|
|
40
|
-
"visitor",
|
|
41
|
-
"broker",
|
|
42
|
-
"company_admin",
|
|
43
|
-
"manager",
|
|
44
|
-
"agent",
|
|
45
|
-
"admin"
|
|
46
|
-
];
|
|
47
39
|
function roleFromGroups(groups) {
|
|
48
40
|
if (Array.isArray(groups) && groups.length > 0) {
|
|
49
|
-
|
|
50
|
-
if (VALID_ROLES.includes(first)) return first;
|
|
41
|
+
return String(groups[0]).toLowerCase();
|
|
51
42
|
}
|
|
52
43
|
return "visitor";
|
|
53
44
|
}
|
|
@@ -55,7 +46,10 @@ function createAuth(opts) {
|
|
|
55
46
|
const isProd = opts.isProd ?? process.env.NODE_ENV === "production";
|
|
56
47
|
const signInPage = opts.signInPage ?? "/login";
|
|
57
48
|
const cookieDomain = isProd ? opts.cookieDomain ?? process.env.AUTH_COOKIE_DOMAIN : void 0;
|
|
58
|
-
const SECRET = process.env.AUTH_SECRET ?? (isProd ? void 0 : "dev-only-fallback-not-for-prod");
|
|
49
|
+
const SECRET = opts.secret ?? process.env.AUTH_SECRET ?? (isProd ? void 0 : "dev-only-fallback-not-for-prod");
|
|
50
|
+
const cognitoClientId = opts.cognito?.clientId ?? process.env.AUTH_COGNITO_ID;
|
|
51
|
+
const cognitoClientSecret = opts.cognito?.clientSecret ?? process.env.AUTH_COGNITO_SECRET;
|
|
52
|
+
const cognitoIssuer = opts.cognito?.issuer ?? process.env.AUTH_COGNITO_ISSUER;
|
|
59
53
|
const config = {
|
|
60
54
|
secret: SECRET,
|
|
61
55
|
cookies: cookieDomain ? {
|
|
@@ -72,9 +66,9 @@ function createAuth(opts) {
|
|
|
72
66
|
} : void 0,
|
|
73
67
|
providers: isProd ? [
|
|
74
68
|
(0, import_cognito.default)({
|
|
75
|
-
clientId:
|
|
76
|
-
clientSecret:
|
|
77
|
-
issuer:
|
|
69
|
+
clientId: cognitoClientId,
|
|
70
|
+
clientSecret: cognitoClientSecret,
|
|
71
|
+
issuer: cognitoIssuer
|
|
78
72
|
})
|
|
79
73
|
] : [
|
|
80
74
|
(0, import_credentials.default)({
|
|
@@ -83,12 +77,12 @@ function createAuth(opts) {
|
|
|
83
77
|
role: {
|
|
84
78
|
label: "Role",
|
|
85
79
|
type: "text",
|
|
86
|
-
placeholder: "
|
|
80
|
+
placeholder: "any role string"
|
|
87
81
|
}
|
|
88
82
|
},
|
|
89
83
|
authorize: async (credentials) => {
|
|
90
84
|
const role = credentials?.role;
|
|
91
|
-
if (!role
|
|
85
|
+
if (!role) return null;
|
|
92
86
|
const display = role.charAt(0).toUpperCase() + role.slice(1);
|
|
93
87
|
return {
|
|
94
88
|
id: `mock-${role}`,
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["// Auth.js v5 (the package is still distributed as `next-auth`, but treat\n// these as Auth.js v5 internally — docs at https://authjs.dev, NOT\n// next-auth.js.org which is v4 and incompatible).\n//\n// Provider strategy:\n// - Production: Cognito OIDC. Group membership from `cognito:groups`\n// drives role.\n// - Dev / preview: Credentials with a role picker, BUT shaped to mirror\n// Cognito's claim payload so consumers (callbacks, gates, audit logs)\n// never branch on environment. Same `sub`, `email`, `cognito:groups`\n// in both modes.\n//\n// IMPORTANT: do not let the dev-mode session diverge from production. If\n// you add a claim in prod, also add it (with a synthetic value) in dev.\n\nimport NextAuth, { type DefaultSession, type NextAuthConfig } from \"next-auth\";\nimport Credentials from \"next-auth/providers/credentials\";\nimport Cognito from \"next-auth/providers/cognito\";\n\n//
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["// Auth.js v5 (the package is still distributed as `next-auth`, but treat\n// these as Auth.js v5 internally — docs at https://authjs.dev, NOT\n// next-auth.js.org which is v4 and incompatible).\n//\n// Provider strategy:\n// - Production: Cognito OIDC. Group membership from `cognito:groups`\n// drives role.\n// - Dev / preview: Credentials with a role picker, BUT shaped to mirror\n// Cognito's claim payload so consumers (callbacks, gates, audit logs)\n// never branch on environment. Same `sub`, `email`, `cognito:groups`\n// in both modes.\n//\n// IMPORTANT: do not let the dev-mode session diverge from production. If\n// you add a claim in prod, also add it (with a synthetic value) in dev.\n\nimport NextAuth, { type DefaultSession, type NextAuthConfig } from \"next-auth\";\nimport Credentials from \"next-auth/providers/credentials\";\nimport Cognito from \"next-auth/providers/cognito\";\n\n// Role is intentionally `string`. Consumer apps narrow it (e.g. via local\n// module augmentation or runtime check) to whatever taxonomy their Cognito\n// user pool defines. The auth package itself makes no assumptions about\n// what roles exist.\ndeclare module \"next-auth\" {\n interface Session {\n user: {\n role: string;\n } & DefaultSession[\"user\"];\n }\n interface User {\n role: string;\n }\n}\n\nexport type CreateAuthOptions = {\n /**\n * Path prefixes that require an authenticated session.\n * Empty array = no gating (rare).\n */\n authedRoutePrefixes: string[];\n /**\n * Page to redirect to when an unauthed user hits a gated route. Can be a\n * relative path (`\"/login\"`) for in-app login, or a fully-qualified URL\n * (`\"https://example.com/login\"`) to delegate login to a peer app on a\n * sibling subdomain or the apex of a path-routed deployment.\n * Default: `/login`.\n */\n signInPage?: string;\n /**\n * Cookie domain for the session token. Set this to the parent domain\n * (e.g. `.example.com`) when running across multiple subdomains so the\n * session JWT is readable by every app sharing that parent. For\n * path-routed deployments under a single domain, leave unset (host-only\n * is correct).\n *\n * Default: read from `process.env.AUTH_COOKIE_DOMAIN`; if unset, Auth.js\n * defaults to host-only (current request hostname).\n *\n * In dev (NODE_ENV !== \"production\"), this is ignored — cookies stay\n * scoped to localhost so per-port apps don't collide.\n */\n cookieDomain?: string;\n /**\n * Override prod/dev detection. Default reads NODE_ENV.\n */\n isProd?: boolean;\n /**\n * The JWT signing secret. If not provided, falls back to\n * `process.env.AUTH_SECRET`. Pass this from a runtime fetch (e.g. AWS\n * Secrets Manager via @aws-sdk/client-secrets-manager) to keep the secret\n * out of Lambda environment variables and to support rotation without\n * redeploy (Lambda containers re-init periodically and pick up the new\n * value).\n */\n secret?: string;\n /**\n * Cognito OIDC provider config. Each field falls back to the matching\n * `AUTH_COGNITO_*` env var if not provided. Provide them explicitly to\n * fetch the client secret from Secrets Manager at runtime.\n */\n cognito?: {\n clientId?: string;\n clientSecret?: string;\n issuer?: string;\n };\n};\n\nfunction roleFromGroups(groups: unknown): string {\n if (Array.isArray(groups) && groups.length > 0) {\n return String(groups[0]).toLowerCase();\n }\n return \"visitor\";\n}\n\n/**\n * Build an Auth.js v5 NextAuth() invocation. Each consuming app calls this\n * once at module scope and re-exports the returned `handlers`, `auth`,\n * `signIn`, `signOut`.\n *\n * Secrets default to env vars for simple deploys; pass them as options to\n * support runtime fetching from a secret store.\n */\nexport function createAuth(opts: CreateAuthOptions) {\n const isProd = opts.isProd ?? process.env.NODE_ENV === \"production\";\n const signInPage = opts.signInPage ?? \"/login\";\n const cookieDomain = isProd\n ? (opts.cookieDomain ?? process.env.AUTH_COOKIE_DOMAIN)\n : undefined;\n\n const SECRET =\n opts.secret ??\n process.env.AUTH_SECRET ??\n (isProd ? undefined : \"dev-only-fallback-not-for-prod\");\n\n const cognitoClientId = opts.cognito?.clientId ?? process.env.AUTH_COGNITO_ID;\n const cognitoClientSecret =\n opts.cognito?.clientSecret ?? process.env.AUTH_COGNITO_SECRET;\n const cognitoIssuer = opts.cognito?.issuer ?? process.env.AUTH_COGNITO_ISSUER;\n\n const config: NextAuthConfig = {\n secret: SECRET,\n cookies: cookieDomain\n ? {\n sessionToken: {\n name: \"authjs.session-token\",\n options: {\n domain: cookieDomain,\n sameSite: \"lax\",\n secure: true,\n httpOnly: true,\n path: \"/\",\n },\n },\n }\n : undefined,\n providers: isProd\n ? [\n Cognito({\n clientId: cognitoClientId,\n clientSecret: cognitoClientSecret,\n issuer: cognitoIssuer,\n }),\n ]\n : [\n Credentials({\n name: \"Mock role (dev only)\",\n credentials: {\n role: {\n label: \"Role\",\n type: \"text\",\n placeholder: \"any role string\",\n },\n },\n authorize: async (credentials) => {\n const role = credentials?.role as string | undefined;\n if (!role) return null;\n const display = role.charAt(0).toUpperCase() + role.slice(1);\n return {\n id: `mock-${role}`,\n name: `${display} (mock)`,\n email: `${role}@example.local`,\n role,\n };\n },\n }),\n ],\n session: { strategy: \"jwt\" },\n callbacks: {\n jwt: ({ token, user, profile }) => {\n if (user) {\n token.sub ??= user.id ?? undefined;\n token.email ??= user.email ?? undefined;\n if (!isProd && (user as { role?: string }).role) {\n (token as Record<string, unknown>)[\"cognito:groups\"] = [\n (user as { role: string }).role,\n ];\n }\n }\n if (isProd && profile) {\n const groups = (profile as Record<string, unknown>)[\"cognito:groups\"];\n if (groups) {\n (token as Record<string, unknown>)[\"cognito:groups\"] = groups;\n }\n }\n return token;\n },\n session: ({ session, token }) => {\n session.user.role = roleFromGroups(\n (token as Record<string, unknown>)[\"cognito:groups\"],\n );\n return session;\n },\n authorized: ({ auth: session, request: { nextUrl } }) => {\n const path = nextUrl.pathname;\n const isAuthedRoute = opts.authedRoutePrefixes.some(\n (prefix) => path === prefix || path.startsWith(`${prefix}/`),\n );\n if (!session && isAuthedRoute) return false;\n return true;\n },\n },\n pages: { signIn: signInPage },\n trustHost: true,\n };\n\n return NextAuth(config);\n}\n\n/**\n * Re-export of NextAuthConfig for consumers that want to extend the config\n * shape returned by createAuth().\n */\nexport type { NextAuthConfig } from \"next-auth\";\n"],"mappings":"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","names":["Cognito","Credentials","NextAuth"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import { type DefaultSession } from "next-auth";
|
|
2
|
-
export type Role = "visitor" | "broker" | "company_admin" | "manager" | "agent" | "admin";
|
|
3
2
|
declare module "next-auth" {
|
|
4
3
|
interface Session {
|
|
5
4
|
user: {
|
|
6
|
-
role:
|
|
5
|
+
role: string;
|
|
7
6
|
} & DefaultSession["user"];
|
|
8
7
|
}
|
|
9
8
|
interface User {
|
|
10
|
-
role:
|
|
9
|
+
role: string;
|
|
11
10
|
}
|
|
12
11
|
}
|
|
13
12
|
export type CreateAuthOptions = {
|
|
@@ -19,14 +18,18 @@ export type CreateAuthOptions = {
|
|
|
19
18
|
/**
|
|
20
19
|
* Page to redirect to when an unauthed user hits a gated route. Can be a
|
|
21
20
|
* relative path (`"/login"`) for in-app login, or a fully-qualified URL
|
|
22
|
-
* (`"https://
|
|
23
|
-
*
|
|
21
|
+
* (`"https://example.com/login"`) to delegate login to a peer app on a
|
|
22
|
+
* sibling subdomain or the apex of a path-routed deployment.
|
|
23
|
+
* Default: `/login`.
|
|
24
24
|
*/
|
|
25
25
|
signInPage?: string;
|
|
26
26
|
/**
|
|
27
27
|
* Cookie domain for the session token. Set this to the parent domain
|
|
28
|
-
* (e.g. `.
|
|
29
|
-
*
|
|
28
|
+
* (e.g. `.example.com`) when running across multiple subdomains so the
|
|
29
|
+
* session JWT is readable by every app sharing that parent. For
|
|
30
|
+
* path-routed deployments under a single domain, leave unset (host-only
|
|
31
|
+
* is correct).
|
|
32
|
+
*
|
|
30
33
|
* Default: read from `process.env.AUTH_COOKIE_DOMAIN`; if unset, Auth.js
|
|
31
34
|
* defaults to host-only (current request hostname).
|
|
32
35
|
*
|
|
@@ -38,28 +41,38 @@ export type CreateAuthOptions = {
|
|
|
38
41
|
* Override prod/dev detection. Default reads NODE_ENV.
|
|
39
42
|
*/
|
|
40
43
|
isProd?: boolean;
|
|
44
|
+
/**
|
|
45
|
+
* The JWT signing secret. If not provided, falls back to
|
|
46
|
+
* `process.env.AUTH_SECRET`. Pass this from a runtime fetch (e.g. AWS
|
|
47
|
+
* Secrets Manager via @aws-sdk/client-secrets-manager) to keep the secret
|
|
48
|
+
* out of Lambda environment variables and to support rotation without
|
|
49
|
+
* redeploy (Lambda containers re-init periodically and pick up the new
|
|
50
|
+
* value).
|
|
51
|
+
*/
|
|
52
|
+
secret?: string;
|
|
53
|
+
/**
|
|
54
|
+
* Cognito OIDC provider config. Each field falls back to the matching
|
|
55
|
+
* `AUTH_COGNITO_*` env var if not provided. Provide them explicitly to
|
|
56
|
+
* fetch the client secret from Secrets Manager at runtime.
|
|
57
|
+
*/
|
|
58
|
+
cognito?: {
|
|
59
|
+
clientId?: string;
|
|
60
|
+
clientSecret?: string;
|
|
61
|
+
issuer?: string;
|
|
62
|
+
};
|
|
41
63
|
};
|
|
42
64
|
/**
|
|
43
65
|
* Build an Auth.js v5 NextAuth() invocation. Each consuming app calls this
|
|
44
66
|
* once at module scope and re-exports the returned `handlers`, `auth`,
|
|
45
67
|
* `signIn`, `signOut`.
|
|
46
68
|
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
69
|
+
* Secrets default to env vars for simple deploys; pass them as options to
|
|
70
|
+
* support runtime fetching from a secret store.
|
|
49
71
|
*/
|
|
50
72
|
export declare function createAuth(opts: CreateAuthOptions): import("next-auth").NextAuthResult;
|
|
51
73
|
/**
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
* named-export form throws "TypeError: adapterFn is not a function".
|
|
55
|
-
*
|
|
56
|
-
* Usage:
|
|
57
|
-
* // src/proxy.ts
|
|
58
|
-
* import { auth } from "@/lib/auth";
|
|
59
|
-
* export default auth;
|
|
60
|
-
* export const config = {
|
|
61
|
-
* matcher: ["/dashboard", "/dashboard/:path*"],
|
|
62
|
-
* };
|
|
74
|
+
* Re-export of NextAuthConfig for consumers that want to extend the config
|
|
75
|
+
* shape returned by createAuth().
|
|
63
76
|
*/
|
|
64
77
|
export type { NextAuthConfig } from "next-auth";
|
|
65
78
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAeA,OAAiB,EAAE,KAAK,cAAc,EAAuB,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAeA,OAAiB,EAAE,KAAK,cAAc,EAAuB,MAAM,WAAW,CAAC;AAQ/E,OAAO,QAAQ,WAAW,CAAC;IACzB,UAAU,OAAO;QACf,IAAI,EAAE;YACJ,IAAI,EAAE,MAAM,CAAC;SACd,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;KAC5B;IACD,UAAU,IAAI;QACZ,IAAI,EAAE,MAAM,CAAC;KACd;CACF;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B;;;OAGG;IACH,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;;;;;;;;OAYG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;OAEG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,OAAO,CAAC,EAAE;QACR,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;CACH,CAAC;AASF;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,iBAAiB,sCAwGjD;AAED;;;GAGG;AACH,YAAY,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -2,18 +2,9 @@
|
|
|
2
2
|
import NextAuth from "next-auth";
|
|
3
3
|
import Credentials from "next-auth/providers/credentials";
|
|
4
4
|
import Cognito from "next-auth/providers/cognito";
|
|
5
|
-
var VALID_ROLES = [
|
|
6
|
-
"visitor",
|
|
7
|
-
"broker",
|
|
8
|
-
"company_admin",
|
|
9
|
-
"manager",
|
|
10
|
-
"agent",
|
|
11
|
-
"admin"
|
|
12
|
-
];
|
|
13
5
|
function roleFromGroups(groups) {
|
|
14
6
|
if (Array.isArray(groups) && groups.length > 0) {
|
|
15
|
-
|
|
16
|
-
if (VALID_ROLES.includes(first)) return first;
|
|
7
|
+
return String(groups[0]).toLowerCase();
|
|
17
8
|
}
|
|
18
9
|
return "visitor";
|
|
19
10
|
}
|
|
@@ -21,7 +12,10 @@ function createAuth(opts) {
|
|
|
21
12
|
const isProd = opts.isProd ?? process.env.NODE_ENV === "production";
|
|
22
13
|
const signInPage = opts.signInPage ?? "/login";
|
|
23
14
|
const cookieDomain = isProd ? opts.cookieDomain ?? process.env.AUTH_COOKIE_DOMAIN : void 0;
|
|
24
|
-
const SECRET = process.env.AUTH_SECRET ?? (isProd ? void 0 : "dev-only-fallback-not-for-prod");
|
|
15
|
+
const SECRET = opts.secret ?? process.env.AUTH_SECRET ?? (isProd ? void 0 : "dev-only-fallback-not-for-prod");
|
|
16
|
+
const cognitoClientId = opts.cognito?.clientId ?? process.env.AUTH_COGNITO_ID;
|
|
17
|
+
const cognitoClientSecret = opts.cognito?.clientSecret ?? process.env.AUTH_COGNITO_SECRET;
|
|
18
|
+
const cognitoIssuer = opts.cognito?.issuer ?? process.env.AUTH_COGNITO_ISSUER;
|
|
25
19
|
const config = {
|
|
26
20
|
secret: SECRET,
|
|
27
21
|
cookies: cookieDomain ? {
|
|
@@ -38,9 +32,9 @@ function createAuth(opts) {
|
|
|
38
32
|
} : void 0,
|
|
39
33
|
providers: isProd ? [
|
|
40
34
|
Cognito({
|
|
41
|
-
clientId:
|
|
42
|
-
clientSecret:
|
|
43
|
-
issuer:
|
|
35
|
+
clientId: cognitoClientId,
|
|
36
|
+
clientSecret: cognitoClientSecret,
|
|
37
|
+
issuer: cognitoIssuer
|
|
44
38
|
})
|
|
45
39
|
] : [
|
|
46
40
|
Credentials({
|
|
@@ -49,12 +43,12 @@ function createAuth(opts) {
|
|
|
49
43
|
role: {
|
|
50
44
|
label: "Role",
|
|
51
45
|
type: "text",
|
|
52
|
-
placeholder: "
|
|
46
|
+
placeholder: "any role string"
|
|
53
47
|
}
|
|
54
48
|
},
|
|
55
49
|
authorize: async (credentials) => {
|
|
56
50
|
const role = credentials?.role;
|
|
57
|
-
if (!role
|
|
51
|
+
if (!role) return null;
|
|
58
52
|
const display = role.charAt(0).toUpperCase() + role.slice(1);
|
|
59
53
|
return {
|
|
60
54
|
id: `mock-${role}`,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["// Auth.js v5 (the package is still distributed as `next-auth`, but treat\n// these as Auth.js v5 internally — docs at https://authjs.dev, NOT\n// next-auth.js.org which is v4 and incompatible).\n//\n// Provider strategy:\n// - Production: Cognito OIDC. Group membership from `cognito:groups`\n// drives role.\n// - Dev / preview: Credentials with a role picker, BUT shaped to mirror\n// Cognito's claim payload so consumers (callbacks, gates, audit logs)\n// never branch on environment. Same `sub`, `email`, `cognito:groups`\n// in both modes.\n//\n// IMPORTANT: do not let the dev-mode session diverge from production. If\n// you add a claim in prod, also add it (with a synthetic value) in dev.\n\nimport NextAuth, { type DefaultSession, type NextAuthConfig } from \"next-auth\";\nimport Credentials from \"next-auth/providers/credentials\";\nimport Cognito from \"next-auth/providers/cognito\";\n\n//
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["// Auth.js v5 (the package is still distributed as `next-auth`, but treat\n// these as Auth.js v5 internally — docs at https://authjs.dev, NOT\n// next-auth.js.org which is v4 and incompatible).\n//\n// Provider strategy:\n// - Production: Cognito OIDC. Group membership from `cognito:groups`\n// drives role.\n// - Dev / preview: Credentials with a role picker, BUT shaped to mirror\n// Cognito's claim payload so consumers (callbacks, gates, audit logs)\n// never branch on environment. Same `sub`, `email`, `cognito:groups`\n// in both modes.\n//\n// IMPORTANT: do not let the dev-mode session diverge from production. If\n// you add a claim in prod, also add it (with a synthetic value) in dev.\n\nimport NextAuth, { type DefaultSession, type NextAuthConfig } from \"next-auth\";\nimport Credentials from \"next-auth/providers/credentials\";\nimport Cognito from \"next-auth/providers/cognito\";\n\n// Role is intentionally `string`. Consumer apps narrow it (e.g. via local\n// module augmentation or runtime check) to whatever taxonomy their Cognito\n// user pool defines. The auth package itself makes no assumptions about\n// what roles exist.\ndeclare module \"next-auth\" {\n interface Session {\n user: {\n role: string;\n } & DefaultSession[\"user\"];\n }\n interface User {\n role: string;\n }\n}\n\nexport type CreateAuthOptions = {\n /**\n * Path prefixes that require an authenticated session.\n * Empty array = no gating (rare).\n */\n authedRoutePrefixes: string[];\n /**\n * Page to redirect to when an unauthed user hits a gated route. Can be a\n * relative path (`\"/login\"`) for in-app login, or a fully-qualified URL\n * (`\"https://example.com/login\"`) to delegate login to a peer app on a\n * sibling subdomain or the apex of a path-routed deployment.\n * Default: `/login`.\n */\n signInPage?: string;\n /**\n * Cookie domain for the session token. Set this to the parent domain\n * (e.g. `.example.com`) when running across multiple subdomains so the\n * session JWT is readable by every app sharing that parent. For\n * path-routed deployments under a single domain, leave unset (host-only\n * is correct).\n *\n * Default: read from `process.env.AUTH_COOKIE_DOMAIN`; if unset, Auth.js\n * defaults to host-only (current request hostname).\n *\n * In dev (NODE_ENV !== \"production\"), this is ignored — cookies stay\n * scoped to localhost so per-port apps don't collide.\n */\n cookieDomain?: string;\n /**\n * Override prod/dev detection. Default reads NODE_ENV.\n */\n isProd?: boolean;\n /**\n * The JWT signing secret. If not provided, falls back to\n * `process.env.AUTH_SECRET`. Pass this from a runtime fetch (e.g. AWS\n * Secrets Manager via @aws-sdk/client-secrets-manager) to keep the secret\n * out of Lambda environment variables and to support rotation without\n * redeploy (Lambda containers re-init periodically and pick up the new\n * value).\n */\n secret?: string;\n /**\n * Cognito OIDC provider config. Each field falls back to the matching\n * `AUTH_COGNITO_*` env var if not provided. Provide them explicitly to\n * fetch the client secret from Secrets Manager at runtime.\n */\n cognito?: {\n clientId?: string;\n clientSecret?: string;\n issuer?: string;\n };\n};\n\nfunction roleFromGroups(groups: unknown): string {\n if (Array.isArray(groups) && groups.length > 0) {\n return String(groups[0]).toLowerCase();\n }\n return \"visitor\";\n}\n\n/**\n * Build an Auth.js v5 NextAuth() invocation. Each consuming app calls this\n * once at module scope and re-exports the returned `handlers`, `auth`,\n * `signIn`, `signOut`.\n *\n * Secrets default to env vars for simple deploys; pass them as options to\n * support runtime fetching from a secret store.\n */\nexport function createAuth(opts: CreateAuthOptions) {\n const isProd = opts.isProd ?? process.env.NODE_ENV === \"production\";\n const signInPage = opts.signInPage ?? \"/login\";\n const cookieDomain = isProd\n ? (opts.cookieDomain ?? process.env.AUTH_COOKIE_DOMAIN)\n : undefined;\n\n const SECRET =\n opts.secret ??\n process.env.AUTH_SECRET ??\n (isProd ? undefined : \"dev-only-fallback-not-for-prod\");\n\n const cognitoClientId = opts.cognito?.clientId ?? process.env.AUTH_COGNITO_ID;\n const cognitoClientSecret =\n opts.cognito?.clientSecret ?? process.env.AUTH_COGNITO_SECRET;\n const cognitoIssuer = opts.cognito?.issuer ?? process.env.AUTH_COGNITO_ISSUER;\n\n const config: NextAuthConfig = {\n secret: SECRET,\n cookies: cookieDomain\n ? {\n sessionToken: {\n name: \"authjs.session-token\",\n options: {\n domain: cookieDomain,\n sameSite: \"lax\",\n secure: true,\n httpOnly: true,\n path: \"/\",\n },\n },\n }\n : undefined,\n providers: isProd\n ? [\n Cognito({\n clientId: cognitoClientId,\n clientSecret: cognitoClientSecret,\n issuer: cognitoIssuer,\n }),\n ]\n : [\n Credentials({\n name: \"Mock role (dev only)\",\n credentials: {\n role: {\n label: \"Role\",\n type: \"text\",\n placeholder: \"any role string\",\n },\n },\n authorize: async (credentials) => {\n const role = credentials?.role as string | undefined;\n if (!role) return null;\n const display = role.charAt(0).toUpperCase() + role.slice(1);\n return {\n id: `mock-${role}`,\n name: `${display} (mock)`,\n email: `${role}@example.local`,\n role,\n };\n },\n }),\n ],\n session: { strategy: \"jwt\" },\n callbacks: {\n jwt: ({ token, user, profile }) => {\n if (user) {\n token.sub ??= user.id ?? undefined;\n token.email ??= user.email ?? undefined;\n if (!isProd && (user as { role?: string }).role) {\n (token as Record<string, unknown>)[\"cognito:groups\"] = [\n (user as { role: string }).role,\n ];\n }\n }\n if (isProd && profile) {\n const groups = (profile as Record<string, unknown>)[\"cognito:groups\"];\n if (groups) {\n (token as Record<string, unknown>)[\"cognito:groups\"] = groups;\n }\n }\n return token;\n },\n session: ({ session, token }) => {\n session.user.role = roleFromGroups(\n (token as Record<string, unknown>)[\"cognito:groups\"],\n );\n return session;\n },\n authorized: ({ auth: session, request: { nextUrl } }) => {\n const path = nextUrl.pathname;\n const isAuthedRoute = opts.authedRoutePrefixes.some(\n (prefix) => path === prefix || path.startsWith(`${prefix}/`),\n );\n if (!session && isAuthedRoute) return false;\n return true;\n },\n },\n pages: { signIn: signInPage },\n trustHost: true,\n };\n\n return NextAuth(config);\n}\n\n/**\n * Re-export of NextAuthConfig for consumers that want to extend the config\n * shape returned by createAuth().\n */\nexport type { NextAuthConfig } from \"next-auth\";\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@augmenting-integrations/auth",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0",
|
|
4
4
|
"description": "Auth.js v5 factory: Cognito in prod, Credentials role-picker in dev. Same JWT shape (sub, email, cognito:groups) regardless of provider.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"publishConfig": {
|