@flytedesk/app-kit 0.4.0 → 0.6.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/auth/index.d.ts +1 -1
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/oidc-client.d.ts +18 -0
- package/dist/auth/oidc-client.js +11 -0
- package/dist/auth/oidc-client.js.map +1 -1
- package/dist/auth/testing/fake-idp.d.ts +76 -0
- package/dist/auth/testing/fake-idp.js +255 -0
- package/dist/auth/testing/fake-idp.js.map +1 -0
- package/dist/auth/testing/index.d.ts +5 -0
- package/dist/auth/testing/index.js +6 -0
- package/dist/auth/testing/index.js.map +1 -0
- package/package.json +5 -1
package/dist/auth/index.d.ts
CHANGED
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
export { flytedeskAuth } from "./plugin.js";
|
|
30
30
|
export { requireAuth, requirePermission } from "./guards.js";
|
|
31
31
|
export type { AuthedUser, AuthStore, CreateIdpSessionInput, CreateRefreshTokenInput, FlytedeskAuthOptions, IdpRole, IdpSessionRow, RefreshTokenRow, UpdateIdpSessionInput, UserinfoClaims, } from "./types.js";
|
|
32
|
-
export type { IdpAuthorization, IdpTokenResponse, IdTokenClaims, OidcClient } from "./oidc-client.js";
|
|
32
|
+
export type { IdpAppSwitcherEntry, IdpAuthorization, IdpTokenResponse, IdTokenClaims, OidcClient, } from "./oidc-client.js";
|
|
33
33
|
export { createOidcClient } from "./oidc-client.js";
|
|
34
34
|
export { generatePkce, randomState, type PkcePair } from "./pkce.js";
|
|
35
35
|
export { generateRefreshToken, hashRefreshToken, signAccessToken, verifyAccessToken, type AccessTokenClaims, } from "./tokens.js";
|
package/dist/auth/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAsB7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEpD,OAAO,EAAE,YAAY,EAAE,WAAW,EAAiB,MAAM,WAAW,CAAC;AAErE,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,EACf,iBAAiB,GAElB,MAAM,aAAa,CAAC"}
|
|
@@ -25,6 +25,19 @@ export interface IdpAuthorization {
|
|
|
25
25
|
}>;
|
|
26
26
|
permissions: string[];
|
|
27
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* One entry from `GET {issuer}/me/apps` — an app the caller holds any role in.
|
|
30
|
+
* Shaped to drop straight into `@flytedan/flytebot-design-system`'s `AppEntry`
|
|
31
|
+
* ("All flytedesk apps" switcher, MP-209): `icon` is that same convention's bare
|
|
32
|
+
* Phosphor icon-library key (e.g. "chart-bar"), not a URL, and either field is
|
|
33
|
+
* `null` for an app flytedesk-id hasn't been seeded with one for yet.
|
|
34
|
+
*/
|
|
35
|
+
export interface IdpAppSwitcherEntry {
|
|
36
|
+
key: string;
|
|
37
|
+
name: string;
|
|
38
|
+
url: string | null;
|
|
39
|
+
icon: string | null;
|
|
40
|
+
}
|
|
28
41
|
export interface OidcClient {
|
|
29
42
|
buildAuthorizeUrl(opts: {
|
|
30
43
|
state: string;
|
|
@@ -35,6 +48,11 @@ export interface OidcClient {
|
|
|
35
48
|
verifyIdToken(idToken: string): Promise<IdTokenClaims>;
|
|
36
49
|
fetchUserinfo(idpAccessToken: string): Promise<UserinfoClaims>;
|
|
37
50
|
fetchAuthorization(idpAccessToken: string, appId: string): Promise<IdpAuthorization>;
|
|
51
|
+
/** `GET {issuer}/me/apps` — every app the caller holds any role in, for feeding the
|
|
52
|
+
* design system's "All flytedesk apps" switcher. Computed live by flytedesk-id on
|
|
53
|
+
* every call (never cached there — see fetchAuthorization's doc comment, same
|
|
54
|
+
* reasoning), so callers must call this live too rather than memoizing the result. */
|
|
55
|
+
fetchMyApps(idpAccessToken: string): Promise<IdpAppSwitcherEntry[]>;
|
|
38
56
|
/** Best-effort — never throws. Returns whether flytedesk-id accepted the revocation. */
|
|
39
57
|
revokeIdpToken(token: string): Promise<boolean>;
|
|
40
58
|
}
|
package/dist/auth/oidc-client.js
CHANGED
|
@@ -134,6 +134,17 @@ export function createOidcClient(opts) {
|
|
|
134
134
|
}
|
|
135
135
|
return (await res.json());
|
|
136
136
|
},
|
|
137
|
+
/** `GET {issuer}/me/apps` — see fetchMyApps's doc comment on OidcClient above. */
|
|
138
|
+
async fetchMyApps(idpAccessToken) {
|
|
139
|
+
const res = await fetch(issuerUrl("/me/apps"), {
|
|
140
|
+
headers: { Authorization: `Bearer ${idpAccessToken}` },
|
|
141
|
+
});
|
|
142
|
+
if (!res.ok) {
|
|
143
|
+
throw new Error(`flytedesk-id /me/apps returned ${res.status}`);
|
|
144
|
+
}
|
|
145
|
+
const body = (await res.json());
|
|
146
|
+
return body.apps;
|
|
147
|
+
},
|
|
137
148
|
/** Best-effort — revokes the IdP-side refresh token (and, transitively, its grant)
|
|
138
149
|
* on logout if flytedesk-id exposes a revocation endpoint. Never throws: a failed
|
|
139
150
|
* revocation attempt must not block local logout, since the local session is what
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oidc-client.js","sourceRoot":"","sources":["../../src/auth/oidc-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAwB,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"oidc-client.js","sourceRoot":"","sources":["../../src/auth/oidc-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { IdpAppSwitcherEntry } from "../oidc-client.js";
|
|
2
|
+
/**
|
|
3
|
+
* A fake flytedesk-id (OIDC provider) for e2e/integration harnesses, generalized out of
|
|
4
|
+
* media-planner's `apps/web/e2e/fake-idp.ts` (AK-10 follow-up, R-2/R-10) so every
|
|
5
|
+
* `@flytedesk/app-kit/auth` consumer gets ONE maintained fixture instead of each app
|
|
6
|
+
* hand-rolling its own. It serves the exact endpoints `./oidc-client.ts` calls —
|
|
7
|
+
* discovery, JWKS, `/auth` (authorize), `/token` (authorization_code + refresh, PKCE
|
|
8
|
+
* S256, Basic client auth), `/me` (userinfo), `/apps/:appId/authorization` (roles +
|
|
9
|
+
* permissions) and `/me/apps` (the "All flytedesk apps" switcher feed, `fetchMyApps`) —
|
|
10
|
+
* so a consumer's REAL login → callback → refresh chain runs UNMODIFIED against it. No
|
|
11
|
+
* bypass ever lands in production code: the consuming app simply points
|
|
12
|
+
* `FLYTEDESK_ID_ISSUER` at this server in its own e2e setup.
|
|
13
|
+
*
|
|
14
|
+
* Unlike the media-planner original, this fixture takes NO opinion on what identities or
|
|
15
|
+
* permission catalog exist — the caller supplies a map of named identities up front
|
|
16
|
+
* (`identities`) and picks which one the next `/auth` grants with `setNextIdentity` (in-
|
|
17
|
+
* process, for a Vitest-style harness) or the cross-process `/__set-identity` HTTP hook
|
|
18
|
+
* (for a Playwright spec driving a real browser against a real server process).
|
|
19
|
+
*/
|
|
20
|
+
export interface FakeIdpIdentity {
|
|
21
|
+
sub: string;
|
|
22
|
+
email: string;
|
|
23
|
+
name: string;
|
|
24
|
+
roles: Array<{
|
|
25
|
+
id: string;
|
|
26
|
+
key: string;
|
|
27
|
+
name: string;
|
|
28
|
+
}>;
|
|
29
|
+
/** UNPREFIXED permission keys — this fixture app-prefixes them on
|
|
30
|
+
* `/apps/:appId/authorization`, exactly as real flytedesk-id does (the consuming
|
|
31
|
+
* app's `flytedeskAuth` plugin strips the prefix back off). */
|
|
32
|
+
permissions: string[];
|
|
33
|
+
/** Fed to `/me/apps` for `fetchMyApps`/the design system's "All flytedesk apps"
|
|
34
|
+
* switcher. Defaults to an empty list. */
|
|
35
|
+
apps?: IdpAppSwitcherEntry[];
|
|
36
|
+
}
|
|
37
|
+
export interface FakeIdpOptions {
|
|
38
|
+
clientId: string;
|
|
39
|
+
/** Defaults to `clientId` — distinct because real flytedesk-id keys the authorization
|
|
40
|
+
* catalog on `appId`, not `clientId` (see `FlytedeskAuthOptions.appId`). */
|
|
41
|
+
appId?: string;
|
|
42
|
+
/** Every identity this fixture can grant, keyed by a caller-chosen name (e.g. role). */
|
|
43
|
+
identities: Record<string, FakeIdpIdentity>;
|
|
44
|
+
/** Which key in `identities` `/auth` grants until `setNextIdentity`/`/__set-identity`
|
|
45
|
+
* says otherwise. */
|
|
46
|
+
defaultIdentityKey: string;
|
|
47
|
+
}
|
|
48
|
+
export declare class FakeIdp {
|
|
49
|
+
private server?;
|
|
50
|
+
private baseUrl;
|
|
51
|
+
private readonly clientId;
|
|
52
|
+
private readonly appId;
|
|
53
|
+
private readonly identities;
|
|
54
|
+
private nextIdentityKey;
|
|
55
|
+
private idpSessionLive;
|
|
56
|
+
private keys;
|
|
57
|
+
private publicJwk;
|
|
58
|
+
private readonly kid;
|
|
59
|
+
private readonly codes;
|
|
60
|
+
private readonly grants;
|
|
61
|
+
constructor(opts: FakeIdpOptions);
|
|
62
|
+
/** Pick the identity the NEXT `/auth` grants. */
|
|
63
|
+
setNextIdentity(key: string): void;
|
|
64
|
+
/** See `idpSessionLive`'s doc comment. */
|
|
65
|
+
setIdpSessionLive(live: boolean): void;
|
|
66
|
+
get url(): string;
|
|
67
|
+
start(port?: number): Promise<string>;
|
|
68
|
+
stop(): Promise<void>;
|
|
69
|
+
private json;
|
|
70
|
+
private readForm;
|
|
71
|
+
private bearer;
|
|
72
|
+
private signIdToken;
|
|
73
|
+
private issueGrant;
|
|
74
|
+
private handle;
|
|
75
|
+
private tokenGrant;
|
|
76
|
+
}
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import { createServer } from "node:http";
|
|
2
|
+
import { createHash, randomBytes } from "node:crypto";
|
|
3
|
+
import { generateKeyPair, exportJWK, SignJWT } from "jose";
|
|
4
|
+
export class FakeIdp {
|
|
5
|
+
server;
|
|
6
|
+
baseUrl = "";
|
|
7
|
+
clientId;
|
|
8
|
+
appId;
|
|
9
|
+
identities;
|
|
10
|
+
nextIdentityKey;
|
|
11
|
+
// Whether this browser/client still holds a live flytedesk-id end-user session cookie
|
|
12
|
+
// — real oidc-provider's `prompt=none` handling (OIDC Core 3.1.2.1) answers straight
|
|
13
|
+
// from that cookie with no interaction at all: a fresh code if it's live,
|
|
14
|
+
// `error=login_required` back to redirect_uri if it's not. Defaults to true.
|
|
15
|
+
idpSessionLive = true;
|
|
16
|
+
keys;
|
|
17
|
+
publicJwk;
|
|
18
|
+
kid = "fake-idp-key";
|
|
19
|
+
codes = new Map();
|
|
20
|
+
grants = new Map();
|
|
21
|
+
constructor(opts) {
|
|
22
|
+
this.clientId = opts.clientId;
|
|
23
|
+
this.appId = opts.appId ?? opts.clientId;
|
|
24
|
+
this.identities = opts.identities;
|
|
25
|
+
if (!(opts.defaultIdentityKey in this.identities)) {
|
|
26
|
+
throw new Error(`FakeIdp: defaultIdentityKey "${opts.defaultIdentityKey}" is not in identities`);
|
|
27
|
+
}
|
|
28
|
+
this.nextIdentityKey = opts.defaultIdentityKey;
|
|
29
|
+
}
|
|
30
|
+
/** Pick the identity the NEXT `/auth` grants. */
|
|
31
|
+
setNextIdentity(key) {
|
|
32
|
+
if (!(key in this.identities)) {
|
|
33
|
+
throw new Error(`FakeIdp: no identity registered for "${key}"`);
|
|
34
|
+
}
|
|
35
|
+
this.nextIdentityKey = key;
|
|
36
|
+
}
|
|
37
|
+
/** See `idpSessionLive`'s doc comment. */
|
|
38
|
+
setIdpSessionLive(live) {
|
|
39
|
+
this.idpSessionLive = live;
|
|
40
|
+
}
|
|
41
|
+
get url() {
|
|
42
|
+
if (!this.baseUrl)
|
|
43
|
+
throw new Error("FakeIdp not started");
|
|
44
|
+
return this.baseUrl;
|
|
45
|
+
}
|
|
46
|
+
async start(port = 0) {
|
|
47
|
+
this.keys = await generateKeyPair("RS256", { extractable: true });
|
|
48
|
+
this.publicJwk = {
|
|
49
|
+
...(await exportJWK(this.keys.publicKey)),
|
|
50
|
+
kid: this.kid,
|
|
51
|
+
use: "sig",
|
|
52
|
+
alg: "RS256",
|
|
53
|
+
};
|
|
54
|
+
this.server = createServer((req, res) => {
|
|
55
|
+
this.handle(req, res).catch((err) => {
|
|
56
|
+
res.writeHead(500, { "content-type": "application/json" });
|
|
57
|
+
res.end(JSON.stringify({ error: "fake_idp_error", detail: String(err) }));
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
await new Promise((resolve) => this.server.listen(port, "127.0.0.1", resolve));
|
|
61
|
+
const addr = this.server.address();
|
|
62
|
+
if (!addr || typeof addr === "string")
|
|
63
|
+
throw new Error("FakeIdp failed to bind a port");
|
|
64
|
+
this.baseUrl = `http://127.0.0.1:${addr.port}`;
|
|
65
|
+
return this.baseUrl;
|
|
66
|
+
}
|
|
67
|
+
async stop() {
|
|
68
|
+
if (this.server)
|
|
69
|
+
await new Promise((resolve) => this.server.close(() => resolve()));
|
|
70
|
+
this.server = undefined;
|
|
71
|
+
}
|
|
72
|
+
json(res, status, body) {
|
|
73
|
+
res.writeHead(status, { "content-type": "application/json" });
|
|
74
|
+
res.end(JSON.stringify(body));
|
|
75
|
+
}
|
|
76
|
+
async readForm(req) {
|
|
77
|
+
const chunks = [];
|
|
78
|
+
for await (const c of req)
|
|
79
|
+
chunks.push(c);
|
|
80
|
+
return new URLSearchParams(Buffer.concat(chunks).toString("utf8"));
|
|
81
|
+
}
|
|
82
|
+
bearer(req) {
|
|
83
|
+
const h = req.headers.authorization;
|
|
84
|
+
return h?.startsWith("Bearer ") ? h.slice(7) : null;
|
|
85
|
+
}
|
|
86
|
+
async signIdToken(identity) {
|
|
87
|
+
return new SignJWT({})
|
|
88
|
+
.setProtectedHeader({ alg: "RS256", kid: this.kid })
|
|
89
|
+
.setIssuer(this.baseUrl)
|
|
90
|
+
.setAudience(this.clientId)
|
|
91
|
+
.setSubject(identity.sub)
|
|
92
|
+
.setIssuedAt()
|
|
93
|
+
.setExpirationTime("15m")
|
|
94
|
+
.sign(this.keys.privateKey);
|
|
95
|
+
}
|
|
96
|
+
issueGrant(identity) {
|
|
97
|
+
const accessToken = `at-${randomBytes(24).toString("base64url")}`;
|
|
98
|
+
const refreshToken = `rt-${randomBytes(24).toString("base64url")}`;
|
|
99
|
+
this.grants.set(accessToken, { identity });
|
|
100
|
+
this.grants.set(refreshToken, { identity });
|
|
101
|
+
return { accessToken, refreshToken };
|
|
102
|
+
}
|
|
103
|
+
async handle(req, res) {
|
|
104
|
+
const u = new URL(req.url ?? "/", this.baseUrl);
|
|
105
|
+
const path = u.pathname;
|
|
106
|
+
if (req.method === "GET" && path === "/.well-known/openid-configuration") {
|
|
107
|
+
return this.json(res, 200, {
|
|
108
|
+
issuer: this.baseUrl,
|
|
109
|
+
authorization_endpoint: `${this.baseUrl}/auth`,
|
|
110
|
+
token_endpoint: `${this.baseUrl}/token`,
|
|
111
|
+
jwks_uri: `${this.baseUrl}/jwks`,
|
|
112
|
+
userinfo_endpoint: `${this.baseUrl}/me`,
|
|
113
|
+
revocation_endpoint: `${this.baseUrl}/revoke`,
|
|
114
|
+
response_types_supported: ["code"],
|
|
115
|
+
id_token_signing_alg_values_supported: ["RS256"],
|
|
116
|
+
code_challenge_methods_supported: ["S256"],
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
if (req.method === "GET" && path === "/jwks") {
|
|
120
|
+
return this.json(res, 200, { keys: [this.publicJwk] });
|
|
121
|
+
}
|
|
122
|
+
// Authorize: auto-grant the currently-selected identity, redirect back with a code —
|
|
123
|
+
// UNLESS this is a `prompt=none` silent request and idpSessionLive has been turned
|
|
124
|
+
// off, in which case real oidc-provider answers `error=login_required` with no
|
|
125
|
+
// interaction UI at all, and this fake mirrors that exactly.
|
|
126
|
+
if (req.method === "GET" && path === "/auth") {
|
|
127
|
+
const redirectUri = u.searchParams.get("redirect_uri");
|
|
128
|
+
const state = u.searchParams.get("state") ?? "";
|
|
129
|
+
const codeChallenge = u.searchParams.get("code_challenge") ?? "";
|
|
130
|
+
const prompt = u.searchParams.get("prompt");
|
|
131
|
+
if (!redirectUri)
|
|
132
|
+
return this.json(res, 400, { error: "missing redirect_uri" });
|
|
133
|
+
const loc = new URL(redirectUri);
|
|
134
|
+
if (prompt === "none" && !this.idpSessionLive) {
|
|
135
|
+
loc.searchParams.set("error", "login_required");
|
|
136
|
+
loc.searchParams.set("state", state);
|
|
137
|
+
res.writeHead(302, { location: loc.toString() });
|
|
138
|
+
return void res.end();
|
|
139
|
+
}
|
|
140
|
+
const code = `code-${randomBytes(18).toString("base64url")}`;
|
|
141
|
+
this.codes.set(code, { identity: this.identities[this.nextIdentityKey], codeChallenge });
|
|
142
|
+
loc.searchParams.set("code", code);
|
|
143
|
+
loc.searchParams.set("state", state);
|
|
144
|
+
res.writeHead(302, { location: loc.toString() });
|
|
145
|
+
return void res.end();
|
|
146
|
+
}
|
|
147
|
+
if (req.method === "POST" && path === "/token") {
|
|
148
|
+
const form = await this.readForm(req);
|
|
149
|
+
const grantType = form.get("grant_type");
|
|
150
|
+
if (grantType === "authorization_code") {
|
|
151
|
+
const code = form.get("code") ?? "";
|
|
152
|
+
const verifier = form.get("code_verifier") ?? "";
|
|
153
|
+
const entry = this.codes.get(code);
|
|
154
|
+
if (!entry)
|
|
155
|
+
return this.json(res, 400, { error: "invalid_grant" });
|
|
156
|
+
this.codes.delete(code);
|
|
157
|
+
// PKCE S256: base64url(sha256(verifier)) must equal the stored challenge.
|
|
158
|
+
const challenge = createHash("sha256").update(verifier).digest("base64url");
|
|
159
|
+
if (entry.codeChallenge && challenge !== entry.codeChallenge) {
|
|
160
|
+
return this.json(res, 400, { error: "invalid_grant", detail: "pkce_mismatch" });
|
|
161
|
+
}
|
|
162
|
+
const { accessToken, refreshToken } = this.issueGrant(entry.identity);
|
|
163
|
+
return this.json(res, 200, {
|
|
164
|
+
access_token: accessToken,
|
|
165
|
+
id_token: await this.signIdToken(entry.identity),
|
|
166
|
+
refresh_token: refreshToken,
|
|
167
|
+
token_type: "Bearer",
|
|
168
|
+
expires_in: 900,
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
if (grantType === "refresh_token") {
|
|
172
|
+
const rt = form.get("refresh_token") ?? "";
|
|
173
|
+
const grant = this.grants.get(rt);
|
|
174
|
+
if (!grant)
|
|
175
|
+
return this.json(res, 400, { error: "invalid_grant" });
|
|
176
|
+
// rotateRefreshToken: true — issue a fresh pair for the same identity.
|
|
177
|
+
const { accessToken, refreshToken } = this.issueGrant(grant.identity);
|
|
178
|
+
return this.json(res, 200, {
|
|
179
|
+
access_token: accessToken,
|
|
180
|
+
id_token: await this.signIdToken(grant.identity),
|
|
181
|
+
refresh_token: refreshToken,
|
|
182
|
+
token_type: "Bearer",
|
|
183
|
+
expires_in: 900,
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
return this.json(res, 400, { error: "unsupported_grant_type" });
|
|
187
|
+
}
|
|
188
|
+
if (req.method === "GET" && path === "/me") {
|
|
189
|
+
const grant = this.tokenGrant(req);
|
|
190
|
+
if (!grant)
|
|
191
|
+
return this.json(res, 401, { error: "invalid_token" });
|
|
192
|
+
return this.json(res, 200, {
|
|
193
|
+
sub: grant.identity.sub,
|
|
194
|
+
email: grant.identity.email,
|
|
195
|
+
email_verified: true,
|
|
196
|
+
name: grant.identity.name,
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
if (req.method === "GET" && path === `/apps/${this.appId}/authorization`) {
|
|
200
|
+
const grant = this.tokenGrant(req);
|
|
201
|
+
if (!grant)
|
|
202
|
+
return this.json(res, 401, { error: "invalid_token" });
|
|
203
|
+
return this.json(res, 200, {
|
|
204
|
+
userId: grant.identity.sub,
|
|
205
|
+
appId: this.appId,
|
|
206
|
+
roles: grant.identity.roles,
|
|
207
|
+
// App-prefixed, exactly as real flytedesk-id returns (the consuming app's
|
|
208
|
+
// flytedeskAuth plugin strips it back off — see plugin.ts's loadAuthedUser).
|
|
209
|
+
permissions: grant.identity.permissions.map((p) => `${this.appId}:${p}`),
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
if (req.method === "GET" && path === "/me/apps") {
|
|
213
|
+
const grant = this.tokenGrant(req);
|
|
214
|
+
if (!grant)
|
|
215
|
+
return this.json(res, 401, { error: "invalid_token" });
|
|
216
|
+
return this.json(res, 200, { apps: grant.identity.apps ?? [] });
|
|
217
|
+
}
|
|
218
|
+
if (req.method === "POST" && path === "/revoke") {
|
|
219
|
+
const form = await this.readForm(req);
|
|
220
|
+
this.grants.delete(form.get("token") ?? "");
|
|
221
|
+
return this.json(res, 200, {});
|
|
222
|
+
}
|
|
223
|
+
// Test-control (out-of-band, not part of OIDC): pick the identity the next /auth
|
|
224
|
+
// grants. The in-process setNextIdentity() covers a Vitest-style harness; this HTTP
|
|
225
|
+
// hook lets a Playwright spec (a separate process from the server under test) choose
|
|
226
|
+
// the persona cross-process.
|
|
227
|
+
if (req.method === "POST" && path === "/__set-identity") {
|
|
228
|
+
const form = await this.readForm(req);
|
|
229
|
+
const key = form.get("key") ?? "";
|
|
230
|
+
if (!(key in this.identities)) {
|
|
231
|
+
return this.json(res, 400, { error: "unknown_identity", key });
|
|
232
|
+
}
|
|
233
|
+
this.setNextIdentity(key);
|
|
234
|
+
return this.json(res, 200, { key });
|
|
235
|
+
}
|
|
236
|
+
// Test-control: flip whether this fake IdP currently has a live end-user session
|
|
237
|
+
// (see idpSessionLive's doc comment) — same cross-process HTTP-hook pattern as
|
|
238
|
+
// /__set-identity.
|
|
239
|
+
if (req.method === "POST" && path === "/__set-idp-session") {
|
|
240
|
+
const form = await this.readForm(req);
|
|
241
|
+
const live = form.get("live");
|
|
242
|
+
if (live !== "true" && live !== "false") {
|
|
243
|
+
return this.json(res, 400, { error: "invalid_live", live });
|
|
244
|
+
}
|
|
245
|
+
this.setIdpSessionLive(live === "true");
|
|
246
|
+
return this.json(res, 200, { live: this.idpSessionLive });
|
|
247
|
+
}
|
|
248
|
+
return this.json(res, 404, { error: "not_found", path });
|
|
249
|
+
}
|
|
250
|
+
tokenGrant(req) {
|
|
251
|
+
const token = this.bearer(req);
|
|
252
|
+
return token ? (this.grants.get(token) ?? null) : null;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
//# sourceMappingURL=fake-idp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fake-idp.js","sourceRoot":"","sources":["../../../src/auth/testing/fake-idp.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/auth/testing/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,OAAO,EAA6C,MAAM,eAAe,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flytedesk/app-kit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Shared platform kit for flytedesk apps: flytedesk-id auth (BFF/OIDC client) and a Postgres-native trace/audit layer.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -37,6 +37,10 @@
|
|
|
37
37
|
"types": "./dist/auth/index.d.ts",
|
|
38
38
|
"import": "./dist/auth/index.js"
|
|
39
39
|
},
|
|
40
|
+
"./auth/testing": {
|
|
41
|
+
"types": "./dist/auth/testing/index.d.ts",
|
|
42
|
+
"import": "./dist/auth/testing/index.js"
|
|
43
|
+
},
|
|
40
44
|
"./trace": {
|
|
41
45
|
"types": "./dist/trace/index.d.ts",
|
|
42
46
|
"import": "./dist/trace/index.js"
|