@kanzo-tech/auth 0.29.1 → 0.30.1

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.
Files changed (89) hide show
  1. package/README.md +36 -23
  2. package/dist/bff-auth.d.ts +1 -2
  3. package/dist/bff-auth.d.ts.map +1 -1
  4. package/dist/bff-auth.js +82 -77
  5. package/dist/bff-auth.js.map +1 -1
  6. package/dist/can.d.ts +13 -9
  7. package/dist/can.d.ts.map +1 -1
  8. package/dist/can.js +6 -6
  9. package/dist/can.js.map +1 -1
  10. package/dist/gate.d.ts +4 -4
  11. package/dist/gate.d.ts.map +1 -1
  12. package/dist/gate.js +8 -9
  13. package/dist/gate.js.map +1 -1
  14. package/dist/index.d.ts +11 -19
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +17 -23
  17. package/dist/index.js.map +1 -1
  18. package/dist/issuer.d.ts +16 -0
  19. package/dist/issuer.d.ts.map +1 -1
  20. package/dist/issuer.js +43 -25
  21. package/dist/issuer.js.map +1 -1
  22. package/dist/next-auth.d.ts +66 -0
  23. package/dist/next-auth.d.ts.map +1 -0
  24. package/dist/next-auth.js +43 -0
  25. package/dist/next-auth.js.map +1 -0
  26. package/dist/next-bound.d.ts +89 -0
  27. package/dist/next-bound.d.ts.map +1 -0
  28. package/dist/next-bound.js +48 -0
  29. package/dist/next-bound.js.map +1 -0
  30. package/dist/next-gate.d.ts +4 -0
  31. package/dist/next-gate.d.ts.map +1 -0
  32. package/dist/next-gate.js +74 -0
  33. package/dist/next-gate.js.map +1 -0
  34. package/dist/next-proxy.d.ts +15 -24
  35. package/dist/next-proxy.d.ts.map +1 -1
  36. package/dist/next-proxy.js +47 -39
  37. package/dist/next-proxy.js.map +1 -1
  38. package/dist/next-routes.d.ts +4 -21
  39. package/dist/next-routes.d.ts.map +1 -1
  40. package/dist/next-routes.js +83 -64
  41. package/dist/next-routes.js.map +1 -1
  42. package/dist/next.d.ts +16 -41
  43. package/dist/next.d.ts.map +1 -1
  44. package/dist/next.js +2 -10
  45. package/dist/next.js.map +1 -1
  46. package/dist/server.d.ts +60 -38
  47. package/dist/server.d.ts.map +1 -1
  48. package/dist/server.js +183 -159
  49. package/dist/server.js.map +1 -1
  50. package/dist/store.d.ts +102 -20
  51. package/dist/store.d.ts.map +1 -1
  52. package/dist/store.js +56 -21
  53. package/dist/store.js.map +1 -1
  54. package/dist/types.d.ts +40 -23
  55. package/dist/types.d.ts.map +1 -1
  56. package/dist/types.js.map +1 -1
  57. package/dist/use-session.d.ts +6 -1
  58. package/dist/use-session.d.ts.map +1 -1
  59. package/dist/use-session.js +9 -7
  60. package/dist/use-session.js.map +1 -1
  61. package/package.json +11 -30
  62. package/dist/auth-fetch.d.ts +0 -44
  63. package/dist/auth-fetch.d.ts.map +0 -1
  64. package/dist/auth-fetch.js +0 -21
  65. package/dist/auth-fetch.js.map +0 -1
  66. package/dist/browser.d.ts +0 -61
  67. package/dist/browser.d.ts.map +0 -1
  68. package/dist/browser.js +0 -130
  69. package/dist/browser.js.map +0 -1
  70. package/dist/host.d.ts +0 -22
  71. package/dist/host.d.ts.map +0 -1
  72. package/dist/host.js +0 -10
  73. package/dist/host.js.map +0 -1
  74. package/dist/next-middleware.d.ts +0 -23
  75. package/dist/next-middleware.d.ts.map +0 -1
  76. package/dist/next-middleware.js +0 -23
  77. package/dist/next-middleware.js.map +0 -1
  78. package/dist/next-session.d.ts +0 -44
  79. package/dist/next-session.d.ts.map +0 -1
  80. package/dist/next-session.js +0 -11
  81. package/dist/next-session.js.map +0 -1
  82. package/dist/next-token.d.ts +0 -56
  83. package/dist/next-token.d.ts.map +0 -1
  84. package/dist/next-token.js +0 -9
  85. package/dist/next-token.js.map +0 -1
  86. package/dist/use-organization.d.ts +0 -22
  87. package/dist/use-organization.d.ts.map +0 -1
  88. package/dist/use-organization.js +0 -20
  89. package/dist/use-organization.js.map +0 -1
