@kanzo-tech/auth 0.29.0 → 0.30.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/README.md +36 -23
- package/dist/bff-auth.d.ts +1 -2
- package/dist/bff-auth.d.ts.map +1 -1
- package/dist/bff-auth.js +82 -77
- package/dist/bff-auth.js.map +1 -1
- package/dist/can.d.ts +13 -9
- package/dist/can.d.ts.map +1 -1
- package/dist/can.js +6 -6
- package/dist/can.js.map +1 -1
- package/dist/gate.d.ts +4 -4
- package/dist/gate.d.ts.map +1 -1
- package/dist/gate.js +8 -9
- package/dist/gate.js.map +1 -1
- package/dist/index.d.ts +11 -19
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -23
- package/dist/index.js.map +1 -1
- package/dist/issuer.d.ts +16 -0
- package/dist/issuer.d.ts.map +1 -1
- package/dist/issuer.js +43 -25
- package/dist/issuer.js.map +1 -1
- package/dist/next-auth.d.ts +66 -0
- package/dist/next-auth.d.ts.map +1 -0
- package/dist/next-auth.js +43 -0
- package/dist/next-auth.js.map +1 -0
- package/dist/next-bound.d.ts +82 -0
- package/dist/next-bound.d.ts.map +1 -0
- package/dist/next-bound.js +27 -0
- package/dist/next-bound.js.map +1 -0
- package/dist/next-gate.d.ts +4 -0
- package/dist/next-gate.d.ts.map +1 -0
- package/dist/next-gate.js +74 -0
- package/dist/next-gate.js.map +1 -0
- package/dist/next-proxy.d.ts +15 -24
- package/dist/next-proxy.d.ts.map +1 -1
- package/dist/next-proxy.js +38 -33
- package/dist/next-proxy.js.map +1 -1
- package/dist/next-routes.d.ts +3 -21
- package/dist/next-routes.d.ts.map +1 -1
- package/dist/next-routes.js +93 -65
- package/dist/next-routes.js.map +1 -1
- package/dist/next.d.ts +16 -41
- package/dist/next.d.ts.map +1 -1
- package/dist/next.js +2 -10
- package/dist/next.js.map +1 -1
- package/dist/server.d.ts +60 -38
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +183 -159
- package/dist/server.js.map +1 -1
- package/dist/store.d.ts +102 -20
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +56 -21
- package/dist/store.js.map +1 -1
- package/dist/types.d.ts +40 -23
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/use-session.d.ts +6 -1
- package/dist/use-session.d.ts.map +1 -1
- package/dist/use-session.js +9 -7
- package/dist/use-session.js.map +1 -1
- package/package.json +10 -29
- package/dist/auth-fetch.d.ts +0 -44
- package/dist/auth-fetch.d.ts.map +0 -1
- package/dist/auth-fetch.js +0 -21
- package/dist/auth-fetch.js.map +0 -1
- package/dist/browser.d.ts +0 -61
- package/dist/browser.d.ts.map +0 -1
- package/dist/browser.js +0 -130
- package/dist/browser.js.map +0 -1
- package/dist/host.d.ts +0 -22
- package/dist/host.d.ts.map +0 -1
- package/dist/host.js +0 -10
- package/dist/host.js.map +0 -1
- package/dist/next-middleware.d.ts +0 -23
- package/dist/next-middleware.d.ts.map +0 -1
- package/dist/next-middleware.js +0 -23
- package/dist/next-middleware.js.map +0 -1
- package/dist/next-session.d.ts +0 -44
- package/dist/next-session.d.ts.map +0 -1
- package/dist/next-session.js +0 -11
- package/dist/next-session.js.map +0 -1
- package/dist/next-token.d.ts +0 -56
- package/dist/next-token.d.ts.map +0 -1
- package/dist/next-token.js +0 -9
- package/dist/next-token.js.map +0 -1
- package/dist/use-organization.d.ts +0 -22
- package/dist/use-organization.d.ts.map +0 -1
- package/dist/use-organization.js +0 -20
- package/dist/use-organization.js.map +0 -1
package/dist/next.d.ts
CHANGED
|
@@ -1,55 +1,30 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `@kanzo-tech/auth/next` — the Backend For Frontend
|
|
3
|
-
* has.
|
|
2
|
+
* `@kanzo-tech/auth/next` — the Backend For Frontend for an App Router product, as one object.
|
|
4
3
|
*
|
|
5
4
|
* ```ts
|
|
6
|
-
* //
|
|
7
|
-
* export const
|
|
5
|
+
* // lib/auth.ts
|
|
6
|
+
* export const auth = kanzoAuth(async () => ({ issuer, clientId, clientSecret, secret, store }));
|
|
8
7
|
*
|
|
9
|
-
* //
|
|
10
|
-
* export const
|
|
11
|
-
* export const
|
|
8
|
+
* // proxy.ts
|
|
9
|
+
* export const proxy = (request: NextRequest) => auth.proxy(request);
|
|
10
|
+
* export const config = { matcher: ["/((?!_next/static|_next/image|favicon.ico|.*\\..*).*)"] };
|
|
12
11
|
*
|
|
13
|
-
* //
|
|
14
|
-
* export const
|
|
12
|
+
* // app/api/auth/[...auth]/route.ts
|
|
13
|
+
* export const { GET, POST } = auth.routes;
|
|
15
14
|
* ```
|
|
16
15
|
*
|
|
17
|
-
* **
|
|
18
|
-
* party
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* `
|
|
23
|
-
*
|
|
24
|
-
* library's. `next.test.ts` holds the absence.
|
|
25
|
-
*
|
|
26
|
-
* ## Who may be asked what, and why the signatures differ
|
|
27
|
-
*
|
|
28
|
-
* `authSession` reads `next/headers` and answers an identity; `authToken` is handed a `Cookie`
|
|
29
|
-
* header and answers a credential *plus the cookies to set*. The asymmetry is not an oversight —
|
|
30
|
-
* **a React Server Component cannot write cookies in Next**, and a renewal whose `Set-Cookie` is
|
|
31
|
-
* dropped ends the session rather than merely failing, because the refresh token it spent is gone.
|
|
32
|
-
* So the read-only one is the one an RSC can reach for, and the renewing one asks for something
|
|
33
|
-
* only a route handler, a middleware or a server action has. `authProxy` is that pairing already
|
|
34
|
-
* assembled: a route file that forwards to a resource server with the bearer token attached.
|
|
16
|
+
* **One name.** The proxy, the routes, the resource-server forwarder and the server component's
|
|
17
|
+
* session are four pieces of one relying party, and `kanzoAuth` is that relying party: one issuer,
|
|
18
|
+
* one discovery cache, one store, one renewal per session. `can` on the root barrel is how a
|
|
19
|
+
* server component asks about a role, exactly as `Gate` asks in the browser. There is no
|
|
20
|
+
* `requireRole`: it would have added no new evaluation of a role, only a *throw*, and which throw —
|
|
21
|
+
* `forbidden()`, a redirect, a rendered explanation — is a product's answer and not a library's.
|
|
22
|
+
* `next.test.ts` holds the absence.
|
|
35
23
|
*
|
|
36
24
|
* ## This door must never reach React's client half
|
|
37
25
|
*
|
|
38
26
|
* The modules behind it import `./server` and `./claims` directly and never `./index`, for the
|
|
39
27
|
* reason `server.ts`'s own header gives. `next.test.ts` walks the relative imports from here.
|
|
40
|
-
*
|
|
41
|
-
* ## Why one barrel does not put `openid-client` on the edge
|
|
42
|
-
*
|
|
43
|
-
* `authMiddleware` runs in the edge runtime and must arrive with nothing behind it. It does:
|
|
44
|
-
* `next-middleware.ts` imports only `next/server`, the package is `sideEffects: false`, and the
|
|
45
|
-
* build writes one file per module (`preserveModules`), so a `middleware.ts` importing this barrel
|
|
46
|
-
* is left holding that one module. They are kept in one file each for exactly this reason rather
|
|
47
|
-
* than tidied together.
|
|
48
28
|
*/
|
|
49
|
-
export {
|
|
50
|
-
export { authProxy, type AuthProxyConfig, type AuthProxyHandlers } from './next-proxy';
|
|
51
|
-
export { authRoutes, type AuthRouteHandlers, type AuthRoutesConfig } from './next-routes';
|
|
52
|
-
export { authSession, type AuthSessionConfig } from './next-session';
|
|
53
|
-
export { authToken } from './next-token';
|
|
54
|
-
export type { Token } from './server';
|
|
29
|
+
export { kanzoAuth, type KanzoAuth, type KanzoAuthConfig } from './next-auth';
|
|
55
30
|
//# sourceMappingURL=next.d.ts.map
|
package/dist/next.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"next.d.ts","sourceRoot":"","sources":["../src/next.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"next.d.ts","sourceRoot":"","sources":["../src/next.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,EAAE,SAAS,EAAE,KAAK,SAAS,EAAE,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/next.js
CHANGED
|
@@ -1,13 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { authProxy as a } from "./next-proxy.js";
|
|
3
|
-
import { authRoutes as x } from "./next-routes.js";
|
|
4
|
-
import { authSession as h } from "./next-session.js";
|
|
5
|
-
import { authToken as p } from "./next-token.js";
|
|
1
|
+
import { kanzoAuth as t } from "./next-auth.js";
|
|
6
2
|
export {
|
|
7
|
-
t as
|
|
8
|
-
a as authProxy,
|
|
9
|
-
x as authRoutes,
|
|
10
|
-
h as authSession,
|
|
11
|
-
p as authToken
|
|
3
|
+
t as kanzoAuth
|
|
12
4
|
};
|
|
13
5
|
//# sourceMappingURL=next.js.map
|
package/dist/next.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"next.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"next.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
|
package/dist/server.d.ts
CHANGED
|
@@ -6,36 +6,49 @@ export interface Redirect {
|
|
|
6
6
|
readonly url: string;
|
|
7
7
|
readonly cookies: readonly string[];
|
|
8
8
|
}
|
|
9
|
-
/**
|
|
9
|
+
/**
|
|
10
|
+
* A live session after `refresh`: renewed, or still good. `cookies` is empty unless the ticket
|
|
11
|
+
* itself changed, which only a stateless store's re-seal does.
|
|
12
|
+
*/
|
|
10
13
|
export interface Renewed {
|
|
14
|
+
readonly ended: false;
|
|
11
15
|
readonly session: Session;
|
|
12
16
|
readonly cookies: readonly string[];
|
|
13
17
|
}
|
|
14
|
-
/** What `complete` answers: a renewal, plus where the person was going before they were asked who they are. */
|
|
15
|
-
export interface SignedIn extends Renewed {
|
|
16
|
-
readonly returnTo: string;
|
|
17
|
-
}
|
|
18
18
|
/**
|
|
19
|
-
*
|
|
19
|
+
* No live session: none was presented, the store no longer knows it, or the IdP refused to renew
|
|
20
|
+
* it. The ticket has been dropped, and `cookies` clears the one the browser holds — empty when it
|
|
21
|
+
* held none.
|
|
20
22
|
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* caller with nowhere to put a `Set-Cookie` is a caller that must not be asking for this.
|
|
23
|
+
* A result rather than an exception, because the cookies are the point: an ended session that
|
|
24
|
+
* forgets to clear its cookie is the zombie this replaced, a page drawn for a session the IdP had
|
|
25
|
+
* already closed.
|
|
25
26
|
*/
|
|
26
|
-
export interface
|
|
27
|
-
readonly
|
|
27
|
+
export interface Ended {
|
|
28
|
+
readonly ended: true;
|
|
29
|
+
/** `token/refused` when the IdP refused to renew it; `session/absent` when there was none to renew. */
|
|
30
|
+
readonly code: "session/absent" | "token/refused";
|
|
31
|
+
readonly cookies: readonly string[];
|
|
32
|
+
}
|
|
33
|
+
/** What `complete` answers: the new session, its cookies, and where the person was going. */
|
|
34
|
+
export interface SignedIn {
|
|
28
35
|
readonly session: Session;
|
|
29
36
|
readonly cookies: readonly string[];
|
|
37
|
+
readonly returnTo: string;
|
|
38
|
+
}
|
|
39
|
+
/** What `token` answers for a live session: the credential a resource server takes, and what to set. */
|
|
40
|
+
export interface Token extends Renewed {
|
|
41
|
+
readonly accessToken: string;
|
|
30
42
|
}
|
|
31
43
|
export interface RelyingPartyConfig extends IssuerConfig {
|
|
32
|
-
/** Registered at Keycloak, and where `complete` expects to be called. */
|
|
33
|
-
readonly redirectUri: string;
|
|
34
44
|
/** Seals the cookies. Any length; generate it. See `sealedCookie`. */
|
|
35
45
|
readonly secret: string | Uint8Array;
|
|
36
|
-
/**
|
|
46
|
+
/**
|
|
47
|
+
* Default `openid profile email organization:*`. Whatever is given, its organization scope is
|
|
48
|
+
* `organization:*` — or the one alias a sign-in names.
|
|
49
|
+
*/
|
|
37
50
|
readonly scope?: string;
|
|
38
|
-
/** Default {@link statelessStore}. Supply
|
|
51
|
+
/** Default {@link statelessStore}. Supply a `ticketStore` to end a session before it expires. */
|
|
39
52
|
readonly store?: SessionStore;
|
|
40
53
|
/** Session cookie lifetime in seconds. Default eight hours. */
|
|
41
54
|
readonly maxAge?: number;
|
|
@@ -43,45 +56,54 @@ export interface RelyingPartyConfig extends IssuerConfig {
|
|
|
43
56
|
readonly postLogoutRedirectUri?: string;
|
|
44
57
|
}
|
|
45
58
|
export interface RelyingParty {
|
|
46
|
-
/**
|
|
47
|
-
|
|
48
|
-
|
|
59
|
+
/**
|
|
60
|
+
* Leg one: the authorization URL, and the cookie that remembers this attempt.
|
|
61
|
+
*
|
|
62
|
+
* `redirectUri` is per call, because it is derived from the request that asked, and one relying
|
|
63
|
+
* party serves every origin a deployment answers on.
|
|
64
|
+
*/
|
|
65
|
+
begin(options: SignInOptions & {
|
|
66
|
+
readonly redirectUri: string;
|
|
67
|
+
}): Promise<Redirect>;
|
|
68
|
+
/**
|
|
69
|
+
* Leg two: the callback URL Keycloak returned to, the `Cookie` header it arrived with, and the
|
|
70
|
+
* `redirectUri` `begin` was given — which the token request must repeat exactly.
|
|
71
|
+
*/
|
|
49
72
|
complete(request: {
|
|
50
73
|
readonly url: string | URL;
|
|
51
74
|
readonly cookie: string | null;
|
|
75
|
+
readonly redirectUri: string;
|
|
52
76
|
}): Promise<SignedIn>;
|
|
53
|
-
/** The session a request carries, or `null`.
|
|
77
|
+
/** The session a request carries, or `null`. One store read; nothing is renewed. */
|
|
54
78
|
read(cookie: string | null | undefined): Promise<Session | null>;
|
|
55
79
|
/**
|
|
56
|
-
* The access token a request carries, renewed when it is
|
|
57
|
-
* is no session
|
|
80
|
+
* The access token a request carries, renewed in place when it is within `renewWithin` seconds
|
|
81
|
+
* of expiry (default 60) — or {@link Ended} when there is no live session.
|
|
58
82
|
*
|
|
59
83
|
* This is the *token-mediating backend*: the browser holds a cookie, the resource server is
|
|
60
|
-
* given a bearer token, and the two never meet.
|
|
61
|
-
*
|
|
62
|
-
* from — this one can answer with a `Set-Cookie` and therefore must be called somewhere that can
|
|
63
|
-
* send one.
|
|
64
|
-
*
|
|
65
|
-
* Renewal is single-flight per ticket, so a page that fires eight requests at an expiring token
|
|
66
|
-
* spends it once.
|
|
84
|
+
* given a bearer token, and the two never meet. Renewal is single-flight per ticket, so a page
|
|
85
|
+
* that fires eight requests at an expiring token spends it once.
|
|
67
86
|
*/
|
|
68
87
|
token(cookie: string | null | undefined, options?: {
|
|
69
88
|
readonly renewWithin?: number;
|
|
70
|
-
}): Promise<Token |
|
|
71
|
-
/**
|
|
72
|
-
|
|
73
|
-
*
|
|
74
|
-
* Single-flight per ticket across the whole process: a second concurrent call joins the first
|
|
75
|
-
* rather than replaying a token it already spent. See `renewals`.
|
|
76
|
-
*/
|
|
77
|
-
refresh(cookie: string | null | undefined): Promise<Renewed>;
|
|
89
|
+
}): Promise<Token | Ended>;
|
|
90
|
+
/** Spend the refresh token now, whatever the access token's expiry. See {@link token}. */
|
|
91
|
+
refresh(cookie: string | null | undefined): Promise<Renewed | Ended>;
|
|
78
92
|
/** RP-initiated logout: forget the record here, clear the cookie, and end it at the IdP too. */
|
|
79
93
|
end(cookie: string | null | undefined, options?: {
|
|
80
94
|
readonly returnTo?: string;
|
|
81
95
|
}): Promise<Redirect>;
|
|
96
|
+
/**
|
|
97
|
+
* Back-channel logout, OpenID Connect Back-Channel Logout 1.0 §2.6: verify the logout token
|
|
98
|
+
* Keycloak posted, and drop every session it names.
|
|
99
|
+
*
|
|
100
|
+
* Rejects with `token/refused` for a token that does not verify, and `session/irrevocable` for a
|
|
101
|
+
* store that cannot end a session from here.
|
|
102
|
+
*/
|
|
103
|
+
logout(logoutToken: string): Promise<void>;
|
|
82
104
|
}
|
|
83
105
|
export declare function relyingParty(config: RelyingPartyConfig): RelyingParty;
|
|
84
106
|
export { issuer, rewriteOrigin, type Issuer, type IssuerConfig } from './issuer';
|
|
85
107
|
export { sealedCookie, cookieValue, type SealedCookie, type SealedCookieConfig } from './cookie-session';
|
|
86
|
-
export { statelessStore, ticketStore, type SessionRecord, type SessionStore, type TicketAdapter, type TicketStoreConfig, } from './store';
|
|
108
|
+
export { statelessStore, ticketStore, type SessionRecord, type SessionStore, type SessionSubject, type TicketAdapter, type TicketStoreConfig, } from './store';
|
|
87
109
|
//# sourceMappingURL=server.d.ts.map
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|