@holo-js/auth-workos 0.1.4 → 0.1.6
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.d.ts +122 -26
- package/dist/index.mjs +616 -110
- package/package.json +5 -5
package/dist/index.d.ts
CHANGED
|
@@ -1,17 +1,40 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { AuthResult, AuthLogoutResult, AuthFieldErrors, AuthenticatedAuthUser, AuthEstablishedSession, authRuntimeInternals } from '@holo-js/auth';
|
|
2
|
+
import { NormalizedAuthWorkosProviderConfig } from '@holo-js/config';
|
|
3
3
|
|
|
4
|
+
type WorkosJsonValue = string | number | boolean | null | readonly WorkosJsonValue[] | {
|
|
5
|
+
readonly [key: string]: WorkosJsonValue;
|
|
6
|
+
};
|
|
4
7
|
interface WorkosIdentityProfile {
|
|
5
8
|
readonly id: string;
|
|
6
|
-
readonly email
|
|
7
|
-
readonly
|
|
9
|
+
readonly email: string;
|
|
10
|
+
readonly name: string;
|
|
11
|
+
readonly emailVerified: boolean;
|
|
8
12
|
readonly firstName?: string;
|
|
9
13
|
readonly lastName?: string;
|
|
10
|
-
readonly
|
|
11
|
-
readonly
|
|
14
|
+
readonly profilePictureUrl?: string;
|
|
15
|
+
readonly externalId?: string;
|
|
12
16
|
readonly organizationId?: string;
|
|
13
|
-
readonly
|
|
17
|
+
readonly metadata: Readonly<Record<string, WorkosJsonValue>>;
|
|
18
|
+
readonly createdAt?: string;
|
|
19
|
+
readonly updatedAt?: string;
|
|
20
|
+
readonly raw: Readonly<Record<string, WorkosJsonValue>>;
|
|
14
21
|
}
|
|
22
|
+
type WorkosUserAttributeValue = string | number | boolean | Date | null | undefined | readonly WorkosUserAttributeValue[] | {
|
|
23
|
+
readonly [key: string]: WorkosUserAttributeValue;
|
|
24
|
+
};
|
|
25
|
+
type WorkosUserAttributes = Readonly<Record<string, WorkosUserAttributeValue>>;
|
|
26
|
+
type WorkosDefaultUserAttributes = {
|
|
27
|
+
readonly email: string;
|
|
28
|
+
readonly name: string;
|
|
29
|
+
};
|
|
30
|
+
type WorkosUserMapper<TUserAttributes extends WorkosUserAttributes = WorkosDefaultUserAttributes> = (workosUser: WorkosIdentityProfile) => TUserAttributes;
|
|
31
|
+
type WorkosCompleteAuthOptions<TUserAttributes extends WorkosUserAttributes = WorkosDefaultUserAttributes> = {
|
|
32
|
+
readonly provider?: string;
|
|
33
|
+
readonly user?: WorkosUserMapper<TUserAttributes>;
|
|
34
|
+
};
|
|
35
|
+
type WorkosSyncIdentityOptions<TUserAttributes extends WorkosUserAttributes = WorkosDefaultUserAttributes> = {
|
|
36
|
+
readonly user?: WorkosUserMapper<TUserAttributes>;
|
|
37
|
+
};
|
|
15
38
|
interface WorkosVerifiedSession {
|
|
16
39
|
readonly sessionId: string;
|
|
17
40
|
readonly identity: WorkosIdentityProfile;
|
|
@@ -19,21 +42,45 @@ interface WorkosVerifiedSession {
|
|
|
19
42
|
readonly expiresAt?: Date;
|
|
20
43
|
readonly raw?: unknown;
|
|
21
44
|
}
|
|
45
|
+
interface WorkosLogoutSession {
|
|
46
|
+
readonly provider: string;
|
|
47
|
+
readonly sessionId: string;
|
|
48
|
+
}
|
|
49
|
+
type WorkosAuthenticatedUser<TUserAttributes extends WorkosUserAttributes = WorkosDefaultUserAttributes> = AuthenticatedAuthUser & Omit<TUserAttributes, 'can' | 'id'> & {
|
|
50
|
+
readonly id: string | number;
|
|
51
|
+
};
|
|
52
|
+
type WorkosHostedAuthFailureFields = AuthFieldErrors<'_root'>;
|
|
53
|
+
interface WorkosCompleteAuthData<TUserAttributes extends WorkosUserAttributes = WorkosDefaultUserAttributes> {
|
|
54
|
+
readonly provider: string;
|
|
55
|
+
readonly guard: string;
|
|
56
|
+
readonly authProvider: string;
|
|
57
|
+
readonly status: WorkosSyncStatus;
|
|
58
|
+
readonly user: WorkosAuthenticatedUser<TUserAttributes>;
|
|
59
|
+
readonly identity: HostedIdentityRecord;
|
|
60
|
+
readonly session: WorkosVerifiedSession;
|
|
61
|
+
readonly authSession?: AuthEstablishedSession;
|
|
62
|
+
}
|
|
63
|
+
type WorkosCompleteAuthResult<TUserAttributes extends WorkosUserAttributes = WorkosDefaultUserAttributes> = AuthResult<WorkosCompleteAuthData<TUserAttributes>, string, WorkosHostedAuthFailureFields>;
|
|
64
|
+
type WorkosLogoutErrorCode = 'workos_logout_failed' | 'workos_session_missing';
|
|
65
|
+
interface WorkosLogoutData {
|
|
66
|
+
readonly url: string;
|
|
67
|
+
readonly local: AuthLogoutResult;
|
|
68
|
+
}
|
|
69
|
+
type WorkosLogoutResult = AuthResult<WorkosLogoutData, WorkosLogoutErrorCode, WorkosHostedAuthFailureFields>;
|
|
22
70
|
interface WorkosVerifyRequestContext {
|
|
23
71
|
readonly provider: string;
|
|
24
72
|
readonly request: Request;
|
|
25
|
-
readonly config:
|
|
73
|
+
readonly config: NormalizedAuthWorkosProviderConfig;
|
|
26
74
|
}
|
|
27
75
|
interface WorkosVerifySessionContext {
|
|
28
76
|
readonly provider: string;
|
|
29
77
|
readonly token: string;
|
|
30
|
-
readonly config:
|
|
78
|
+
readonly config: NormalizedAuthWorkosProviderConfig;
|
|
31
79
|
}
|
|
32
80
|
interface WorkosProviderRuntime {
|
|
33
81
|
verifyRequest?(context: WorkosVerifyRequestContext): Promise<WorkosVerifiedSession | null>;
|
|
34
82
|
verifySession?(context: WorkosVerifySessionContext): Promise<WorkosVerifiedSession | null>;
|
|
35
83
|
}
|
|
36
|
-
type RuntimeAuthProviderAdapter = ReturnType<typeof authRuntimeInternals.getRuntimeBindings>['providers'][string];
|
|
37
84
|
interface HostedIdentityRecord {
|
|
38
85
|
readonly provider: string;
|
|
39
86
|
readonly providerUserId: string;
|
|
@@ -52,12 +99,12 @@ interface HostedIdentityStore {
|
|
|
52
99
|
save(record: HostedIdentityRecord): Promise<void>;
|
|
53
100
|
}
|
|
54
101
|
type WorkosSyncStatus = 'created' | 'updated' | 'linked' | 'relinked';
|
|
55
|
-
interface WorkosAuthenticationResult {
|
|
102
|
+
interface WorkosAuthenticationResult<TUserAttributes extends WorkosUserAttributes = WorkosDefaultUserAttributes> {
|
|
56
103
|
readonly provider: string;
|
|
57
104
|
readonly guard: string;
|
|
58
105
|
readonly authProvider: string;
|
|
59
106
|
readonly status: WorkosSyncStatus;
|
|
60
|
-
readonly user:
|
|
107
|
+
readonly user: WorkosAuthenticatedUser<TUserAttributes>;
|
|
61
108
|
readonly identity: HostedIdentityRecord;
|
|
62
109
|
readonly session: WorkosVerifiedSession;
|
|
63
110
|
readonly authSession?: AuthEstablishedSession;
|
|
@@ -71,9 +118,20 @@ interface ConfigureWorkosAuthRuntimeOptions {
|
|
|
71
118
|
readonly identityStore?: HostedIdentityStore;
|
|
72
119
|
}
|
|
73
120
|
interface WorkosAuthFacade {
|
|
121
|
+
loginWithWorkos(request: Request, options?: {
|
|
122
|
+
readonly provider?: string;
|
|
123
|
+
}): Promise<Response>;
|
|
124
|
+
registerWithWorkos(request: Request, options?: {
|
|
125
|
+
readonly provider?: string;
|
|
126
|
+
}): Promise<Response>;
|
|
127
|
+
logoutWithWorkos(request: Request, options?: {
|
|
128
|
+
readonly provider?: string;
|
|
129
|
+
readonly returnTo?: string;
|
|
130
|
+
}): Promise<WorkosLogoutResult>;
|
|
131
|
+
completeWorkosAuth<TUserAttributes extends WorkosUserAttributes = WorkosDefaultUserAttributes>(request: Request, options?: WorkosCompleteAuthOptions<TUserAttributes>): Promise<WorkosCompleteAuthResult<TUserAttributes>>;
|
|
74
132
|
verifyRequest(request: Request, provider?: string): Promise<WorkosVerifiedSession | null>;
|
|
75
133
|
verifySession(token: string, provider?: string): Promise<WorkosVerifiedSession | null>;
|
|
76
|
-
syncIdentity(session: WorkosVerifiedSession, provider?: string): Promise<WorkosAuthenticationResult
|
|
134
|
+
syncIdentity<TUserAttributes extends WorkosUserAttributes = WorkosDefaultUserAttributes>(session: WorkosVerifiedSession, provider?: string, options?: WorkosSyncIdentityOptions<TUserAttributes>): Promise<WorkosAuthenticationResult<TUserAttributes>>;
|
|
77
135
|
authenticate(request: Request, provider?: string): Promise<WorkosAuthenticationResult | null>;
|
|
78
136
|
}
|
|
79
137
|
declare class WorkosAuthConflictError extends Error {
|
|
@@ -88,35 +146,73 @@ declare class WorkosAuthConflictError extends Error {
|
|
|
88
146
|
readonly message: string;
|
|
89
147
|
});
|
|
90
148
|
}
|
|
149
|
+
|
|
150
|
+
type RuntimeAuthProviderAdapter = ReturnType<typeof authRuntimeInternals.getRuntimeBindings>['providers'][string];
|
|
151
|
+
type WorkosRequestHeaders = Headers | ReadonlyArray<readonly [string, string]> | Record<string, string | readonly string[] | undefined> | {
|
|
152
|
+
readonly get?: (name: string) => string | null | undefined;
|
|
153
|
+
readonly forEach?: (callback: (value: string, key: string) => void) => void;
|
|
154
|
+
readonly entries?: () => Iterable<readonly [string, string]>;
|
|
155
|
+
};
|
|
156
|
+
type WorkosRequestLike = {
|
|
157
|
+
readonly method?: string;
|
|
158
|
+
readonly path?: string;
|
|
159
|
+
readonly url?: string | URL;
|
|
160
|
+
readonly headers?: WorkosRequestHeaders;
|
|
161
|
+
readonly request?: Request;
|
|
162
|
+
readonly req?: Request | {
|
|
163
|
+
readonly method?: string;
|
|
164
|
+
readonly url?: string;
|
|
165
|
+
readonly headers?: WorkosRequestHeaders;
|
|
166
|
+
};
|
|
167
|
+
readonly node?: {
|
|
168
|
+
readonly req?: {
|
|
169
|
+
readonly method?: string;
|
|
170
|
+
readonly url?: string;
|
|
171
|
+
readonly headers?: WorkosRequestHeaders;
|
|
172
|
+
};
|
|
173
|
+
};
|
|
174
|
+
readonly web?: {
|
|
175
|
+
readonly request?: Request;
|
|
176
|
+
};
|
|
177
|
+
};
|
|
178
|
+
type WorkosRequestInput = Request | WorkosRequestLike;
|
|
91
179
|
declare function getBindings(): WorkosAuthBindings;
|
|
92
180
|
declare function resolveConfiguredProviderName(provider?: string): string;
|
|
93
181
|
declare function getConfiguredProviderConfig(provider?: string): {
|
|
94
182
|
readonly name: string;
|
|
95
|
-
|
|
96
|
-
readonly apiKey?: string;
|
|
97
|
-
readonly cookiePassword?: string;
|
|
98
|
-
readonly redirectUri?: string;
|
|
99
|
-
readonly sessionCookie: string;
|
|
100
|
-
readonly guard?: string;
|
|
101
|
-
readonly mapToProvider?: string;
|
|
102
|
-
};
|
|
183
|
+
} & NormalizedAuthWorkosProviderConfig;
|
|
103
184
|
declare function resolveGuardAndProvider(provider?: string): {
|
|
104
185
|
readonly guard: string;
|
|
105
186
|
readonly authProvider: string;
|
|
106
187
|
readonly adapter: RuntimeAuthProviderAdapter;
|
|
107
188
|
};
|
|
108
|
-
declare function resolveDisplayName(profile: WorkosIdentityProfile): string
|
|
189
|
+
declare function resolveDisplayName(profile: WorkosIdentityProfile): string;
|
|
109
190
|
declare function resolveEmailForCreation(profile: WorkosIdentityProfile): string;
|
|
110
191
|
declare function normalizeHostedProfile(profile: WorkosIdentityProfile): Readonly<Record<string, unknown>>;
|
|
111
192
|
declare function getSessionTokenFromRequest(request: Request, sessionCookie: string): string | null;
|
|
112
193
|
declare function verifySession(token: string, provider?: string): Promise<WorkosVerifiedSession | null>;
|
|
113
|
-
declare function verifyRequest(
|
|
114
|
-
declare function syncIdentity(session: WorkosVerifiedSession, provider?: string): Promise<WorkosAuthenticationResult
|
|
115
|
-
declare function authenticate(
|
|
194
|
+
declare function verifyRequest(input: WorkosRequestInput, provider?: string): Promise<WorkosVerifiedSession | null>;
|
|
195
|
+
declare function syncIdentity<TUserAttributes extends WorkosUserAttributes = WorkosDefaultUserAttributes>(session: WorkosVerifiedSession, provider?: string, options?: WorkosSyncIdentityOptions<TUserAttributes>): Promise<WorkosAuthenticationResult<TUserAttributes>>;
|
|
196
|
+
declare function authenticate(input: WorkosRequestInput, provider?: string): Promise<WorkosAuthenticationResult | null>;
|
|
197
|
+
declare function loginWithWorkos(input: WorkosRequestInput, options?: {
|
|
198
|
+
readonly provider?: string;
|
|
199
|
+
}): Promise<Response>;
|
|
200
|
+
declare function registerWithWorkos(input: WorkosRequestInput, options?: {
|
|
201
|
+
readonly provider?: string;
|
|
202
|
+
}): Promise<Response>;
|
|
203
|
+
declare function logoutWithWorkos(input: WorkosRequestInput, options?: {
|
|
204
|
+
readonly provider?: string;
|
|
205
|
+
readonly returnTo?: string;
|
|
206
|
+
}): Promise<WorkosLogoutResult>;
|
|
207
|
+
declare function completeWorkosAuth<TUserAttributes extends WorkosUserAttributes = WorkosDefaultUserAttributes>(input: WorkosRequestInput, options?: WorkosCompleteAuthOptions<TUserAttributes>): Promise<WorkosCompleteAuthResult<TUserAttributes>>;
|
|
116
208
|
declare function configureWorkosAuthRuntime(bindings?: ConfigureWorkosAuthRuntimeOptions): void;
|
|
117
209
|
declare function resetWorkosAuthRuntime(): void;
|
|
118
210
|
declare const workosAuth: Readonly<{
|
|
119
211
|
authenticate: typeof authenticate;
|
|
212
|
+
completeWorkosAuth: typeof completeWorkosAuth;
|
|
213
|
+
loginWithWorkos: typeof loginWithWorkos;
|
|
214
|
+
logoutWithWorkos: typeof logoutWithWorkos;
|
|
215
|
+
registerWithWorkos: typeof registerWithWorkos;
|
|
120
216
|
syncIdentity: typeof syncIdentity;
|
|
121
217
|
verifyRequest: typeof verifyRequest;
|
|
122
218
|
verifySession: typeof verifySession;
|
|
@@ -132,4 +228,4 @@ declare const workosAuthInternals: {
|
|
|
132
228
|
resolveGuardAndProvider: typeof resolveGuardAndProvider;
|
|
133
229
|
};
|
|
134
230
|
|
|
135
|
-
export { type ConfigureWorkosAuthRuntimeOptions, type HostedIdentityRecord, type HostedIdentityStore, type WorkosAuthBindings, WorkosAuthConflictError, type WorkosAuthFacade, type WorkosAuthenticationResult, type WorkosIdentityProfile, type WorkosProviderRuntime, type WorkosSyncStatus, type WorkosVerifiedSession, type WorkosVerifyRequestContext, type WorkosVerifySessionContext, authenticate, configureWorkosAuthRuntime, resetWorkosAuthRuntime, syncIdentity, verifyRequest, verifySession, workosAuth, workosAuthInternals };
|
|
231
|
+
export { type ConfigureWorkosAuthRuntimeOptions, type HostedIdentityRecord, type HostedIdentityStore, type WorkosAuthBindings, WorkosAuthConflictError, type WorkosAuthFacade, type WorkosAuthenticatedUser, type WorkosAuthenticationResult, type WorkosCompleteAuthData, type WorkosCompleteAuthOptions, type WorkosCompleteAuthResult, type WorkosDefaultUserAttributes, type WorkosHostedAuthFailureFields, type WorkosIdentityProfile, type WorkosJsonValue, type WorkosLogoutData, type WorkosLogoutErrorCode, type WorkosLogoutResult, type WorkosLogoutSession, type WorkosProviderRuntime, type WorkosSyncIdentityOptions, type WorkosSyncStatus, type WorkosUserAttributeValue, type WorkosUserAttributes, type WorkosVerifiedSession, type WorkosVerifyRequestContext, type WorkosVerifySessionContext, authenticate, completeWorkosAuth, configureWorkosAuthRuntime, loginWithWorkos, logoutWithWorkos, registerWithWorkos, resetWorkosAuthRuntime, syncIdentity, verifyRequest, verifySession, workosAuth, workosAuthInternals };
|
package/dist/index.mjs
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
|
-
import { createPublicKey, verify as verifySignature } from "crypto";
|
|
3
|
-
import { authRuntimeInternals } from "@holo-js/auth";
|
|
4
|
-
import { parseCookieHeader } from "@holo-js/session";
|
|
2
|
+
import { createPublicKey, randomBytes, verify as verifySignature } from "crypto";
|
|
3
|
+
import { authRuntimeInternals, getAuthRuntime } from "@holo-js/auth";
|
|
4
|
+
import { cookie, parseCookieHeader } from "@holo-js/session";
|
|
5
|
+
|
|
6
|
+
// src/contracts.ts
|
|
5
7
|
var WorkosAuthConflictError = class extends Error {
|
|
6
8
|
code = "workos_identity_conflict";
|
|
7
9
|
provider;
|
|
@@ -15,15 +17,127 @@ var WorkosAuthConflictError = class extends Error {
|
|
|
15
17
|
this.email = options.email;
|
|
16
18
|
}
|
|
17
19
|
};
|
|
18
|
-
|
|
20
|
+
|
|
21
|
+
// src/index.ts
|
|
22
|
+
var WORKOS_RUNTIME_STATE_KEY = "__holoJsAuthWorkosRuntime";
|
|
19
23
|
var WORKOS_API_BASE_URL = "https://api.workos.com";
|
|
24
|
+
var WORKOS_AUTHORIZE_URL = `${WORKOS_API_BASE_URL}/user_management/authorize`;
|
|
25
|
+
var WORKOS_AUTHENTICATE_URL = `${WORKOS_API_BASE_URL}/user_management/authenticate`;
|
|
26
|
+
var WORKOS_LOGOUT_URL = `${WORKOS_API_BASE_URL}/user_management/sessions/logout`;
|
|
27
|
+
var WORKOS_STATE_COOKIE_MAX_AGE_SECONDS = 300;
|
|
20
28
|
var workosDefaultProviderRuntimeCache = /* @__PURE__ */ new Map();
|
|
21
29
|
var workosJwksCache = /* @__PURE__ */ new Map();
|
|
22
30
|
var AUTH_PROVIDER_MARKER = /* @__PURE__ */ Symbol.for("holo-js.auth.provider");
|
|
31
|
+
function getRuntimeState() {
|
|
32
|
+
const runtimeGlobal = globalThis;
|
|
33
|
+
if (!runtimeGlobal[WORKOS_RUNTIME_STATE_KEY]) {
|
|
34
|
+
Object.defineProperty(runtimeGlobal, WORKOS_RUNTIME_STATE_KEY, {
|
|
35
|
+
value: {},
|
|
36
|
+
enumerable: false,
|
|
37
|
+
configurable: true,
|
|
38
|
+
writable: true
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
return runtimeGlobal[WORKOS_RUNTIME_STATE_KEY];
|
|
42
|
+
}
|
|
23
43
|
function throwUnconfigured() {
|
|
24
44
|
throw new Error("[@holo-js/auth-workos] WorkOS auth runtime is not configured yet.");
|
|
25
45
|
}
|
|
46
|
+
function isPlainHeaderRecord(value) {
|
|
47
|
+
return Boolean(value) && typeof value === "object" && Object.getPrototypeOf(value) === Object.prototype;
|
|
48
|
+
}
|
|
49
|
+
function appendKnownHeaders(headers, input) {
|
|
50
|
+
for (const name of ["authorization", "cookie", "host", "x-forwarded-host", "x-forwarded-proto"]) {
|
|
51
|
+
const value = input.get?.(name);
|
|
52
|
+
if (typeof value === "string" && value) {
|
|
53
|
+
headers.set(name, value);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
function hasHeaderForEach(input) {
|
|
58
|
+
return !Array.isArray(input) && "forEach" in input && typeof input.forEach === "function";
|
|
59
|
+
}
|
|
60
|
+
function hasHeaderEntries(input) {
|
|
61
|
+
return !Array.isArray(input) && "entries" in input && typeof input.entries === "function";
|
|
62
|
+
}
|
|
63
|
+
function hasHeaderGet(input) {
|
|
64
|
+
return !Array.isArray(input) && "get" in input && typeof input.get === "function";
|
|
65
|
+
}
|
|
66
|
+
function normalizeRequestHeaders(input) {
|
|
67
|
+
const headers = new Headers();
|
|
68
|
+
if (!input) {
|
|
69
|
+
return headers;
|
|
70
|
+
}
|
|
71
|
+
if (input instanceof Headers || Array.isArray(input)) {
|
|
72
|
+
new Headers(input).forEach((value, name) => headers.append(name, value));
|
|
73
|
+
return headers;
|
|
74
|
+
}
|
|
75
|
+
if (hasHeaderForEach(input)) {
|
|
76
|
+
input.forEach((value, name) => headers.append(name, value));
|
|
77
|
+
return headers;
|
|
78
|
+
}
|
|
79
|
+
if (hasHeaderEntries(input)) {
|
|
80
|
+
for (const [name, value] of input.entries()) {
|
|
81
|
+
headers.append(name, value);
|
|
82
|
+
}
|
|
83
|
+
return headers;
|
|
84
|
+
}
|
|
85
|
+
if (hasHeaderGet(input)) {
|
|
86
|
+
appendKnownHeaders(headers, input);
|
|
87
|
+
return headers;
|
|
88
|
+
}
|
|
89
|
+
if (isPlainHeaderRecord(input)) {
|
|
90
|
+
for (const [name, value] of Object.entries(input)) {
|
|
91
|
+
if (typeof value === "string") {
|
|
92
|
+
headers.append(name, value);
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
if (Array.isArray(value)) {
|
|
96
|
+
const separator = name.toLowerCase() === "cookie" ? "; " : ",";
|
|
97
|
+
const joined = value.filter((entry) => typeof entry === "string").join(separator);
|
|
98
|
+
if (joined) {
|
|
99
|
+
headers.append(name, joined);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return headers;
|
|
105
|
+
}
|
|
106
|
+
function getRequestFromLikeInput(input) {
|
|
107
|
+
return input.request ?? input.web?.request ?? (input.req instanceof Request ? input.req : void 0);
|
|
108
|
+
}
|
|
109
|
+
function getRequestLikeHeaders(input) {
|
|
110
|
+
return input.headers ?? (typeof input.req === "object" && !(input.req instanceof Request) ? input.req.headers : void 0) ?? input.node?.req?.headers;
|
|
111
|
+
}
|
|
112
|
+
function getRequestLikeMethod(input) {
|
|
113
|
+
return input.method ?? (typeof input.req === "object" && !(input.req instanceof Request) ? input.req.method : void 0) ?? input.node?.req?.method ?? "GET";
|
|
114
|
+
}
|
|
115
|
+
function getRequestLikeUrl(input, headers) {
|
|
116
|
+
const url = (typeof input.url === "string" ? input.url : input.url?.toString()) ?? (typeof input.req === "object" && !(input.req instanceof Request) ? input.req.url : void 0) ?? input.node?.req?.url ?? input.path ?? "/";
|
|
117
|
+
try {
|
|
118
|
+
return new URL(url).toString();
|
|
119
|
+
} catch {
|
|
120
|
+
const protocol = headers.get("x-forwarded-proto") ?? "http";
|
|
121
|
+
const host = headers.get("x-forwarded-host") ?? headers.get("host") ?? "localhost";
|
|
122
|
+
return new URL(url, `${protocol}://${host}`).toString();
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
function normalizeWorkosRequest(input) {
|
|
126
|
+
if (input instanceof Request) {
|
|
127
|
+
return input;
|
|
128
|
+
}
|
|
129
|
+
const request = getRequestFromLikeInput(input);
|
|
130
|
+
if (request) {
|
|
131
|
+
return request;
|
|
132
|
+
}
|
|
133
|
+
const headers = normalizeRequestHeaders(getRequestLikeHeaders(input));
|
|
134
|
+
return new Request(getRequestLikeUrl(input, headers), {
|
|
135
|
+
method: getRequestLikeMethod(input),
|
|
136
|
+
headers
|
|
137
|
+
});
|
|
138
|
+
}
|
|
26
139
|
function getBindings() {
|
|
140
|
+
const workosBindings = getRuntimeState().bindings;
|
|
27
141
|
if (!workosBindings?.identityStore) {
|
|
28
142
|
throwUnconfigured();
|
|
29
143
|
}
|
|
@@ -51,6 +165,14 @@ function parseJwt(token) {
|
|
|
51
165
|
signingInput: Buffer.from(`${segments[0]}.${segments[1]}`, "utf8")
|
|
52
166
|
};
|
|
53
167
|
}
|
|
168
|
+
function getJwtStringClaim(token, claim) {
|
|
169
|
+
try {
|
|
170
|
+
const value = parseJwt(token).payload[claim];
|
|
171
|
+
return typeof value === "string" && value.trim() ? value : void 0;
|
|
172
|
+
} catch {
|
|
173
|
+
return void 0;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
54
176
|
function verifyJwtSignatureWithJwk(token, jwk) {
|
|
55
177
|
const algorithm = typeof token.header.alg === "string" ? token.header.alg : "";
|
|
56
178
|
const key = createPublicKey({ key: jwk, format: "jwk" });
|
|
@@ -113,29 +235,66 @@ async function verifyWorkosSessionToken(token, config) {
|
|
|
113
235
|
throw new Error("[@holo-js/auth-workos] WorkOS token signature verification failed.");
|
|
114
236
|
}
|
|
115
237
|
const exp = typeof parsed.payload.exp === "number" ? parsed.payload.exp : void 0;
|
|
116
|
-
if (typeof exp
|
|
238
|
+
if (typeof exp !== "number") {
|
|
239
|
+
throw new Error("[@holo-js/auth-workos] WorkOS token did not include an expiration.");
|
|
240
|
+
}
|
|
241
|
+
if (exp * 1e3 <= Date.now()) {
|
|
117
242
|
throw new Error("[@holo-js/auth-workos] WorkOS token has expired.");
|
|
118
243
|
}
|
|
244
|
+
if (typeof parsed.payload.sub !== "string" || !parsed.payload.sub.trim()) {
|
|
245
|
+
throw new Error("[@holo-js/auth-workos] WorkOS token did not include a subject.");
|
|
246
|
+
}
|
|
247
|
+
if ((typeof parsed.payload.sid !== "string" || !parsed.payload.sid.trim()) && (typeof parsed.payload.session_id !== "string" || !parsed.payload.session_id.trim())) {
|
|
248
|
+
throw new Error("[@holo-js/auth-workos] WorkOS token did not include a session id.");
|
|
249
|
+
}
|
|
250
|
+
const audience = parsed.payload.aud;
|
|
251
|
+
const audiences = Array.isArray(audience) ? audience.filter((value) => typeof value === "string") : typeof audience === "string" ? [audience] : [];
|
|
252
|
+
if (!audiences.includes(clientId)) {
|
|
253
|
+
throw new Error(`[@holo-js/auth-workos] WorkOS token audience is not valid for client "${clientId}".`);
|
|
254
|
+
}
|
|
119
255
|
const nbf = typeof parsed.payload.nbf === "number" ? parsed.payload.nbf : void 0;
|
|
120
256
|
if (typeof nbf === "number" && nbf * 1e3 > Date.now()) {
|
|
121
257
|
throw new Error("[@holo-js/auth-workos] WorkOS token is not valid yet.");
|
|
122
258
|
}
|
|
123
259
|
return parsed.payload;
|
|
124
260
|
}
|
|
261
|
+
function toWorkosJsonValue(value) {
|
|
262
|
+
if (value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
263
|
+
return value;
|
|
264
|
+
}
|
|
265
|
+
if (Array.isArray(value)) {
|
|
266
|
+
return value.map((item) => toWorkosJsonValue(item)).filter((item) => typeof item !== "undefined");
|
|
267
|
+
}
|
|
268
|
+
if (value && typeof value === "object" && Object.getPrototypeOf(value) === Object.prototype) {
|
|
269
|
+
return Object.freeze(Object.fromEntries(
|
|
270
|
+
Object.entries(value).map(([key, item]) => [key, toWorkosJsonValue(item)]).filter((entry) => typeof entry[1] !== "undefined")
|
|
271
|
+
));
|
|
272
|
+
}
|
|
273
|
+
return void 0;
|
|
274
|
+
}
|
|
275
|
+
function toWorkosJsonObject(value) {
|
|
276
|
+
const normalized = toWorkosJsonValue(value);
|
|
277
|
+
return normalized && typeof normalized === "object" && !Array.isArray(normalized) ? normalized : Object.freeze({});
|
|
278
|
+
}
|
|
125
279
|
function normalizeWorkosUserProfile(user) {
|
|
126
280
|
const firstName = typeof user.firstName === "string" ? user.firstName : typeof user.first_name === "string" ? user.first_name : void 0;
|
|
127
281
|
const lastName = typeof user.lastName === "string" ? user.lastName : typeof user.last_name === "string" ? user.last_name : void 0;
|
|
128
|
-
const name = typeof user.name === "string" ? user.name : [firstName, lastName].filter(Boolean).join(" ").trim()
|
|
282
|
+
const name = typeof user.name === "string" ? user.name : [firstName, lastName].filter(Boolean).join(" ").trim();
|
|
283
|
+
const email = typeof user.email === "string" ? user.email.trim() : "";
|
|
129
284
|
return Object.freeze({
|
|
130
285
|
id: String(user.id ?? ""),
|
|
131
|
-
email
|
|
286
|
+
email,
|
|
132
287
|
emailVerified: user.emailVerified === true || user.email_verified === true,
|
|
133
288
|
firstName,
|
|
134
289
|
lastName,
|
|
135
|
-
name,
|
|
136
|
-
|
|
290
|
+
name: name || email || String(user.id ?? ""),
|
|
291
|
+
profilePictureUrl: typeof user.profilePictureUrl === "string" ? user.profilePictureUrl : typeof user.profile_picture_url === "string" ? user.profile_picture_url : void 0,
|
|
292
|
+
externalId: typeof user.externalId === "string" ? user.externalId : typeof user.external_id === "string" ? user.external_id : void 0,
|
|
137
293
|
organizationId: typeof user.organizationId === "string" ? user.organizationId : typeof user.organization_id === "string" ? user.organization_id : void 0,
|
|
138
|
-
|
|
294
|
+
metadata: toWorkosJsonObject(user.metadata),
|
|
295
|
+
createdAt: typeof user.createdAt === "string" ? user.createdAt : typeof user.created_at === "string" ? user.created_at : void 0,
|
|
296
|
+
updatedAt: typeof user.updatedAt === "string" ? user.updatedAt : typeof user.updated_at === "string" ? user.updated_at : void 0,
|
|
297
|
+
raw: toWorkosJsonObject(user)
|
|
139
298
|
});
|
|
140
299
|
}
|
|
141
300
|
async function fetchWorkosUserProfile(userId, config) {
|
|
@@ -193,7 +352,11 @@ function resolveConfiguredProviderName(provider) {
|
|
|
193
352
|
if (provider?.trim()) {
|
|
194
353
|
return provider.trim();
|
|
195
354
|
}
|
|
196
|
-
const
|
|
355
|
+
const configuredDefaultProvider = typeof bindings.config.workos.provider === "string" ? bindings.config.workos.provider.trim() : "";
|
|
356
|
+
if (configuredDefaultProvider) {
|
|
357
|
+
return configuredDefaultProvider;
|
|
358
|
+
}
|
|
359
|
+
const configuredProviders = Object.entries(bindings.config.workos).flatMap(([name, value]) => name !== "provider" && name !== "identityStore" && isNormalizedWorkosProviderConfig(value) ? [name] : []);
|
|
197
360
|
if (configuredProviders.length === 0) {
|
|
198
361
|
return "default";
|
|
199
362
|
}
|
|
@@ -205,18 +368,20 @@ function resolveConfiguredProviderName(provider) {
|
|
|
205
368
|
}
|
|
206
369
|
throw new Error("[@holo-js/auth-workos] WorkOS provider name is required when multiple auth.workos entries exist.");
|
|
207
370
|
}
|
|
371
|
+
function isNormalizedWorkosProviderConfig(value) {
|
|
372
|
+
return value !== null && typeof value === "object" && "sessionCookie" in value && typeof value.sessionCookie === "string";
|
|
373
|
+
}
|
|
208
374
|
function getConfiguredProviderConfig(provider) {
|
|
209
375
|
const providerName = resolveConfiguredProviderName(provider);
|
|
210
376
|
const authBindings = authRuntimeInternals.getRuntimeBindings();
|
|
211
377
|
const configured = authBindings.config.workos[providerName];
|
|
212
|
-
if (!configured) {
|
|
378
|
+
if (!isNormalizedWorkosProviderConfig(configured)) {
|
|
213
379
|
throw new Error(`[@holo-js/auth-workos] WorkOS provider "${providerName}" is not configured in auth.workos.`);
|
|
214
380
|
}
|
|
215
381
|
return {
|
|
216
382
|
name: providerName,
|
|
217
383
|
clientId: configured.clientId,
|
|
218
384
|
apiKey: configured.apiKey,
|
|
219
|
-
cookiePassword: configured.cookiePassword,
|
|
220
385
|
redirectUri: configured.redirectUri,
|
|
221
386
|
sessionCookie: configured.sessionCookie,
|
|
222
387
|
guard: configured.guard,
|
|
@@ -227,6 +392,98 @@ function getProviderRuntime(provider) {
|
|
|
227
392
|
const providerName = resolveConfiguredProviderName(provider);
|
|
228
393
|
return getBindings().providers[providerName] ?? createDefaultProviderRuntime(providerName, getConfiguredProviderConfig(providerName));
|
|
229
394
|
}
|
|
395
|
+
function requireWorkosClientConfig(config) {
|
|
396
|
+
const clientId = config.clientId?.trim();
|
|
397
|
+
const apiKey = config.apiKey?.trim();
|
|
398
|
+
const redirectUri = config.redirectUri?.trim();
|
|
399
|
+
if (!clientId) {
|
|
400
|
+
throw new Error("[@holo-js/auth-workos] WorkOS AuthKit requires clientId to be configured.");
|
|
401
|
+
}
|
|
402
|
+
if (!apiKey) {
|
|
403
|
+
throw new Error("[@holo-js/auth-workos] WorkOS AuthKit requires apiKey to be configured.");
|
|
404
|
+
}
|
|
405
|
+
if (!redirectUri) {
|
|
406
|
+
throw new Error("[@holo-js/auth-workos] WorkOS AuthKit requires redirectUri to be configured.");
|
|
407
|
+
}
|
|
408
|
+
return { clientId, apiKey, redirectUri };
|
|
409
|
+
}
|
|
410
|
+
function getWorkosStateCookieName(providerName) {
|
|
411
|
+
return `holo_workos_${providerName}_state`;
|
|
412
|
+
}
|
|
413
|
+
function createWorkosState() {
|
|
414
|
+
return randomBytes(32).toString("base64url");
|
|
415
|
+
}
|
|
416
|
+
function createStateCookie(providerName, state, request) {
|
|
417
|
+
return cookie(getWorkosStateCookieName(providerName), state, {
|
|
418
|
+
httpOnly: true,
|
|
419
|
+
maxAge: WORKOS_STATE_COOKIE_MAX_AGE_SECONDS,
|
|
420
|
+
sameSite: "lax",
|
|
421
|
+
secure: new URL(request.url).protocol === "https:"
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
function clearStateCookie(providerName, request) {
|
|
425
|
+
return cookie(getWorkosStateCookieName(providerName), "", {
|
|
426
|
+
expires: /* @__PURE__ */ new Date(0),
|
|
427
|
+
httpOnly: true,
|
|
428
|
+
sameSite: "lax",
|
|
429
|
+
secure: new URL(request.url).protocol === "https:"
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
function getWorkosStateFromRequest(request, providerName) {
|
|
433
|
+
const cookies = parseCookieHeader(request.headers.get("cookie"));
|
|
434
|
+
return cookies[getWorkosStateCookieName(providerName)]?.trim() || void 0;
|
|
435
|
+
}
|
|
436
|
+
function createAuthorizationUrl(config, screenHint, state) {
|
|
437
|
+
const { clientId, redirectUri } = requireWorkosClientConfig(config);
|
|
438
|
+
const url = new URL(WORKOS_AUTHORIZE_URL);
|
|
439
|
+
url.searchParams.set("provider", "authkit");
|
|
440
|
+
url.searchParams.set("response_type", "code");
|
|
441
|
+
url.searchParams.set("client_id", clientId);
|
|
442
|
+
url.searchParams.set("redirect_uri", redirectUri);
|
|
443
|
+
url.searchParams.set("screen_hint", screenHint);
|
|
444
|
+
url.searchParams.set("state", state);
|
|
445
|
+
return url.toString();
|
|
446
|
+
}
|
|
447
|
+
function createWorkosRedirect(request, config, screenHint) {
|
|
448
|
+
const state = createWorkosState();
|
|
449
|
+
return new Response(null, {
|
|
450
|
+
status: 302,
|
|
451
|
+
headers: {
|
|
452
|
+
location: createAuthorizationUrl(config, screenHint, state),
|
|
453
|
+
"set-cookie": createStateCookie(config.name, state, request)
|
|
454
|
+
}
|
|
455
|
+
});
|
|
456
|
+
}
|
|
457
|
+
function createLogoutUrl(sessionId, request, returnTo) {
|
|
458
|
+
const url = new URL(WORKOS_LOGOUT_URL);
|
|
459
|
+
url.searchParams.set("session_id", sessionId);
|
|
460
|
+
if (returnTo?.trim()) {
|
|
461
|
+
url.searchParams.set("return_to", createWorkosReturnUrl(returnTo, request));
|
|
462
|
+
}
|
|
463
|
+
return url.toString();
|
|
464
|
+
}
|
|
465
|
+
function createWorkosReturnUrl(returnTo, request) {
|
|
466
|
+
const requestUrl = new URL(request.url);
|
|
467
|
+
let target;
|
|
468
|
+
try {
|
|
469
|
+
target = new URL(returnTo, requestUrl.origin);
|
|
470
|
+
} catch {
|
|
471
|
+
return requestUrl.origin;
|
|
472
|
+
}
|
|
473
|
+
if (target.origin !== requestUrl.origin) {
|
|
474
|
+
return requestUrl.origin;
|
|
475
|
+
}
|
|
476
|
+
return target.toString();
|
|
477
|
+
}
|
|
478
|
+
function createWorkosErrorResponse(error, code) {
|
|
479
|
+
return Response.json({
|
|
480
|
+
ok: false,
|
|
481
|
+
code,
|
|
482
|
+
message: getErrorMessage(error)
|
|
483
|
+
}, {
|
|
484
|
+
status: error instanceof WorkosAuthConflictError ? 409 : 422
|
|
485
|
+
});
|
|
486
|
+
}
|
|
230
487
|
function resolveGuardAndProvider(provider) {
|
|
231
488
|
const authBindings = authRuntimeInternals.getRuntimeBindings();
|
|
232
489
|
const providerConfig = getConfiguredProviderConfig(provider);
|
|
@@ -265,6 +522,46 @@ function requireUserRecord(user, message) {
|
|
|
265
522
|
}
|
|
266
523
|
return user;
|
|
267
524
|
}
|
|
525
|
+
function requireSerializedUser(user, message) {
|
|
526
|
+
if (typeof user.id === "string" || typeof user.id === "number") {
|
|
527
|
+
return user;
|
|
528
|
+
}
|
|
529
|
+
throw new Error(message);
|
|
530
|
+
}
|
|
531
|
+
function createWorkosSessionPayload(authenticated, session) {
|
|
532
|
+
const user = requireSerializedUser(
|
|
533
|
+
authenticated.user,
|
|
534
|
+
"[@holo-js/auth-workos] WorkOS-authenticated local users must expose a serializable id."
|
|
535
|
+
);
|
|
536
|
+
return Object.freeze({
|
|
537
|
+
guard: authenticated.guard,
|
|
538
|
+
provider: authenticated.authProvider,
|
|
539
|
+
userId: user.id,
|
|
540
|
+
user,
|
|
541
|
+
workos: Object.freeze({
|
|
542
|
+
provider: authenticated.provider,
|
|
543
|
+
sessionId: session.sessionId
|
|
544
|
+
})
|
|
545
|
+
});
|
|
546
|
+
}
|
|
547
|
+
function getWorkosLogoutSession(payload, providerName) {
|
|
548
|
+
if (!payload || typeof payload !== "object" || !("workos" in payload)) {
|
|
549
|
+
return null;
|
|
550
|
+
}
|
|
551
|
+
const workos = payload.workos;
|
|
552
|
+
if (!workos || typeof workos !== "object") {
|
|
553
|
+
return null;
|
|
554
|
+
}
|
|
555
|
+
const provider = workos.provider;
|
|
556
|
+
const sessionId = workos.sessionId;
|
|
557
|
+
if (provider !== providerName || typeof sessionId !== "string" || !sessionId.trim()) {
|
|
558
|
+
return null;
|
|
559
|
+
}
|
|
560
|
+
return Object.freeze({
|
|
561
|
+
provider,
|
|
562
|
+
sessionId
|
|
563
|
+
});
|
|
564
|
+
}
|
|
268
565
|
function serializeLocalUser(adapter, user, providerName) {
|
|
269
566
|
const id = adapter.getId(user);
|
|
270
567
|
const serialized = adapter.serialize ? adapter.serialize(user) : { ...user };
|
|
@@ -277,22 +574,63 @@ function serializeLocalUser(adapter, user, providerName) {
|
|
|
277
574
|
enumerable: false,
|
|
278
575
|
configurable: true
|
|
279
576
|
});
|
|
577
|
+
Object.defineProperty(result, "can", {
|
|
578
|
+
value: () => false,
|
|
579
|
+
enumerable: false,
|
|
580
|
+
configurable: true
|
|
581
|
+
});
|
|
280
582
|
return Object.freeze(result);
|
|
281
583
|
}
|
|
282
584
|
function resolveDisplayName(profile) {
|
|
283
|
-
if (profile.name
|
|
585
|
+
if (typeof profile.name === "string" && profile.name.trim()) {
|
|
586
|
+
return profile.name.trim();
|
|
587
|
+
}
|
|
588
|
+
const fullName = [profile.firstName?.trim(), profile.lastName?.trim()].filter(Boolean).join(" ").trim();
|
|
589
|
+
return fullName || profile.email || profile.id;
|
|
590
|
+
}
|
|
591
|
+
function resolveDisplayNameForUpdate(profile) {
|
|
592
|
+
if (typeof profile.name === "string" && profile.name.trim()) {
|
|
284
593
|
return profile.name.trim();
|
|
285
594
|
}
|
|
286
595
|
const fullName = [profile.firstName?.trim(), profile.lastName?.trim()].filter(Boolean).join(" ").trim();
|
|
287
596
|
return fullName || void 0;
|
|
288
597
|
}
|
|
289
598
|
function resolveEmailForCreation(profile) {
|
|
290
|
-
const normalized = profile.email
|
|
599
|
+
const normalized = typeof profile.email === "string" ? profile.email.trim() : "";
|
|
291
600
|
if (normalized) {
|
|
292
601
|
return normalized;
|
|
293
602
|
}
|
|
294
603
|
return `${profile.id}@workos.hosted.local`;
|
|
295
604
|
}
|
|
605
|
+
function toAdapterInput(input) {
|
|
606
|
+
return Object.freeze(Object.fromEntries(
|
|
607
|
+
Object.entries(input).filter((entry) => typeof entry[1] !== "undefined")
|
|
608
|
+
));
|
|
609
|
+
}
|
|
610
|
+
function withRequiredUserFields(input, profile) {
|
|
611
|
+
return Object.freeze({
|
|
612
|
+
...input,
|
|
613
|
+
email: typeof input.email === "undefined" ? resolveEmailForCreation(profile) : input.email,
|
|
614
|
+
name: typeof input.name === "undefined" ? resolveDisplayName(profile) : input.name
|
|
615
|
+
});
|
|
616
|
+
}
|
|
617
|
+
function resolveCreateUserInput(profile, mapper) {
|
|
618
|
+
return toAdapterInput(withRequiredUserFields({
|
|
619
|
+
password: null,
|
|
620
|
+
avatar: profile.profilePictureUrl ?? null,
|
|
621
|
+
email_verified_at: profile.emailVerified ? /* @__PURE__ */ new Date() : null,
|
|
622
|
+
...mapper?.(profile) ?? {}
|
|
623
|
+
}, profile));
|
|
624
|
+
}
|
|
625
|
+
function resolveUpdateUserInput(profile, mapper) {
|
|
626
|
+
return toAdapterInput({
|
|
627
|
+
email: typeof profile.email === "string" ? profile.email.trim() || void 0 : void 0,
|
|
628
|
+
name: resolveDisplayNameForUpdate(profile),
|
|
629
|
+
avatar: profile.profilePictureUrl,
|
|
630
|
+
email_verified_at: profile.emailVerified ? /* @__PURE__ */ new Date() : void 0,
|
|
631
|
+
...mapper?.(profile) ?? {}
|
|
632
|
+
});
|
|
633
|
+
}
|
|
296
634
|
function normalizeHostedProfile(profile) {
|
|
297
635
|
return Object.freeze({
|
|
298
636
|
id: profile.id,
|
|
@@ -301,7 +639,7 @@ function normalizeHostedProfile(profile) {
|
|
|
301
639
|
firstName: profile.firstName,
|
|
302
640
|
lastName: profile.lastName,
|
|
303
641
|
name: resolveDisplayName(profile),
|
|
304
|
-
|
|
642
|
+
profilePictureUrl: profile.profilePictureUrl,
|
|
305
643
|
organizationId: profile.organizationId,
|
|
306
644
|
raw: profile.raw
|
|
307
645
|
});
|
|
@@ -314,21 +652,20 @@ async function findUserByEmail(adapter, email) {
|
|
|
314
652
|
return user ? requireUserRecord(user, "[@holo-js/auth-workos] Auth provider lookups must return object users.") : null;
|
|
315
653
|
}
|
|
316
654
|
async function updateLocalUser(adapter, user, input) {
|
|
317
|
-
const nextInput = {
|
|
318
|
-
name: input.name,
|
|
319
|
-
email: input.email,
|
|
320
|
-
avatar: typeof input.avatar === "undefined" ? void 0 : input.avatar,
|
|
321
|
-
email_verified_at: input.emailVerified === true ? /* @__PURE__ */ new Date() : void 0
|
|
322
|
-
};
|
|
323
655
|
const current = user;
|
|
324
|
-
const changed =
|
|
656
|
+
const changed = Object.entries(input).some(([key, value]) => {
|
|
657
|
+
if (key === "email_verified_at") {
|
|
658
|
+
return value instanceof Date && !current.email_verified_at;
|
|
659
|
+
}
|
|
660
|
+
return !Object.is(value, user[key]);
|
|
661
|
+
});
|
|
325
662
|
if (!changed) {
|
|
326
663
|
return { user, changed: false };
|
|
327
664
|
}
|
|
328
665
|
if (adapter.update) {
|
|
329
666
|
return {
|
|
330
667
|
user: requireUserRecord(
|
|
331
|
-
await adapter.update(user,
|
|
668
|
+
await adapter.update(user, input),
|
|
332
669
|
"[@holo-js/auth-workos] Auth provider updates must return object users."
|
|
333
670
|
),
|
|
334
671
|
changed: true
|
|
@@ -338,8 +675,8 @@ async function updateLocalUser(adapter, user, input) {
|
|
|
338
675
|
"[@holo-js/auth-workos] Auth provider adapters must implement update() to persist profile changes."
|
|
339
676
|
);
|
|
340
677
|
}
|
|
341
|
-
async function ensureNoUnexpectedEmailCollision(adapter,
|
|
342
|
-
const email = profile.email
|
|
678
|
+
async function ensureNoUnexpectedEmailCollision(adapter, providerName, profile, currentUserId) {
|
|
679
|
+
const email = typeof profile.email === "string" ? profile.email.trim() : "";
|
|
343
680
|
if (!email) {
|
|
344
681
|
return;
|
|
345
682
|
}
|
|
@@ -353,28 +690,13 @@ async function ensureNoUnexpectedEmailCollision(adapter, authProvider, profile,
|
|
|
353
690
|
"[@holo-js/auth-workos] Matched local users must expose a serializable id."
|
|
354
691
|
) !== currentUserId) {
|
|
355
692
|
throw new WorkosAuthConflictError({
|
|
356
|
-
provider:
|
|
693
|
+
provider: providerName,
|
|
357
694
|
workosUserId: profile.id,
|
|
358
695
|
email,
|
|
359
696
|
message: `[@holo-js/auth-workos] WorkOS email "${email}" collides with a different local user.`
|
|
360
697
|
});
|
|
361
698
|
}
|
|
362
699
|
}
|
|
363
|
-
async function assertUserLinkAvailable(providerName, authProvider, adapter, user, workosUserId) {
|
|
364
|
-
const existing = await getBindings().identityStore.findByUserId(
|
|
365
|
-
providerName,
|
|
366
|
-
authProvider,
|
|
367
|
-
requireUserId(adapter, user, "[@holo-js/auth-workos] Linked users must expose a serializable id.")
|
|
368
|
-
);
|
|
369
|
-
if (existing && existing.providerUserId !== workosUserId) {
|
|
370
|
-
throw new WorkosAuthConflictError({
|
|
371
|
-
provider: providerName,
|
|
372
|
-
workosUserId,
|
|
373
|
-
email: existing.email,
|
|
374
|
-
message: `[@holo-js/auth-workos] Local user is already linked to WorkOS identity "${existing.providerUserId}".`
|
|
375
|
-
});
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
700
|
function isEmailVerificationRequired() {
|
|
379
701
|
return authRuntimeInternals.getRuntimeBindings().config.emailVerification.required === true;
|
|
380
702
|
}
|
|
@@ -426,9 +748,16 @@ async function reuseExistingHoloSession(request, authenticated) {
|
|
|
426
748
|
if (!payload || payload.guard !== authenticated.guard || payload.provider !== authenticated.authProvider || String(payload.userId) !== String(authenticated.user.id)) {
|
|
427
749
|
return null;
|
|
428
750
|
}
|
|
751
|
+
const source = payload;
|
|
752
|
+
if (source.workos && typeof source.workos === "object") {
|
|
753
|
+
if (typeof source.workos.provider !== "string" || source.workos.provider !== authenticated.provider) {
|
|
754
|
+
return null;
|
|
755
|
+
}
|
|
756
|
+
}
|
|
429
757
|
bindings.context.setCachedUser(authenticated.guard, authenticated.user);
|
|
430
758
|
return Object.freeze({
|
|
431
759
|
guard: authenticated.guard,
|
|
760
|
+
provider: source.workos && typeof source.workos === "object" ? "workos" : payload.provider,
|
|
432
761
|
user: authenticated.user,
|
|
433
762
|
sessionId,
|
|
434
763
|
cookies: Object.freeze([])
|
|
@@ -446,7 +775,8 @@ async function verifySession(token, provider) {
|
|
|
446
775
|
config: providerConfig
|
|
447
776
|
});
|
|
448
777
|
}
|
|
449
|
-
async function verifyRequest(
|
|
778
|
+
async function verifyRequest(input, provider) {
|
|
779
|
+
const request = normalizeWorkosRequest(input);
|
|
450
780
|
const providerConfig = getConfiguredProviderConfig(provider);
|
|
451
781
|
const runtime = getProviderRuntime(providerConfig.name);
|
|
452
782
|
if (runtime.verifyRequest) {
|
|
@@ -462,13 +792,72 @@ async function verifyRequest(request, provider) {
|
|
|
462
792
|
}
|
|
463
793
|
return verifySession(token, providerConfig.name);
|
|
464
794
|
}
|
|
465
|
-
|
|
795
|
+
function getStringField(input, ...names) {
|
|
796
|
+
for (const name of names) {
|
|
797
|
+
const value = input[name];
|
|
798
|
+
const normalized = typeof value === "string" ? value.trim() : "";
|
|
799
|
+
if (normalized) {
|
|
800
|
+
return normalized;
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
return void 0;
|
|
804
|
+
}
|
|
805
|
+
function getRecordField(input, name) {
|
|
806
|
+
const value = input[name];
|
|
807
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
808
|
+
}
|
|
809
|
+
function getRequestIpAddress(request) {
|
|
810
|
+
return request.headers.get("x-forwarded-for")?.split(",")[0]?.trim() || request.headers.get("x-real-ip")?.trim() || void 0;
|
|
811
|
+
}
|
|
812
|
+
async function authenticateWorkosCode(request, code, config) {
|
|
813
|
+
const { clientId, apiKey } = requireWorkosClientConfig(config);
|
|
814
|
+
const body = {
|
|
815
|
+
grant_type: "authorization_code",
|
|
816
|
+
client_id: clientId,
|
|
817
|
+
client_secret: apiKey,
|
|
818
|
+
code,
|
|
819
|
+
ip_address: getRequestIpAddress(request),
|
|
820
|
+
user_agent: request.headers.get("user-agent")?.trim() || void 0
|
|
821
|
+
};
|
|
822
|
+
const response = await fetch(WORKOS_AUTHENTICATE_URL, {
|
|
823
|
+
method: "POST",
|
|
824
|
+
headers: {
|
|
825
|
+
accept: "application/json",
|
|
826
|
+
authorization: `Bearer ${apiKey}`,
|
|
827
|
+
"content-type": "application/json"
|
|
828
|
+
},
|
|
829
|
+
body: JSON.stringify(body)
|
|
830
|
+
});
|
|
831
|
+
const payload = await response.json();
|
|
832
|
+
if (!response.ok) {
|
|
833
|
+
const message = getStringField(payload, "message", "error_description", "error") ?? `WorkOS callback authentication failed with status ${response.status}.`;
|
|
834
|
+
throw new Error(message);
|
|
835
|
+
}
|
|
836
|
+
const user = getRecordField(payload, "user");
|
|
837
|
+
if (!user) {
|
|
838
|
+
throw new Error("[@holo-js/auth-workos] WorkOS callback did not return a user.");
|
|
839
|
+
}
|
|
840
|
+
const accessToken = getStringField(payload, "accessToken", "access_token");
|
|
841
|
+
const session = getRecordField(payload, "session");
|
|
842
|
+
const sessionId = getStringField(session ?? {}, "id") ?? getStringField(payload, "sessionId", "session_id") ?? (accessToken ? getJwtStringClaim(accessToken, "sid") : void 0) ?? accessToken ?? code;
|
|
843
|
+
return Object.freeze({
|
|
844
|
+
sessionId,
|
|
845
|
+
identity: normalizeWorkosUserProfile({
|
|
846
|
+
...user,
|
|
847
|
+
organizationId: getStringField(payload, "organizationId", "organization_id") ?? user.organizationId ?? user.organization_id
|
|
848
|
+
}),
|
|
849
|
+
accessToken,
|
|
850
|
+
raw: toWorkosJsonObject(payload)
|
|
851
|
+
});
|
|
852
|
+
}
|
|
853
|
+
async function syncIdentity(session, provider, options = {}) {
|
|
466
854
|
const providerConfig = getConfiguredProviderConfig(provider);
|
|
467
855
|
const providerName = providerConfig.name;
|
|
468
856
|
const profile = session.identity;
|
|
469
857
|
const { guard, authProvider, adapter } = resolveGuardAndProvider(providerName);
|
|
470
858
|
const verificationRequired = isEmailVerificationRequired();
|
|
471
|
-
const
|
|
859
|
+
const profileEmail = typeof profile.email === "string" ? profile.email.trim() : "";
|
|
860
|
+
const verifiedEmail = profile.emailVerified === true && profileEmail ? profileEmail : void 0;
|
|
472
861
|
if (verificationRequired && !verifiedEmail) {
|
|
473
862
|
throw new Error(`[@holo-js/auth-workos] WorkOS identity "${profile.id}" must provide a verified email address.`);
|
|
474
863
|
}
|
|
@@ -478,25 +867,20 @@ async function syncIdentity(session, provider) {
|
|
|
478
867
|
const existingLinkedUser = await adapter.findById(existingIdentity.userId);
|
|
479
868
|
let linkedUser = existingLinkedUser ? requireUserRecord(existingLinkedUser, "[@holo-js/auth-workos] Auth provider lookups must return object users.") : null;
|
|
480
869
|
if (!linkedUser) {
|
|
481
|
-
|
|
482
|
-
if (
|
|
483
|
-
|
|
870
|
+
const emailMatchedUser = verifiedEmail ? await findUserByEmail(adapter, verifiedEmail) : null;
|
|
871
|
+
if (emailMatchedUser) {
|
|
872
|
+
throw new WorkosAuthConflictError({
|
|
873
|
+
provider: providerName,
|
|
874
|
+
workosUserId: profile.id,
|
|
875
|
+
email: verifiedEmail,
|
|
876
|
+
message: `[@holo-js/auth-workos] WorkOS email "${verifiedEmail}" matches an existing local user and must be linked explicitly.`
|
|
877
|
+
});
|
|
484
878
|
}
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
avatar: profile.avatar ?? null,
|
|
491
|
-
email_verified_at: profile.emailVerified === true ? /* @__PURE__ */ new Date() : null
|
|
492
|
-
}), "[@holo-js/auth-workos] Auth provider create() must return an object user.");
|
|
493
|
-
}
|
|
494
|
-
const relinked = await updateLocalUser(adapter, linkedUser, {
|
|
495
|
-
name: resolveDisplayName(profile),
|
|
496
|
-
email: profile.email?.trim(),
|
|
497
|
-
avatar: profile.avatar,
|
|
498
|
-
emailVerified: profile.emailVerified === true
|
|
499
|
-
});
|
|
879
|
+
linkedUser = requireUserRecord(
|
|
880
|
+
await adapter.create(resolveCreateUserInput(profile, options.user)),
|
|
881
|
+
"[@holo-js/auth-workos] Auth provider create() must return an object user."
|
|
882
|
+
);
|
|
883
|
+
const relinked = await updateLocalUser(adapter, linkedUser, resolveUpdateUserInput(profile, options.user));
|
|
500
884
|
const relinkedUser = relinked.user;
|
|
501
885
|
const identity3 = createIdentityRecord({
|
|
502
886
|
provider: providerName,
|
|
@@ -523,7 +907,7 @@ async function syncIdentity(session, provider) {
|
|
|
523
907
|
}
|
|
524
908
|
await ensureNoUnexpectedEmailCollision(
|
|
525
909
|
adapter,
|
|
526
|
-
|
|
910
|
+
providerName,
|
|
527
911
|
profile,
|
|
528
912
|
requireUserId(
|
|
529
913
|
adapter,
|
|
@@ -531,12 +915,7 @@ async function syncIdentity(session, provider) {
|
|
|
531
915
|
"[@holo-js/auth-workos] Linked local users must expose a serializable id."
|
|
532
916
|
)
|
|
533
917
|
);
|
|
534
|
-
const updated = await updateLocalUser(adapter, linkedUser,
|
|
535
|
-
name: resolveDisplayName(profile),
|
|
536
|
-
email: profile.email?.trim(),
|
|
537
|
-
avatar: profile.avatar,
|
|
538
|
-
emailVerified: profile.emailVerified === true
|
|
539
|
-
});
|
|
918
|
+
const updated = await updateLocalUser(adapter, linkedUser, resolveUpdateUserInput(profile, options.user));
|
|
540
919
|
const identity2 = createIdentityRecord({
|
|
541
920
|
provider: providerName,
|
|
542
921
|
guard,
|
|
@@ -562,42 +941,17 @@ async function syncIdentity(session, provider) {
|
|
|
562
941
|
}
|
|
563
942
|
let localUser = verifiedEmail ? await findUserByEmail(adapter, verifiedEmail) : null;
|
|
564
943
|
if (localUser) {
|
|
565
|
-
|
|
566
|
-
const linked = await updateLocalUser(adapter, localUser, {
|
|
567
|
-
name: resolveDisplayName(profile),
|
|
568
|
-
email: profile.email?.trim(),
|
|
569
|
-
avatar: profile.avatar,
|
|
570
|
-
emailVerified: profile.emailVerified === true
|
|
571
|
-
});
|
|
572
|
-
const identity2 = createIdentityRecord({
|
|
573
|
-
provider: providerName,
|
|
574
|
-
guard,
|
|
575
|
-
authProvider,
|
|
576
|
-
userId: requireUserId(
|
|
577
|
-
adapter,
|
|
578
|
-
linked.user,
|
|
579
|
-
"[@holo-js/auth-workos] Linked local users must expose a serializable id."
|
|
580
|
-
),
|
|
581
|
-
profile
|
|
582
|
-
});
|
|
583
|
-
await identityStore.save(identity2);
|
|
584
|
-
return Object.freeze({
|
|
944
|
+
throw new WorkosAuthConflictError({
|
|
585
945
|
provider: providerName,
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
user: serializeLocalUser(adapter, linked.user, authProvider),
|
|
590
|
-
identity: identity2,
|
|
591
|
-
session
|
|
946
|
+
workosUserId: profile.id,
|
|
947
|
+
email: verifiedEmail,
|
|
948
|
+
message: `[@holo-js/auth-workos] WorkOS email "${verifiedEmail}" matches an existing local user and must be linked explicitly.`
|
|
592
949
|
});
|
|
593
950
|
}
|
|
594
|
-
localUser = requireUserRecord(
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
avatar: profile.avatar ?? null,
|
|
599
|
-
email_verified_at: profile.emailVerified === true ? /* @__PURE__ */ new Date() : null
|
|
600
|
-
}), "[@holo-js/auth-workos] Auth provider create() must return an object user.");
|
|
951
|
+
localUser = requireUserRecord(
|
|
952
|
+
await adapter.create(resolveCreateUserInput(profile, options.user)),
|
|
953
|
+
"[@holo-js/auth-workos] Auth provider create() must return an object user."
|
|
954
|
+
);
|
|
601
955
|
const identity = createIdentityRecord({
|
|
602
956
|
provider: providerName,
|
|
603
957
|
guard,
|
|
@@ -620,7 +974,8 @@ async function syncIdentity(session, provider) {
|
|
|
620
974
|
session
|
|
621
975
|
});
|
|
622
976
|
}
|
|
623
|
-
async function authenticate(
|
|
977
|
+
async function authenticate(input, provider) {
|
|
978
|
+
const request = normalizeWorkosRequest(input);
|
|
624
979
|
const session = await verifyRequest(request, provider);
|
|
625
980
|
if (!session) {
|
|
626
981
|
return null;
|
|
@@ -628,28 +983,175 @@ async function authenticate(request, provider) {
|
|
|
628
983
|
const authenticated = await syncIdentity(session, provider);
|
|
629
984
|
const authSession = await reuseExistingHoloSession(request, authenticated) ?? await authRuntimeInternals.establishSessionForUser(authenticated.user, {
|
|
630
985
|
guard: authenticated.guard,
|
|
631
|
-
provider: authenticated.authProvider
|
|
986
|
+
provider: authenticated.authProvider,
|
|
987
|
+
payload: createWorkosSessionPayload(authenticated, session)
|
|
632
988
|
});
|
|
633
989
|
return Object.freeze({
|
|
634
990
|
...authenticated,
|
|
635
991
|
authSession
|
|
636
992
|
});
|
|
637
993
|
}
|
|
994
|
+
function getErrorMessage(error) {
|
|
995
|
+
return error instanceof Error ? error.message : "WorkOS authentication failed.";
|
|
996
|
+
}
|
|
997
|
+
function createHostedAuthSuccess(data) {
|
|
998
|
+
return Object.freeze({
|
|
999
|
+
data,
|
|
1000
|
+
error: null
|
|
1001
|
+
});
|
|
1002
|
+
}
|
|
1003
|
+
function createHostedAuthFailure(code, message, status) {
|
|
1004
|
+
return Object.freeze({
|
|
1005
|
+
data: null,
|
|
1006
|
+
error: Object.freeze({
|
|
1007
|
+
code,
|
|
1008
|
+
message,
|
|
1009
|
+
status,
|
|
1010
|
+
fields: Object.freeze({
|
|
1011
|
+
_root: Object.freeze([message])
|
|
1012
|
+
})
|
|
1013
|
+
})
|
|
1014
|
+
});
|
|
1015
|
+
}
|
|
1016
|
+
async function loginWithWorkos(input, options = {}) {
|
|
1017
|
+
try {
|
|
1018
|
+
const request = normalizeWorkosRequest(input);
|
|
1019
|
+
const providerConfig = getConfiguredProviderConfig(options.provider);
|
|
1020
|
+
return createWorkosRedirect(request, providerConfig, "sign-in");
|
|
1021
|
+
} catch (error) {
|
|
1022
|
+
return createWorkosErrorResponse(error, "workos_login_failed");
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1025
|
+
async function registerWithWorkos(input, options = {}) {
|
|
1026
|
+
try {
|
|
1027
|
+
const request = normalizeWorkosRequest(input);
|
|
1028
|
+
const providerConfig = getConfiguredProviderConfig(options.provider);
|
|
1029
|
+
return createWorkosRedirect(request, providerConfig, "sign-up");
|
|
1030
|
+
} catch (error) {
|
|
1031
|
+
return createWorkosErrorResponse(error, "workos_register_failed");
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
async function readCurrentWorkosLogoutSession(guard, providerName) {
|
|
1035
|
+
const bindings = authRuntimeInternals.getRuntimeBindings();
|
|
1036
|
+
const sessionId = bindings.context.getSessionId(guard);
|
|
1037
|
+
if (!sessionId) {
|
|
1038
|
+
return null;
|
|
1039
|
+
}
|
|
1040
|
+
const record = await bindings.session.read(sessionId);
|
|
1041
|
+
return getWorkosLogoutSession(authRuntimeInternals.readSessionPayload(record, guard), providerName);
|
|
1042
|
+
}
|
|
1043
|
+
async function logoutWithWorkos(input, options = {}) {
|
|
1044
|
+
const request = normalizeWorkosRequest(input);
|
|
1045
|
+
try {
|
|
1046
|
+
const providerConfig = getConfiguredProviderConfig(options.provider);
|
|
1047
|
+
const providerName = providerConfig.name;
|
|
1048
|
+
const { guard } = resolveGuardAndProvider(providerName);
|
|
1049
|
+
const requestSessionId = getHoloSessionIdFromRequest(request);
|
|
1050
|
+
if (requestSessionId) {
|
|
1051
|
+
authRuntimeInternals.getRuntimeBindings().context.setSessionId(guard, requestSessionId);
|
|
1052
|
+
}
|
|
1053
|
+
const workosSession = await readCurrentWorkosLogoutSession(guard, providerName);
|
|
1054
|
+
if (!workosSession) {
|
|
1055
|
+
return createHostedAuthFailure(
|
|
1056
|
+
"workos_session_missing",
|
|
1057
|
+
"The current Holo session was not created by WorkOS.",
|
|
1058
|
+
422
|
|
1059
|
+
);
|
|
1060
|
+
}
|
|
1061
|
+
const local = await getAuthRuntime().guard(guard).logout();
|
|
1062
|
+
return createHostedAuthSuccess(Object.freeze({
|
|
1063
|
+
url: createLogoutUrl(workosSession.sessionId, request, options.returnTo),
|
|
1064
|
+
local
|
|
1065
|
+
}));
|
|
1066
|
+
} catch {
|
|
1067
|
+
return createHostedAuthFailure("workos_logout_failed", "Unable to complete WorkOS logout.", 500);
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1070
|
+
async function completeWorkosAuth(input, options = {}) {
|
|
1071
|
+
try {
|
|
1072
|
+
const request = normalizeWorkosRequest(input);
|
|
1073
|
+
const url = new URL(request.url);
|
|
1074
|
+
const callbackError = url.searchParams.get("error")?.trim();
|
|
1075
|
+
if (callbackError) {
|
|
1076
|
+
return createHostedAuthFailure(
|
|
1077
|
+
callbackError,
|
|
1078
|
+
url.searchParams.get("error_description")?.trim() || "WorkOS authentication failed.",
|
|
1079
|
+
422
|
|
1080
|
+
);
|
|
1081
|
+
}
|
|
1082
|
+
const code = url.searchParams.get("code")?.trim();
|
|
1083
|
+
if (!code) {
|
|
1084
|
+
return createHostedAuthFailure(
|
|
1085
|
+
"workos_code_required",
|
|
1086
|
+
"WorkOS callback did not include an authorization code.",
|
|
1087
|
+
422
|
|
1088
|
+
);
|
|
1089
|
+
}
|
|
1090
|
+
const providerConfig = getConfiguredProviderConfig(options.provider);
|
|
1091
|
+
const callbackState = url.searchParams.get("state")?.trim();
|
|
1092
|
+
const expectedState = getWorkosStateFromRequest(request, providerConfig.name);
|
|
1093
|
+
if (!callbackState || !expectedState || !Object.is(callbackState, expectedState)) {
|
|
1094
|
+
return createHostedAuthFailure(
|
|
1095
|
+
"workos_state_mismatch",
|
|
1096
|
+
"WorkOS callback state did not match the login request.",
|
|
1097
|
+
422
|
|
1098
|
+
);
|
|
1099
|
+
}
|
|
1100
|
+
const session = await authenticateWorkosCode(request, code, providerConfig);
|
|
1101
|
+
const authenticated = await syncIdentity(session, providerConfig.name, {
|
|
1102
|
+
user: options.user
|
|
1103
|
+
});
|
|
1104
|
+
const authSession = await authRuntimeInternals.establishSessionForUser(authenticated.user, {
|
|
1105
|
+
guard: authenticated.guard,
|
|
1106
|
+
provider: authenticated.authProvider,
|
|
1107
|
+
payload: createWorkosSessionPayload(authenticated, session)
|
|
1108
|
+
});
|
|
1109
|
+
return createHostedAuthSuccess(Object.freeze({
|
|
1110
|
+
provider: authenticated.provider,
|
|
1111
|
+
guard: authenticated.guard,
|
|
1112
|
+
authProvider: authenticated.authProvider,
|
|
1113
|
+
status: authenticated.status,
|
|
1114
|
+
user: authenticated.user,
|
|
1115
|
+
identity: authenticated.identity,
|
|
1116
|
+
session,
|
|
1117
|
+
authSession: Object.freeze({
|
|
1118
|
+
...authSession,
|
|
1119
|
+
cookies: Object.freeze([
|
|
1120
|
+
...authSession.cookies,
|
|
1121
|
+
clearStateCookie(providerConfig.name, request)
|
|
1122
|
+
])
|
|
1123
|
+
})
|
|
1124
|
+
}));
|
|
1125
|
+
} catch (error) {
|
|
1126
|
+
return createHostedAuthFailure(
|
|
1127
|
+
error instanceof WorkosAuthConflictError ? error.code : "workos_auth_failed",
|
|
1128
|
+
getErrorMessage(error),
|
|
1129
|
+
error instanceof WorkosAuthConflictError ? 409 : 422
|
|
1130
|
+
);
|
|
1131
|
+
}
|
|
1132
|
+
}
|
|
638
1133
|
function configureWorkosAuthRuntime(bindings) {
|
|
1134
|
+
const runtimeState = getRuntimeState();
|
|
639
1135
|
if (!bindings) {
|
|
640
|
-
|
|
1136
|
+
runtimeState.bindings = void 0;
|
|
641
1137
|
return;
|
|
642
1138
|
}
|
|
643
|
-
|
|
644
|
-
providers: bindings.providers ??
|
|
645
|
-
identityStore: bindings.identityStore ??
|
|
1139
|
+
runtimeState.bindings = Object.freeze({
|
|
1140
|
+
providers: bindings.providers ?? runtimeState.bindings?.providers,
|
|
1141
|
+
identityStore: bindings.identityStore ?? runtimeState.bindings?.identityStore
|
|
646
1142
|
});
|
|
647
1143
|
}
|
|
648
1144
|
function resetWorkosAuthRuntime() {
|
|
649
|
-
|
|
1145
|
+
getRuntimeState().bindings = void 0;
|
|
1146
|
+
workosDefaultProviderRuntimeCache.clear();
|
|
1147
|
+
workosJwksCache.clear();
|
|
650
1148
|
}
|
|
651
1149
|
var workosAuth = Object.freeze({
|
|
652
1150
|
authenticate,
|
|
1151
|
+
completeWorkosAuth,
|
|
1152
|
+
loginWithWorkos,
|
|
1153
|
+
logoutWithWorkos,
|
|
1154
|
+
registerWithWorkos,
|
|
653
1155
|
syncIdentity,
|
|
654
1156
|
verifyRequest,
|
|
655
1157
|
verifySession
|
|
@@ -667,7 +1169,11 @@ var workosAuthInternals = {
|
|
|
667
1169
|
export {
|
|
668
1170
|
WorkosAuthConflictError,
|
|
669
1171
|
authenticate,
|
|
1172
|
+
completeWorkosAuth,
|
|
670
1173
|
configureWorkosAuthRuntime,
|
|
1174
|
+
loginWithWorkos,
|
|
1175
|
+
logoutWithWorkos,
|
|
1176
|
+
registerWithWorkos,
|
|
671
1177
|
resetWorkosAuthRuntime,
|
|
672
1178
|
syncIdentity,
|
|
673
1179
|
verifyRequest,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@holo-js/auth-workos",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"description": "Holo-JS Framework - WorkOS auth integration contracts",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -23,14 +23,14 @@
|
|
|
23
23
|
"test": "vitest --run"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@holo-js/auth": "
|
|
27
|
-
"@holo-js/config": "
|
|
28
|
-
"@holo-js/session": "
|
|
26
|
+
"@holo-js/auth": "^0.1.6",
|
|
27
|
+
"@holo-js/config": "^0.1.6",
|
|
28
|
+
"@holo-js/session": "^0.1.6"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@types/node": "^22.10.2",
|
|
32
32
|
"tsup": "^8.3.5",
|
|
33
33
|
"typescript": "^5.7.2",
|
|
34
|
-
"vitest": "^
|
|
34
|
+
"vitest": "^4.1.5"
|
|
35
35
|
}
|
|
36
36
|
}
|