@voltro/plugin-auth-workos 0.80.0 → 0.82.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/CHANGELOG.md +1610 -6
- package/dist/index.d.ts +28 -0
- package/dist/index.js +35 -20
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -179,6 +179,22 @@ export declare interface WorkosLoginHandoff {
|
|
|
179
179
|
readonly codeVerifier: string;
|
|
180
180
|
}
|
|
181
181
|
|
|
182
|
+
export declare interface WorkosLogoutOptions {
|
|
183
|
+
/** {@link WorkosProfile.sessionId} of the sign-in being ended. */
|
|
184
|
+
readonly sessionId: string;
|
|
185
|
+
/** Where WorkOS sends the browser afterwards. Register it as a logout
|
|
186
|
+
* redirect of the WorkOS application. */
|
|
187
|
+
readonly returnTo?: string;
|
|
188
|
+
readonly apiBase?: string;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* The URL that ends a WorkOS session — redirect the browser there at
|
|
193
|
+
* sign-out, after clearing your own session. Every application sharing that
|
|
194
|
+
* WorkOS session is signed out with it; the next sign-in asks again.
|
|
195
|
+
*/
|
|
196
|
+
export declare const workosLogoutUrl: (o: WorkosLogoutOptions) => string;
|
|
197
|
+
|
|
182
198
|
export declare interface WorkosMagicAuthSendOptions {
|
|
183
199
|
/** WorkOS API key (`sk_…`) — sent as a Bearer token. Server-only. */
|
|
184
200
|
readonly apiKey: string;
|
|
@@ -219,11 +235,23 @@ export declare interface WorkosOrganization {
|
|
|
219
235
|
export declare interface WorkosProfile {
|
|
220
236
|
readonly workosUserId: string;
|
|
221
237
|
readonly email: string;
|
|
238
|
+
/** Whether WorkOS has verified that the person controls `email`. An app
|
|
239
|
+
* that finds or links an existing account BY EMAIL must refuse when this
|
|
240
|
+
* is false: an identity provider that hands out unverified addresses would
|
|
241
|
+
* otherwise let anyone claim another person's account. Read from WorkOS's
|
|
242
|
+
* `email_verified`; absent counts as unverified. */
|
|
243
|
+
readonly emailVerified: boolean;
|
|
222
244
|
readonly firstName: string | null;
|
|
223
245
|
readonly lastName: string | null;
|
|
224
246
|
/** The WorkOS organization the user authenticated into, when SSO/org
|
|
225
247
|
* membership applies. Null for a plain AuthKit user. */
|
|
226
248
|
readonly organizationId: string | null;
|
|
249
|
+
/** The WorkOS session this sign-in opened — the `sid` claim of the access
|
|
250
|
+
* token WorkOS returned. Keep it (server-side, e.g. an HttpOnly cookie) to
|
|
251
|
+
* end that session at sign-out with {@link workosLogoutUrl}; without it,
|
|
252
|
+
* signing out of your app leaves the WorkOS session — and every other app
|
|
253
|
+
* sharing it — signed in. Null when WorkOS returned no access token. */
|
|
254
|
+
readonly sessionId: string | null;
|
|
227
255
|
}
|
|
228
256
|
|
|
229
257
|
/**
|
package/dist/index.js
CHANGED
|
@@ -51,11 +51,26 @@ var i = "https://api.workos.com", a = "wos-session", o = (t) => {
|
|
|
51
51
|
return {
|
|
52
52
|
workosUserId: n.id,
|
|
53
53
|
email: n.email,
|
|
54
|
+
emailVerified: n.email_verified === !0,
|
|
54
55
|
firstName: n.first_name ?? null,
|
|
55
56
|
lastName: n.last_name ?? null,
|
|
56
|
-
organizationId: t.organization_id ?? null
|
|
57
|
+
organizationId: t.organization_id ?? null,
|
|
58
|
+
sessionId: h(t.access_token)
|
|
57
59
|
};
|
|
58
|
-
}, h =
|
|
60
|
+
}, h = (e) => {
|
|
61
|
+
let t = e?.split(".")[1];
|
|
62
|
+
if (!t) return null;
|
|
63
|
+
try {
|
|
64
|
+
let e = JSON.parse(Buffer.from(t, "base64url").toString("utf8"));
|
|
65
|
+
return typeof e.sid == "string" && e.sid !== "" ? e.sid : null;
|
|
66
|
+
} catch {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
}, g = (e) => {
|
|
70
|
+
if (!e.sessionId) throw Error("workosLogoutUrl: `sessionId` is required");
|
|
71
|
+
let t = new URLSearchParams({ session_id: e.sessionId });
|
|
72
|
+
return e.returnTo && t.set("return_to", e.returnTo), `${e.apiBase ?? s}/user_management/sessions/logout?${t.toString()}`;
|
|
73
|
+
}, _ = async (e) => {
|
|
59
74
|
if (!e.code) throw new f(400, "workosAuthenticateWithCode: missing `code`");
|
|
60
75
|
if (!e.expectedState) throw new p("workosAuthenticateWithCode: no `expectedState` — the login was never started by this server, or the state cookie expired. Refusing to exchange the code.");
|
|
61
76
|
if (!e.state || !r(e.state, e.expectedState)) throw new p("workosAuthenticateWithCode: `state` does not match the value minted for this browser (possible CSRF).");
|
|
@@ -71,7 +86,7 @@ var i = "https://api.workos.com", a = "wos-session", o = (t) => {
|
|
|
71
86
|
code_verifier: e.codeVerifier
|
|
72
87
|
})
|
|
73
88
|
}));
|
|
74
|
-
},
|
|
89
|
+
}, v = async (e) => {
|
|
75
90
|
if (!e.email) throw new f(400, "workosSendMagicAuthCode: missing `email`");
|
|
76
91
|
let t = await (e.fetchImpl ?? fetch)(`${e.apiBase ?? s}/user_management/magic_auth`, {
|
|
77
92
|
method: "POST",
|
|
@@ -85,7 +100,7 @@ var i = "https://api.workos.com", a = "wos-session", o = (t) => {
|
|
|
85
100
|
let e = await t.text().catch(() => "");
|
|
86
101
|
throw new f(t.status, `WorkOS magic-auth send failed (${t.status}): ${e.slice(0, 200)}`);
|
|
87
102
|
}
|
|
88
|
-
},
|
|
103
|
+
}, y = async (e) => {
|
|
89
104
|
if (!e.code) throw new f(400, "workosAuthenticateWithMagicAuth: missing `code`");
|
|
90
105
|
if (!e.email) throw new f(400, "workosAuthenticateWithMagicAuth: missing `email`");
|
|
91
106
|
return m(await (e.fetchImpl ?? fetch)(`${e.apiBase ?? s}/user_management/authenticate`, {
|
|
@@ -99,8 +114,8 @@ var i = "https://api.workos.com", a = "wos-session", o = (t) => {
|
|
|
99
114
|
email: e.email
|
|
100
115
|
})
|
|
101
116
|
}));
|
|
102
|
-
},
|
|
103
|
-
let i = await (e.fetchImpl ?? fetch)(`${e.apiBase ??
|
|
117
|
+
}, b = "https://api.workos.com", x = async (e, t, n, r) => {
|
|
118
|
+
let i = await (e.fetchImpl ?? fetch)(`${e.apiBase ?? b}${n}`, {
|
|
104
119
|
method: t,
|
|
105
120
|
headers: {
|
|
106
121
|
authorization: `Bearer ${e.apiKey}`,
|
|
@@ -113,15 +128,15 @@ var i = "https://api.workos.com", a = "wos-session", o = (t) => {
|
|
|
113
128
|
throw new f(i.status, `WorkOS ${t} ${n} failed (${i.status}): ${e.slice(0, 200)}`);
|
|
114
129
|
}
|
|
115
130
|
if (i.status !== 204) return await i.json();
|
|
116
|
-
},
|
|
131
|
+
}, S = (e) => {
|
|
117
132
|
if (!e.id) throw new f(502, "WorkOS organization response missing id");
|
|
118
133
|
return {
|
|
119
134
|
id: e.id,
|
|
120
135
|
name: e.name ?? ""
|
|
121
136
|
};
|
|
122
|
-
},
|
|
137
|
+
}, C = async (e) => {
|
|
123
138
|
if (!e.name) throw new f(400, "workosCreateOrganization: missing `name`");
|
|
124
|
-
let t = await (e.fetchImpl ?? fetch)(`${e.apiBase ??
|
|
139
|
+
let t = await (e.fetchImpl ?? fetch)(`${e.apiBase ?? b}/organizations`, {
|
|
125
140
|
method: "POST",
|
|
126
141
|
headers: {
|
|
127
142
|
authorization: `Bearer ${e.apiKey}`,
|
|
@@ -134,8 +149,8 @@ var i = "https://api.workos.com", a = "wos-session", o = (t) => {
|
|
|
134
149
|
let e = await t.text().catch(() => "");
|
|
135
150
|
throw new f(t.status, `WorkOS create organization failed (${t.status}): ${e.slice(0, 200)}`);
|
|
136
151
|
}
|
|
137
|
-
return
|
|
138
|
-
},
|
|
152
|
+
return S(await t.json());
|
|
153
|
+
}, w = async (e) => S(await x(e, "GET", `/organizations/${encodeURIComponent(e.organizationId)}`)), T = async (e) => S(await x(e, "PUT", `/organizations/${encodeURIComponent(e.organizationId)}`, { name: e.name })), E = (e) => {
|
|
139
154
|
if (!e.id || !e.user_id || !e.organization_id) throw new f(502, "WorkOS membership response missing id/user_id/organization_id");
|
|
140
155
|
return {
|
|
141
156
|
id: e.id,
|
|
@@ -144,11 +159,11 @@ var i = "https://api.workos.com", a = "wos-session", o = (t) => {
|
|
|
144
159
|
roleSlug: e.role?.slug ?? null,
|
|
145
160
|
status: e.status ?? "active"
|
|
146
161
|
};
|
|
147
|
-
},
|
|
162
|
+
}, D = async (e) => E(await x(e, "POST", "/user_management/organization_memberships", {
|
|
148
163
|
user_id: e.userId,
|
|
149
164
|
organization_id: e.organizationId,
|
|
150
165
|
...e.roleSlug ? { role_slug: e.roleSlug } : {}
|
|
151
|
-
})),
|
|
166
|
+
})), O = async (e) => {
|
|
152
167
|
let t = [], n;
|
|
153
168
|
for (let r = 0; r < 100; r++) {
|
|
154
169
|
let r = new URLSearchParams({
|
|
@@ -156,18 +171,18 @@ var i = "https://api.workos.com", a = "wos-session", o = (t) => {
|
|
|
156
171
|
limit: "100"
|
|
157
172
|
});
|
|
158
173
|
n && r.set("after", n);
|
|
159
|
-
let i = await
|
|
160
|
-
for (let e of i.data ?? []) t.push(
|
|
174
|
+
let i = await x(e, "GET", `/user_management/organization_memberships?${r.toString()}`);
|
|
175
|
+
for (let e of i.data ?? []) t.push(E(e));
|
|
161
176
|
let a = i.list_metadata?.after;
|
|
162
177
|
if (!a) break;
|
|
163
178
|
n = a;
|
|
164
179
|
}
|
|
165
180
|
return t;
|
|
166
|
-
},
|
|
167
|
-
await
|
|
168
|
-
},
|
|
181
|
+
}, k = async (e) => {
|
|
182
|
+
await x(e, "DELETE", `/user_management/organization_memberships/${encodeURIComponent(e.membershipId)}`);
|
|
183
|
+
}, A = async (e) => {
|
|
169
184
|
if (!e.email) throw new f(400, "workosCreateInvitation: missing `email`");
|
|
170
|
-
let t = await
|
|
185
|
+
let t = await x(e, "POST", "/user_management/invitations", {
|
|
171
186
|
email: e.email,
|
|
172
187
|
organization_id: e.organizationId,
|
|
173
188
|
...e.roleSlug ? { role_slug: e.roleSlug } : {},
|
|
@@ -182,4 +197,4 @@ var i = "https://api.workos.com", a = "wos-session", o = (t) => {
|
|
|
182
197
|
};
|
|
183
198
|
};
|
|
184
199
|
//#endregion
|
|
185
|
-
export { f as WorkosExchangeError, p as WorkosStateMismatchError,
|
|
200
|
+
export { f as WorkosExchangeError, p as WorkosStateMismatchError, _ as workosAuthenticateWithCode, y as workosAuthenticateWithMagicAuth, d as workosBeginLogin, A as workosCreateInvitation, D as workosCreateMembership, C as workosCreateOrganization, k as workosDeleteMembership, w as workosGetOrganization, O as workosListUserMemberships, g as workosLogoutUrl, v as workosSendMagicAuthCode, o as workosStrategy, T as workosUpdateOrganization };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@voltro/plugin-auth-workos",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.82.0",
|
|
4
4
|
"description": "WorkOS-backed AuthStrategy for the Voltro framework. Verifies WorkOS AuthKit/SSO JWTs via JWKS and maps `org_id`→tenant. Composes via @voltro/protocol AuthStrategy alongside other IdP plugins.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"voltro",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"node": ">=24.0.0"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@voltro/protocol": "0.
|
|
36
|
+
"@voltro/protocol": "0.82.0"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
39
|
"effect": "^3.22.2"
|