@@ -1,11 +0,0 @@
1
- import { cookies as o } from "next/headers";
2
- import { cache as i } from "react";
3
- import { relyingParty as e } from "./server.js";
4
- function m(r) {
5
- const t = e({ ...r, redirectUri: "" });
6
- return i(async () => t.read((await o()).toString()));
7
- }
8
- export {
9
- m as authSession
10
- };
11
- //# sourceMappingURL=next-session.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"next-session.js","sources":["../src/next-session.ts"],"sourcesContent":["import { cookies } from \"next/headers\";\nimport { cache } from \"react\";\nimport { relyingParty, type RelyingPartyConfig } from \"./server\";\nimport type { Session } from \"./types\";\n\n/**\n * The session a React Server Component can read, without a request object in hand.\n *\n * An RSC is handed no `Request`; `next/headers` is how it reaches the one it is rendering for, and\n * that import is what makes this module — and only this module of the three — Node-only. It is\n * also what earns the whole door its place on a subpath: *a part belongs on a subpath only if it\n * imports that subpath's engine.*\n *\n * ## Why a factory, when the call site is `await getSession()`\n *\n * The call site is preserved exactly; what moved is where the binding is made. A\n * zero-argument import would have to find its secret somewhere ambient — an environment variable\n * this package would then be naming and documenting forever — and it could never be given a\n * {@link SessionStore}, which is an object and not a string. So the consumer binds it once, in the\n * same module that already holds the config it hands {@link authRoutes}:\n *\n * ```ts\n * // auth.ts\n * export const getSession = authSession({ issuer, clientId, clientSecret, secret });\n * ```\n *\n * and every server component writes `await getSession()`. That also makes the three names of this\n * door one shape — `authRoutes`, `authSession`, `authMiddleware` are all factories over a config —\n * rather than two factories and an exception.\n *\n * ## `cache`, and what it is for\n *\n * React's `cache` scopes memoization to one request, so a page that asks in a layout, in a\n * breadcrumb and in a menu unseals the cookie once. A host that wraps its own reader does it for\n * exactly this reason. **It is dormant outside a React request scope** — `cache`\n * with no dispatcher simply calls through — which is why the test beside this file asserts the\n * answers and not the number of reads.\n */\n\n/**\n * What reading a session needs, which is strictly less than signing one in.\n *\n * `redirectUri` is absent because no authorization request is built here: {@link RelyingParty.read}\n * unseals a cookie and asks the store, and neither of those has a browser to send anywhere.\n */\nexport type AuthSessionConfig = Omit<RelyingPartyConfig, \"redirectUri\">;\n\nexport function authSession(config: AuthSessionConfig): () => Promise<Session | null> {\n // The redirect URI is a required field of the confidential client and an unused one on this\n // path. Naming it here rather than making it optional on `RelyingPartyConfig` keeps the type that\n // signs people in honest: a sign-in without a redirect URI is a configuration error.\n const auth = relyingParty({ ...config, redirectUri: \"\" });\n\n return cache(async () => auth.read((await cookies()).toString()));\n}\n"],"names":["authSession","config","auth","relyingParty","cache","cookies"],"mappings":";;;AA+CO,SAASA,EAAYC,GAA0D;AAIpF,QAAMC,IAAOC,EAAa,EAAE,GAAGF,GAAQ,aAAa,IAAI;AAExD,SAAOG,EAAM,YAAYF,EAAK,MAAM,MAAMG,EAAA,GAAW,SAAA,CAAU,CAAC;AAClE;"}
@@ -1,56 +0,0 @@
1
- import { AuthSessionConfig } from './next-session';
2
- import { Token } from './server';
3
- /**
4
- * The access token a request carries, renewed when it is about to expire.
5
- *
6
- * ```ts
7
- * // auth.ts
8
- * export const getToken = authToken({ issuer, clientId, clientSecret, secret });
9
- *
10
- * // app/api/reports/route.ts
11
- * export async function GET(request: Request) {
12
- * const held = await getToken(request.headers.get("cookie"));
13
- * if (held === null) return new Response(null, { status: 401 });
14
- *
15
- * const upstream = await fetch(REPORTS, {
16
- * headers: { authorization: `Bearer ${held.accessToken}` },
17
- * });
18
- * const answer = new Response(upstream.body, upstream);
19
- * for (const cookie of held.cookies) answer.headers.append("set-cookie", cookie);
20
- * return answer;
21
- * }
22
- * ```
23
- *
24
- * This is the complement of {@link authSession}: that one answers *who*, this one answers *with
25
- * what*. Both are factories over the same config, for the reason `next-session.ts` gives.
26
- *
27
- * ## Why this exists at all, rather than a product reaching into the cookie
28
- *
29
- * Without it the only way to a bearer token is to rebuild the sealed cookie by hand — the same
30
- * name, the same `maxAge`, the same secret — and open it. That is this package's protocol,
31
- * reimplemented in a product, held together by nothing but two constants agreeing: change the
32
- * default cookie name or the default lifetime here and that product breaks in silence. A protocol
33
- * a consumer must re-derive is a protocol the package failed to expose.
34
- *
35
- * ## The cookie is an argument, and that is the API design
36
- *
37
- * There is no zero-argument form, and the absence is the point. **A React Server Component cannot
38
- * write cookies in Next**, and a renewal it dropped would not be a stale token — under the
39
- * rotation RFC 10017 requires, the refresh token this call spent is gone and the one it minted was
40
- * never persisted, so the session is over. A zero-argument form reading `next/headers` would work
41
- * in an RSC exactly well enough to destroy the session on the first renewal.
42
- *
43
- * So the signature asks for the `Cookie` header, which a **route handler**, a **middleware** and a
44
- * **server action** have and an RSC does not — and each of those can send the `Set-Cookie` that
45
- * comes back. An RSC that wants to know who is signed in calls {@link authSession}, which only
46
- * ever reads.
47
- *
48
- * ## Attaching `cookies` is not optional
49
- *
50
- * It is empty when nothing was renewed. When it is not empty it carries the only refresh token
51
- * still valid, and dropping it ends the session at the next renewal.
52
- */
53
- export declare function authToken(config: AuthSessionConfig): (cookie: string | null | undefined, options?: {
54
- readonly renewWithin?: number;
55
- }) => Promise<Token | null>;
56
- //# sourceMappingURL=next-token.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"next-token.d.ts","sourceRoot":"","sources":["../src/next-token.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAgB,KAAK,KAAK,EAAE,MAAM,UAAU,CAAC;AAEpD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AACH,wBAAgB,SAAS,CACvB,MAAM,EAAE,iBAAiB,GACxB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAAE,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,KAAK,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CAM3G"}
@@ -1,9 +0,0 @@
1
- import { relyingParty as o } from "./server.js";
2
- function u(r) {
3
- const t = o({ ...r, redirectUri: "" });
4
- return (e, n) => t.token(e, n);
5
- }
6
- export {
7
- u as authToken
8
- };
9
- //# sourceMappingURL=next-token.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"next-token.js","sources":["../src/next-token.ts"],"sourcesContent":["import type { AuthSessionConfig } from \"./next-session\";\nimport { relyingParty, type Token } from \"./server\";\n\n/**\n * The access token a request carries, renewed when it is about to expire.\n *\n * ```ts\n * // auth.ts\n * export const getToken = authToken({ issuer, clientId, clientSecret, secret });\n *\n * // app/api/reports/route.ts\n * export async function GET(request: Request) {\n * const held = await getToken(request.headers.get(\"cookie\"));\n * if (held === null) return new Response(null, { status: 401 });\n *\n * const upstream = await fetch(REPORTS, {\n * headers: { authorization: `Bearer ${held.accessToken}` },\n * });\n * const answer = new Response(upstream.body, upstream);\n * for (const cookie of held.cookies) answer.headers.append(\"set-cookie\", cookie);\n * return answer;\n * }\n * ```\n *\n * This is the complement of {@link authSession}: that one answers *who*, this one answers *with\n * what*. Both are factories over the same config, for the reason `next-session.ts` gives.\n *\n * ## Why this exists at all, rather than a product reaching into the cookie\n *\n * Without it the only way to a bearer token is to rebuild the sealed cookie by hand — the same\n * name, the same `maxAge`, the same secret — and open it. That is this package's protocol,\n * reimplemented in a product, held together by nothing but two constants agreeing: change the\n * default cookie name or the default lifetime here and that product breaks in silence. A protocol\n * a consumer must re-derive is a protocol the package failed to expose.\n *\n * ## The cookie is an argument, and that is the API design\n *\n * There is no zero-argument form, and the absence is the point. **A React Server Component cannot\n * write cookies in Next**, and a renewal it dropped would not be a stale token — under the\n * rotation RFC 10017 requires, the refresh token this call spent is gone and the one it minted was\n * never persisted, so the session is over. A zero-argument form reading `next/headers` would work\n * in an RSC exactly well enough to destroy the session on the first renewal.\n *\n * So the signature asks for the `Cookie` header, which a **route handler**, a **middleware** and a\n * **server action** have and an RSC does not — and each of those can send the `Set-Cookie` that\n * comes back. An RSC that wants to know who is signed in calls {@link authSession}, which only\n * ever reads.\n *\n * ## Attaching `cookies` is not optional\n *\n * It is empty when nothing was renewed. When it is not empty it carries the only refresh token\n * still valid, and dropping it ends the session at the next renewal.\n */\nexport function authToken(\n config: AuthSessionConfig,\n): (cookie: string | null | undefined, options?: { readonly renewWithin?: number }) => Promise<Token | null> {\n // The redirect URI is a required field of the confidential client and an unused one on this\n // path — no authorization request is built here — for the reason `next-session.ts` spells out.\n const auth = relyingParty({ ...config, redirectUri: \"\" });\n\n return (cookie, options) => auth.token(cookie, options);\n}\n"],"names":["authToken","config","auth","relyingParty","cookie","options"],"mappings":";AAqDO,SAASA,EACdC,GAC2G;AAG3G,QAAMC,IAAOC,EAAa,EAAE,GAAGF,GAAQ,aAAa,IAAI;AAExD,SAAO,CAACG,GAAQC,MAAYH,EAAK,MAAME,GAAQC,CAAO;AACxD;"}
@@ -1,22 +0,0 @@
1
- import { Organization } from './types';
2
- /**
3
- * Which organization this view is *in*, resolved per render rather than stored.
4
- *
5
- * The session says which organizations you belong to; the URL says which one you are looking at.
6
- * `Session` in `types.ts` carries why the second is never stored.
7
- *
8
- * `alias` names the organization explicitly; omitted, it is read from the hostname. A hostname
9
- * naming an organization this person does not belong to yields `organization: undefined` and
10
- * `isMember: false` — never a throw, and **never the first organization instead**. Falling back
11
- * is how someone ends up reading another customer's data believing it is their own.
12
- *
13
- * `isMember` answers about the *candidate*, so it is a different question from
14
- * `organizations.length > 0`: a product with one membership addressed at the wrong host is a member
15
- * of something and a member of nothing here.
16
- */
17
- export declare function useOrganization(alias?: string): {
18
- readonly organization: Organization | undefined;
19
- readonly organizations: readonly Organization[];
20
- readonly isMember: boolean;
21
- };
22
- //# sourceMappingURL=use-organization.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"use-organization.d.ts","sourceRoot":"","sources":["../src/use-organization.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAG5C;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG;IAC/C,QAAQ,CAAC,YAAY,EAAE,YAAY,GAAG,SAAS,CAAC;IAChD,QAAQ,CAAC,aAAa,EAAE,SAAS,YAAY,EAAE,CAAC;IAChD,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC5B,CAmBA"}
@@ -1,20 +0,0 @@
1
- "use client";
2
- import { useMemo as r } from "react";
3
- import { organizationOf as a } from "./can.js";
4
- import { organizationFromHost as e } from "./host.js";
5
- import { useSession as m } from "./use-session.js";
6
- function c(i) {
7
- const { session: o } = m();
8
- return r(() => {
9
- const n = i ?? (typeof window > "u" ? void 0 : e(window.location.hostname)), t = n === void 0 ? void 0 : a(o, n);
10
- return {
11
- organization: t,
12
- organizations: (o == null ? void 0 : o.organizations) ?? [],
13
- isMember: t !== void 0
14
- };
15
- }, [i, o]);
16
- }
17
- export {
18
- c as useOrganization
19
- };
20
- //# sourceMappingURL=use-organization.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"use-organization.js","sources":["../src/use-organization.ts"],"sourcesContent":["\"use client\";\n\nimport { useMemo } from \"react\";\nimport { organizationOf } from \"./can\";\nimport { organizationFromHost } from \"./host\";\nimport type { Organization } from \"./types\";\nimport { useSession } from \"./use-session\";\n\n/**\n * Which organization this view is *in*, resolved per render rather than stored.\n *\n * The session says which organizations you belong to; the URL says which one you are looking at.\n * `Session` in `types.ts` carries why the second is never stored.\n *\n * `alias` names the organization explicitly; omitted, it is read from the hostname. A hostname\n * naming an organization this person does not belong to yields `organization: undefined` and\n * `isMember: false` — never a throw, and **never the first organization instead**. Falling back\n * is how someone ends up reading another customer's data believing it is their own.\n *\n * `isMember` answers about the *candidate*, so it is a different question from\n * `organizations.length > 0`: a product with one membership addressed at the wrong host is a member\n * of something and a member of nothing here.\n */\nexport function useOrganization(alias?: string): {\n readonly organization: Organization | undefined;\n readonly organizations: readonly Organization[];\n readonly isMember: boolean;\n} {\n const { session } = useSession();\n\n return useMemo(() => {\n // Read at render, and undefined on a server. There is no hydration mismatch to manage: the\n // session itself arrives in the provider's effect, so the server render and the first client\n // render both resolve against `null` and agree whatever the hostname says.\n const candidate =\n alias ??\n (typeof window === \"undefined\" ? undefined : organizationFromHost(window.location.hostname));\n\n const organization = candidate === undefined ? undefined : organizationOf(session, candidate);\n\n return {\n organization,\n organizations: session?.organizations ?? [],\n isMember: organization !== undefined,\n };\n }, [alias, session]);\n}\n"],"names":[],"mappings":";;;;;AAuBO;AAKL;AAEA;AAIE;AAMA;AAAO;AACL;AACyC;AACd;AAAA;AAGjC;;;;"}