@weirdfingers/boards-auth-clerk 0.9.13
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.mts +69 -0
- package/dist/index.d.ts +69 -0
- package/dist/index.js +219 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +182 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +48 -0
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { AuthProviderConfig, BaseAuthProvider, AuthState, User } from '@weirdfingers/boards';
|
|
2
|
+
export { AuthContextValue, AuthProviderConfig, AuthState, User } from '@weirdfingers/boards';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Clerk auth provider types.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
interface ClerkConfig extends AuthProviderConfig {
|
|
9
|
+
/**
|
|
10
|
+
* Clerk publishable key.
|
|
11
|
+
*/
|
|
12
|
+
publishableKey: string;
|
|
13
|
+
/**
|
|
14
|
+
* Optional Clerk options.
|
|
15
|
+
*/
|
|
16
|
+
options?: {
|
|
17
|
+
debug?: boolean;
|
|
18
|
+
localization?: any;
|
|
19
|
+
appearance?: any;
|
|
20
|
+
[key: string]: unknown;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Clerk authentication provider.
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
declare class ClerkAuthProvider extends BaseAuthProvider {
|
|
29
|
+
protected config: ClerkConfig;
|
|
30
|
+
private listeners;
|
|
31
|
+
private currentState;
|
|
32
|
+
private clerk;
|
|
33
|
+
constructor(config: ClerkConfig);
|
|
34
|
+
initialize(): Promise<void>;
|
|
35
|
+
getAuthState(): Promise<AuthState>;
|
|
36
|
+
signIn(options?: {
|
|
37
|
+
strategy?: "oauth_google" | "oauth_github" | "oauth_discord" | "email_code" | "password";
|
|
38
|
+
identifier?: string;
|
|
39
|
+
password?: string;
|
|
40
|
+
code?: string;
|
|
41
|
+
redirectUrl?: string;
|
|
42
|
+
[key: string]: unknown;
|
|
43
|
+
}): Promise<void>;
|
|
44
|
+
signOut(): Promise<void>;
|
|
45
|
+
getToken(): Promise<string | null>;
|
|
46
|
+
getUser(): Promise<User | null>;
|
|
47
|
+
onAuthStateChange(callback: (state: AuthState) => void): () => void;
|
|
48
|
+
destroy(): Promise<void>;
|
|
49
|
+
private handleClerkUpdate;
|
|
50
|
+
private updateState;
|
|
51
|
+
/**
|
|
52
|
+
* Get the underlying Clerk instance for advanced operations.
|
|
53
|
+
*/
|
|
54
|
+
getClerkInstance(): any;
|
|
55
|
+
/**
|
|
56
|
+
* Open Clerk user profile modal.
|
|
57
|
+
*/
|
|
58
|
+
openUserProfile(): Promise<void>;
|
|
59
|
+
/**
|
|
60
|
+
* Open Clerk organization switcher.
|
|
61
|
+
*/
|
|
62
|
+
openOrganizationSwitcher(): Promise<void>;
|
|
63
|
+
/**
|
|
64
|
+
* Verify an email code (after email_code sign in).
|
|
65
|
+
*/
|
|
66
|
+
verifyEmailCode(code: string): Promise<void>;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export { ClerkAuthProvider, type ClerkConfig };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { AuthProviderConfig, BaseAuthProvider, AuthState, User } from '@weirdfingers/boards';
|
|
2
|
+
export { AuthContextValue, AuthProviderConfig, AuthState, User } from '@weirdfingers/boards';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Clerk auth provider types.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
interface ClerkConfig extends AuthProviderConfig {
|
|
9
|
+
/**
|
|
10
|
+
* Clerk publishable key.
|
|
11
|
+
*/
|
|
12
|
+
publishableKey: string;
|
|
13
|
+
/**
|
|
14
|
+
* Optional Clerk options.
|
|
15
|
+
*/
|
|
16
|
+
options?: {
|
|
17
|
+
debug?: boolean;
|
|
18
|
+
localization?: any;
|
|
19
|
+
appearance?: any;
|
|
20
|
+
[key: string]: unknown;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Clerk authentication provider.
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
declare class ClerkAuthProvider extends BaseAuthProvider {
|
|
29
|
+
protected config: ClerkConfig;
|
|
30
|
+
private listeners;
|
|
31
|
+
private currentState;
|
|
32
|
+
private clerk;
|
|
33
|
+
constructor(config: ClerkConfig);
|
|
34
|
+
initialize(): Promise<void>;
|
|
35
|
+
getAuthState(): Promise<AuthState>;
|
|
36
|
+
signIn(options?: {
|
|
37
|
+
strategy?: "oauth_google" | "oauth_github" | "oauth_discord" | "email_code" | "password";
|
|
38
|
+
identifier?: string;
|
|
39
|
+
password?: string;
|
|
40
|
+
code?: string;
|
|
41
|
+
redirectUrl?: string;
|
|
42
|
+
[key: string]: unknown;
|
|
43
|
+
}): Promise<void>;
|
|
44
|
+
signOut(): Promise<void>;
|
|
45
|
+
getToken(): Promise<string | null>;
|
|
46
|
+
getUser(): Promise<User | null>;
|
|
47
|
+
onAuthStateChange(callback: (state: AuthState) => void): () => void;
|
|
48
|
+
destroy(): Promise<void>;
|
|
49
|
+
private handleClerkUpdate;
|
|
50
|
+
private updateState;
|
|
51
|
+
/**
|
|
52
|
+
* Get the underlying Clerk instance for advanced operations.
|
|
53
|
+
*/
|
|
54
|
+
getClerkInstance(): any;
|
|
55
|
+
/**
|
|
56
|
+
* Open Clerk user profile modal.
|
|
57
|
+
*/
|
|
58
|
+
openUserProfile(): Promise<void>;
|
|
59
|
+
/**
|
|
60
|
+
* Open Clerk organization switcher.
|
|
61
|
+
*/
|
|
62
|
+
openOrganizationSwitcher(): Promise<void>;
|
|
63
|
+
/**
|
|
64
|
+
* Verify an email code (after email_code sign in).
|
|
65
|
+
*/
|
|
66
|
+
verifyEmailCode(code: string): Promise<void>;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export { ClerkAuthProvider, type ClerkConfig };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
|
+
ClerkAuthProvider: () => ClerkAuthProvider
|
|
34
|
+
});
|
|
35
|
+
module.exports = __toCommonJS(index_exports);
|
|
36
|
+
|
|
37
|
+
// src/ClerkAuthProvider.ts
|
|
38
|
+
var import_boards = require("@weirdfingers/boards");
|
|
39
|
+
var ClerkAuthProvider = class extends import_boards.BaseAuthProvider {
|
|
40
|
+
// Will be typed properly when @clerk/clerk-js is available
|
|
41
|
+
constructor(config) {
|
|
42
|
+
super(config);
|
|
43
|
+
this.listeners = [];
|
|
44
|
+
this.config = config;
|
|
45
|
+
this.currentState = {
|
|
46
|
+
user: null,
|
|
47
|
+
status: "loading",
|
|
48
|
+
signIn: this.signIn.bind(this),
|
|
49
|
+
signOut: this.signOut.bind(this),
|
|
50
|
+
getToken: this.getToken.bind(this),
|
|
51
|
+
refreshToken: async () => null
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
async initialize() {
|
|
55
|
+
try {
|
|
56
|
+
const Clerk = (await import("@clerk/clerk-js")).default;
|
|
57
|
+
this.clerk = new Clerk(this.config.publishableKey);
|
|
58
|
+
await this.clerk.load({
|
|
59
|
+
...this.config.options
|
|
60
|
+
});
|
|
61
|
+
this.clerk.addListener(this.handleClerkUpdate.bind(this));
|
|
62
|
+
this.handleClerkUpdate();
|
|
63
|
+
} catch (error) {
|
|
64
|
+
console.error("Failed to initialize Clerk:", error);
|
|
65
|
+
this.updateState({ user: null, status: "unauthenticated" });
|
|
66
|
+
throw error;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
async getAuthState() {
|
|
70
|
+
return this.currentState;
|
|
71
|
+
}
|
|
72
|
+
async signIn(options = {}) {
|
|
73
|
+
if (!this.clerk) {
|
|
74
|
+
throw new Error("Clerk not initialized");
|
|
75
|
+
}
|
|
76
|
+
this.updateState({ status: "loading" });
|
|
77
|
+
try {
|
|
78
|
+
if (options.strategy?.startsWith("oauth_")) {
|
|
79
|
+
await this.clerk.authenticateWithRedirect({
|
|
80
|
+
strategy: options.strategy,
|
|
81
|
+
redirectUrl: options.redirectUrl || window.location.href,
|
|
82
|
+
redirectUrlComplete: options.redirectUrl || window.location.origin
|
|
83
|
+
});
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
if (options.strategy === "email_code" && options.identifier) {
|
|
87
|
+
const signIn = await this.clerk.client.signIn.create({
|
|
88
|
+
identifier: options.identifier
|
|
89
|
+
});
|
|
90
|
+
await signIn.prepareFirstFactor({
|
|
91
|
+
strategy: "email_code",
|
|
92
|
+
emailAddressId: signIn.supportedFirstFactors[0].emailAddressId
|
|
93
|
+
});
|
|
94
|
+
this.updateState({ status: "unauthenticated" });
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
if (options.strategy === "password" && options.identifier && options.password) {
|
|
98
|
+
const signIn = await this.clerk.client.signIn.create({
|
|
99
|
+
identifier: options.identifier,
|
|
100
|
+
password: options.password
|
|
101
|
+
});
|
|
102
|
+
if (signIn.status === "complete") {
|
|
103
|
+
await this.clerk.setActive({ session: signIn.createdSessionId });
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
throw new Error("Sign in incomplete");
|
|
107
|
+
}
|
|
108
|
+
await this.clerk.openSignIn({
|
|
109
|
+
redirectUrl: options.redirectUrl || window.location.href
|
|
110
|
+
});
|
|
111
|
+
} catch (error) {
|
|
112
|
+
this.updateState({ user: null, status: "unauthenticated" });
|
|
113
|
+
throw error;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
async signOut() {
|
|
117
|
+
if (!this.clerk) {
|
|
118
|
+
throw new Error("Clerk not initialized");
|
|
119
|
+
}
|
|
120
|
+
await this.clerk.signOut();
|
|
121
|
+
}
|
|
122
|
+
async getToken() {
|
|
123
|
+
if (!this.clerk || !this.clerk.session) return null;
|
|
124
|
+
try {
|
|
125
|
+
return await this.clerk.session.getToken();
|
|
126
|
+
} catch (error) {
|
|
127
|
+
console.error("Failed to get token:", error);
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
async getUser() {
|
|
132
|
+
return this.currentState.user;
|
|
133
|
+
}
|
|
134
|
+
onAuthStateChange(callback) {
|
|
135
|
+
this.listeners.push(callback);
|
|
136
|
+
return () => {
|
|
137
|
+
const index = this.listeners.indexOf(callback);
|
|
138
|
+
if (index > -1) {
|
|
139
|
+
this.listeners.splice(index, 1);
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
async destroy() {
|
|
144
|
+
this.listeners = [];
|
|
145
|
+
if (this.clerk) {
|
|
146
|
+
this.clerk.removeListener(this.handleClerkUpdate.bind(this));
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
handleClerkUpdate() {
|
|
150
|
+
if (!this.clerk) return;
|
|
151
|
+
if (this.clerk.user) {
|
|
152
|
+
const user = {
|
|
153
|
+
id: this.clerk.user.id,
|
|
154
|
+
email: this.clerk.user.primaryEmailAddress?.emailAddress,
|
|
155
|
+
name: this.clerk.user.fullName || this.clerk.user.firstName || this.clerk.user.username || this.clerk.user.primaryEmailAddress?.emailAddress?.split("@")[0],
|
|
156
|
+
avatar: this.clerk.user.imageUrl,
|
|
157
|
+
metadata: { provider: "clerk", subject: this.clerk.user.id },
|
|
158
|
+
credits: { balance: 0, reserved: 0 }
|
|
159
|
+
};
|
|
160
|
+
this.updateState({ user, status: "authenticated" });
|
|
161
|
+
} else {
|
|
162
|
+
this.updateState({ user: null, status: "unauthenticated" });
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
updateState(updates) {
|
|
166
|
+
this.currentState = { ...this.currentState, ...updates };
|
|
167
|
+
this.listeners.forEach((listener) => listener(this.currentState));
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Get the underlying Clerk instance for advanced operations.
|
|
171
|
+
*/
|
|
172
|
+
getClerkInstance() {
|
|
173
|
+
return this.clerk;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Open Clerk user profile modal.
|
|
177
|
+
*/
|
|
178
|
+
async openUserProfile() {
|
|
179
|
+
if (!this.clerk) {
|
|
180
|
+
throw new Error("Clerk not initialized");
|
|
181
|
+
}
|
|
182
|
+
await this.clerk.openUserProfile();
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Open Clerk organization switcher.
|
|
186
|
+
*/
|
|
187
|
+
async openOrganizationSwitcher() {
|
|
188
|
+
if (!this.clerk) {
|
|
189
|
+
throw new Error("Clerk not initialized");
|
|
190
|
+
}
|
|
191
|
+
await this.clerk.openOrganizationSwitcher();
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Verify an email code (after email_code sign in).
|
|
195
|
+
*/
|
|
196
|
+
async verifyEmailCode(code) {
|
|
197
|
+
if (!this.clerk) {
|
|
198
|
+
throw new Error("Clerk not initialized");
|
|
199
|
+
}
|
|
200
|
+
const signIn = this.clerk.client.signIn;
|
|
201
|
+
if (!signIn) {
|
|
202
|
+
throw new Error("No active sign in attempt");
|
|
203
|
+
}
|
|
204
|
+
const result = await signIn.attemptFirstFactor({
|
|
205
|
+
strategy: "email_code",
|
|
206
|
+
code
|
|
207
|
+
});
|
|
208
|
+
if (result.status === "complete") {
|
|
209
|
+
await this.clerk.setActive({ session: result.createdSessionId });
|
|
210
|
+
} else {
|
|
211
|
+
throw new Error("Verification failed");
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
216
|
+
0 && (module.exports = {
|
|
217
|
+
ClerkAuthProvider
|
|
218
|
+
});
|
|
219
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/ClerkAuthProvider.ts"],"sourcesContent":["/**\n * Clerk authentication provider package for Boards.\n */\n\nexport { ClerkAuthProvider } from './ClerkAuthProvider';\nexport type { ClerkConfig } from './types';\n\n// Re-export core types for convenience\nexport type {\n AuthState,\n User,\n AuthProviderConfig,\n AuthContextValue\n} from '@weirdfingers/boards';\n","/**\n * Clerk authentication provider.\n */\n\nimport { BaseAuthProvider, AuthState, User } from \"@weirdfingers/boards\";\nimport type { ClerkConfig } from \"./types\";\n\nexport class ClerkAuthProvider extends BaseAuthProvider {\n protected config: ClerkConfig;\n private listeners: ((state: AuthState) => void)[] = [];\n private currentState: AuthState;\n private clerk: any; // Will be typed properly when @clerk/clerk-js is available\n\n constructor(config: ClerkConfig) {\n super(config);\n this.config = config;\n\n this.currentState = {\n user: null,\n status: \"loading\",\n signIn: this.signIn.bind(this) as any,\n signOut: this.signOut.bind(this),\n getToken: this.getToken.bind(this),\n refreshToken: async () => null,\n };\n }\n\n async initialize(): Promise<void> {\n try {\n // Dynamically import Clerk\n const Clerk = (await import(\"@clerk/clerk-js\")).default;\n\n this.clerk = new Clerk(this.config.publishableKey);\n\n await this.clerk.load({\n ...this.config.options,\n });\n\n // Set up auth state listener\n this.clerk.addListener(this.handleClerkUpdate.bind(this));\n\n // Get initial state\n this.handleClerkUpdate();\n } catch (error) {\n console.error(\"Failed to initialize Clerk:\", error);\n this.updateState({ user: null, status: \"unauthenticated\" });\n throw error;\n }\n }\n\n async getAuthState(): Promise<AuthState> {\n return this.currentState;\n }\n\n async signIn(\n options: {\n strategy?:\n | \"oauth_google\"\n | \"oauth_github\"\n | \"oauth_discord\"\n | \"email_code\"\n | \"password\";\n identifier?: string; // email or username\n password?: string;\n code?: string;\n redirectUrl?: string;\n [key: string]: unknown;\n } = {}\n ): Promise<void> {\n if (!this.clerk) {\n throw new Error(\"Clerk not initialized\");\n }\n\n this.updateState({ status: \"loading\" });\n\n try {\n // OAuth strategies\n if (options.strategy?.startsWith(\"oauth_\")) {\n await this.clerk.authenticateWithRedirect({\n strategy: options.strategy,\n redirectUrl: options.redirectUrl || window.location.href,\n redirectUrlComplete: options.redirectUrl || window.location.origin,\n });\n return; // Redirects, so we don't update state here\n }\n\n // Email code strategy\n if (options.strategy === \"email_code\" && options.identifier) {\n const signIn = await this.clerk.client.signIn.create({\n identifier: options.identifier,\n });\n\n await signIn.prepareFirstFactor({\n strategy: \"email_code\",\n emailAddressId: signIn.supportedFirstFactors[0].emailAddressId,\n });\n\n // Return so user can enter code\n this.updateState({ status: \"unauthenticated\" });\n return;\n }\n\n // Password strategy\n if (\n options.strategy === \"password\" &&\n options.identifier &&\n options.password\n ) {\n const signIn = await this.clerk.client.signIn.create({\n identifier: options.identifier,\n password: options.password,\n });\n\n if (signIn.status === \"complete\") {\n await this.clerk.setActive({ session: signIn.createdSessionId });\n return; // State will update via listener\n }\n\n throw new Error(\"Sign in incomplete\");\n }\n\n // Default: open Clerk sign-in modal\n await this.clerk.openSignIn({\n redirectUrl: options.redirectUrl || window.location.href,\n });\n } catch (error) {\n this.updateState({ user: null, status: \"unauthenticated\" });\n throw error;\n }\n }\n\n async signOut(): Promise<void> {\n if (!this.clerk) {\n throw new Error(\"Clerk not initialized\");\n }\n\n await this.clerk.signOut();\n // State will update via listener\n }\n\n async getToken(): Promise<string | null> {\n if (!this.clerk || !this.clerk.session) return null;\n\n try {\n return await this.clerk.session.getToken();\n } catch (error) {\n console.error(\"Failed to get token:\", error);\n return null;\n }\n }\n\n async getUser(): Promise<User | null> {\n return this.currentState.user;\n }\n\n onAuthStateChange(callback: (state: AuthState) => void): () => void {\n this.listeners.push(callback);\n return () => {\n const index = this.listeners.indexOf(callback);\n if (index > -1) {\n this.listeners.splice(index, 1);\n }\n };\n }\n\n async destroy(): Promise<void> {\n this.listeners = [];\n if (this.clerk) {\n this.clerk.removeListener(this.handleClerkUpdate.bind(this));\n }\n }\n\n private handleClerkUpdate(): void {\n if (!this.clerk) return;\n\n if (this.clerk.user) {\n const user: User = {\n id: this.clerk.user.id,\n email: this.clerk.user.primaryEmailAddress?.emailAddress,\n name:\n this.clerk.user.fullName ||\n this.clerk.user.firstName ||\n this.clerk.user.username ||\n this.clerk.user.primaryEmailAddress?.emailAddress?.split(\"@\")[0],\n avatar: this.clerk.user.imageUrl,\n metadata: { provider: \"clerk\", subject: this.clerk.user.id },\n credits: { balance: 0, reserved: 0 },\n };\n\n this.updateState({ user, status: \"authenticated\" });\n } else {\n this.updateState({ user: null, status: \"unauthenticated\" });\n }\n }\n\n private updateState(updates: Partial<AuthState>): void {\n this.currentState = { ...this.currentState, ...updates };\n this.listeners.forEach((listener) => listener(this.currentState));\n }\n\n /**\n * Get the underlying Clerk instance for advanced operations.\n */\n getClerkInstance() {\n return this.clerk;\n }\n\n /**\n * Open Clerk user profile modal.\n */\n async openUserProfile(): Promise<void> {\n if (!this.clerk) {\n throw new Error(\"Clerk not initialized\");\n }\n\n await this.clerk.openUserProfile();\n }\n\n /**\n * Open Clerk organization switcher.\n */\n async openOrganizationSwitcher(): Promise<void> {\n if (!this.clerk) {\n throw new Error(\"Clerk not initialized\");\n }\n\n await this.clerk.openOrganizationSwitcher();\n }\n\n /**\n * Verify an email code (after email_code sign in).\n */\n async verifyEmailCode(code: string): Promise<void> {\n if (!this.clerk) {\n throw new Error(\"Clerk not initialized\");\n }\n\n const signIn = this.clerk.client.signIn;\n if (!signIn) {\n throw new Error(\"No active sign in attempt\");\n }\n\n const result = await signIn.attemptFirstFactor({\n strategy: \"email_code\",\n code,\n });\n\n if (result.status === \"complete\") {\n await this.clerk.setActive({ session: result.createdSessionId });\n } else {\n throw new Error(\"Verification failed\");\n }\n }\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
// src/ClerkAuthProvider.ts
|
|
2
|
+
import { BaseAuthProvider } from "@weirdfingers/boards";
|
|
3
|
+
var ClerkAuthProvider = class extends BaseAuthProvider {
|
|
4
|
+
// Will be typed properly when @clerk/clerk-js is available
|
|
5
|
+
constructor(config) {
|
|
6
|
+
super(config);
|
|
7
|
+
this.listeners = [];
|
|
8
|
+
this.config = config;
|
|
9
|
+
this.currentState = {
|
|
10
|
+
user: null,
|
|
11
|
+
status: "loading",
|
|
12
|
+
signIn: this.signIn.bind(this),
|
|
13
|
+
signOut: this.signOut.bind(this),
|
|
14
|
+
getToken: this.getToken.bind(this),
|
|
15
|
+
refreshToken: async () => null
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
async initialize() {
|
|
19
|
+
try {
|
|
20
|
+
const Clerk = (await import("@clerk/clerk-js")).default;
|
|
21
|
+
this.clerk = new Clerk(this.config.publishableKey);
|
|
22
|
+
await this.clerk.load({
|
|
23
|
+
...this.config.options
|
|
24
|
+
});
|
|
25
|
+
this.clerk.addListener(this.handleClerkUpdate.bind(this));
|
|
26
|
+
this.handleClerkUpdate();
|
|
27
|
+
} catch (error) {
|
|
28
|
+
console.error("Failed to initialize Clerk:", error);
|
|
29
|
+
this.updateState({ user: null, status: "unauthenticated" });
|
|
30
|
+
throw error;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
async getAuthState() {
|
|
34
|
+
return this.currentState;
|
|
35
|
+
}
|
|
36
|
+
async signIn(options = {}) {
|
|
37
|
+
if (!this.clerk) {
|
|
38
|
+
throw new Error("Clerk not initialized");
|
|
39
|
+
}
|
|
40
|
+
this.updateState({ status: "loading" });
|
|
41
|
+
try {
|
|
42
|
+
if (options.strategy?.startsWith("oauth_")) {
|
|
43
|
+
await this.clerk.authenticateWithRedirect({
|
|
44
|
+
strategy: options.strategy,
|
|
45
|
+
redirectUrl: options.redirectUrl || window.location.href,
|
|
46
|
+
redirectUrlComplete: options.redirectUrl || window.location.origin
|
|
47
|
+
});
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
if (options.strategy === "email_code" && options.identifier) {
|
|
51
|
+
const signIn = await this.clerk.client.signIn.create({
|
|
52
|
+
identifier: options.identifier
|
|
53
|
+
});
|
|
54
|
+
await signIn.prepareFirstFactor({
|
|
55
|
+
strategy: "email_code",
|
|
56
|
+
emailAddressId: signIn.supportedFirstFactors[0].emailAddressId
|
|
57
|
+
});
|
|
58
|
+
this.updateState({ status: "unauthenticated" });
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
if (options.strategy === "password" && options.identifier && options.password) {
|
|
62
|
+
const signIn = await this.clerk.client.signIn.create({
|
|
63
|
+
identifier: options.identifier,
|
|
64
|
+
password: options.password
|
|
65
|
+
});
|
|
66
|
+
if (signIn.status === "complete") {
|
|
67
|
+
await this.clerk.setActive({ session: signIn.createdSessionId });
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
throw new Error("Sign in incomplete");
|
|
71
|
+
}
|
|
72
|
+
await this.clerk.openSignIn({
|
|
73
|
+
redirectUrl: options.redirectUrl || window.location.href
|
|
74
|
+
});
|
|
75
|
+
} catch (error) {
|
|
76
|
+
this.updateState({ user: null, status: "unauthenticated" });
|
|
77
|
+
throw error;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
async signOut() {
|
|
81
|
+
if (!this.clerk) {
|
|
82
|
+
throw new Error("Clerk not initialized");
|
|
83
|
+
}
|
|
84
|
+
await this.clerk.signOut();
|
|
85
|
+
}
|
|
86
|
+
async getToken() {
|
|
87
|
+
if (!this.clerk || !this.clerk.session) return null;
|
|
88
|
+
try {
|
|
89
|
+
return await this.clerk.session.getToken();
|
|
90
|
+
} catch (error) {
|
|
91
|
+
console.error("Failed to get token:", error);
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
async getUser() {
|
|
96
|
+
return this.currentState.user;
|
|
97
|
+
}
|
|
98
|
+
onAuthStateChange(callback) {
|
|
99
|
+
this.listeners.push(callback);
|
|
100
|
+
return () => {
|
|
101
|
+
const index = this.listeners.indexOf(callback);
|
|
102
|
+
if (index > -1) {
|
|
103
|
+
this.listeners.splice(index, 1);
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
async destroy() {
|
|
108
|
+
this.listeners = [];
|
|
109
|
+
if (this.clerk) {
|
|
110
|
+
this.clerk.removeListener(this.handleClerkUpdate.bind(this));
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
handleClerkUpdate() {
|
|
114
|
+
if (!this.clerk) return;
|
|
115
|
+
if (this.clerk.user) {
|
|
116
|
+
const user = {
|
|
117
|
+
id: this.clerk.user.id,
|
|
118
|
+
email: this.clerk.user.primaryEmailAddress?.emailAddress,
|
|
119
|
+
name: this.clerk.user.fullName || this.clerk.user.firstName || this.clerk.user.username || this.clerk.user.primaryEmailAddress?.emailAddress?.split("@")[0],
|
|
120
|
+
avatar: this.clerk.user.imageUrl,
|
|
121
|
+
metadata: { provider: "clerk", subject: this.clerk.user.id },
|
|
122
|
+
credits: { balance: 0, reserved: 0 }
|
|
123
|
+
};
|
|
124
|
+
this.updateState({ user, status: "authenticated" });
|
|
125
|
+
} else {
|
|
126
|
+
this.updateState({ user: null, status: "unauthenticated" });
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
updateState(updates) {
|
|
130
|
+
this.currentState = { ...this.currentState, ...updates };
|
|
131
|
+
this.listeners.forEach((listener) => listener(this.currentState));
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Get the underlying Clerk instance for advanced operations.
|
|
135
|
+
*/
|
|
136
|
+
getClerkInstance() {
|
|
137
|
+
return this.clerk;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Open Clerk user profile modal.
|
|
141
|
+
*/
|
|
142
|
+
async openUserProfile() {
|
|
143
|
+
if (!this.clerk) {
|
|
144
|
+
throw new Error("Clerk not initialized");
|
|
145
|
+
}
|
|
146
|
+
await this.clerk.openUserProfile();
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Open Clerk organization switcher.
|
|
150
|
+
*/
|
|
151
|
+
async openOrganizationSwitcher() {
|
|
152
|
+
if (!this.clerk) {
|
|
153
|
+
throw new Error("Clerk not initialized");
|
|
154
|
+
}
|
|
155
|
+
await this.clerk.openOrganizationSwitcher();
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Verify an email code (after email_code sign in).
|
|
159
|
+
*/
|
|
160
|
+
async verifyEmailCode(code) {
|
|
161
|
+
if (!this.clerk) {
|
|
162
|
+
throw new Error("Clerk not initialized");
|
|
163
|
+
}
|
|
164
|
+
const signIn = this.clerk.client.signIn;
|
|
165
|
+
if (!signIn) {
|
|
166
|
+
throw new Error("No active sign in attempt");
|
|
167
|
+
}
|
|
168
|
+
const result = await signIn.attemptFirstFactor({
|
|
169
|
+
strategy: "email_code",
|
|
170
|
+
code
|
|
171
|
+
});
|
|
172
|
+
if (result.status === "complete") {
|
|
173
|
+
await this.clerk.setActive({ session: result.createdSessionId });
|
|
174
|
+
} else {
|
|
175
|
+
throw new Error("Verification failed");
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
export {
|
|
180
|
+
ClerkAuthProvider
|
|
181
|
+
};
|
|
182
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/ClerkAuthProvider.ts"],"sourcesContent":["/**\n * Clerk authentication provider.\n */\n\nimport { BaseAuthProvider, AuthState, User } from \"@weirdfingers/boards\";\nimport type { ClerkConfig } from \"./types\";\n\nexport class ClerkAuthProvider extends BaseAuthProvider {\n protected config: ClerkConfig;\n private listeners: ((state: AuthState) => void)[] = [];\n private currentState: AuthState;\n private clerk: any; // Will be typed properly when @clerk/clerk-js is available\n\n constructor(config: ClerkConfig) {\n super(config);\n this.config = config;\n\n this.currentState = {\n user: null,\n status: \"loading\",\n signIn: this.signIn.bind(this) as any,\n signOut: this.signOut.bind(this),\n getToken: this.getToken.bind(this),\n refreshToken: async () => null,\n };\n }\n\n async initialize(): Promise<void> {\n try {\n // Dynamically import Clerk\n const Clerk = (await import(\"@clerk/clerk-js\")).default;\n\n this.clerk = new Clerk(this.config.publishableKey);\n\n await this.clerk.load({\n ...this.config.options,\n });\n\n // Set up auth state listener\n this.clerk.addListener(this.handleClerkUpdate.bind(this));\n\n // Get initial state\n this.handleClerkUpdate();\n } catch (error) {\n console.error(\"Failed to initialize Clerk:\", error);\n this.updateState({ user: null, status: \"unauthenticated\" });\n throw error;\n }\n }\n\n async getAuthState(): Promise<AuthState> {\n return this.currentState;\n }\n\n async signIn(\n options: {\n strategy?:\n | \"oauth_google\"\n | \"oauth_github\"\n | \"oauth_discord\"\n | \"email_code\"\n | \"password\";\n identifier?: string; // email or username\n password?: string;\n code?: string;\n redirectUrl?: string;\n [key: string]: unknown;\n } = {}\n ): Promise<void> {\n if (!this.clerk) {\n throw new Error(\"Clerk not initialized\");\n }\n\n this.updateState({ status: \"loading\" });\n\n try {\n // OAuth strategies\n if (options.strategy?.startsWith(\"oauth_\")) {\n await this.clerk.authenticateWithRedirect({\n strategy: options.strategy,\n redirectUrl: options.redirectUrl || window.location.href,\n redirectUrlComplete: options.redirectUrl || window.location.origin,\n });\n return; // Redirects, so we don't update state here\n }\n\n // Email code strategy\n if (options.strategy === \"email_code\" && options.identifier) {\n const signIn = await this.clerk.client.signIn.create({\n identifier: options.identifier,\n });\n\n await signIn.prepareFirstFactor({\n strategy: \"email_code\",\n emailAddressId: signIn.supportedFirstFactors[0].emailAddressId,\n });\n\n // Return so user can enter code\n this.updateState({ status: \"unauthenticated\" });\n return;\n }\n\n // Password strategy\n if (\n options.strategy === \"password\" &&\n options.identifier &&\n options.password\n ) {\n const signIn = await this.clerk.client.signIn.create({\n identifier: options.identifier,\n password: options.password,\n });\n\n if (signIn.status === \"complete\") {\n await this.clerk.setActive({ session: signIn.createdSessionId });\n return; // State will update via listener\n }\n\n throw new Error(\"Sign in incomplete\");\n }\n\n // Default: open Clerk sign-in modal\n await this.clerk.openSignIn({\n redirectUrl: options.redirectUrl || window.location.href,\n });\n } catch (error) {\n this.updateState({ user: null, status: \"unauthenticated\" });\n throw error;\n }\n }\n\n async signOut(): Promise<void> {\n if (!this.clerk) {\n throw new Error(\"Clerk not initialized\");\n }\n\n await this.clerk.signOut();\n // State will update via listener\n }\n\n async getToken(): Promise<string | null> {\n if (!this.clerk || !this.clerk.session) return null;\n\n try {\n return await this.clerk.session.getToken();\n } catch (error) {\n console.error(\"Failed to get token:\", error);\n return null;\n }\n }\n\n async getUser(): Promise<User | null> {\n return this.currentState.user;\n }\n\n onAuthStateChange(callback: (state: AuthState) => void): () => void {\n this.listeners.push(callback);\n return () => {\n const index = this.listeners.indexOf(callback);\n if (index > -1) {\n this.listeners.splice(index, 1);\n }\n };\n }\n\n async destroy(): Promise<void> {\n this.listeners = [];\n if (this.clerk) {\n this.clerk.removeListener(this.handleClerkUpdate.bind(this));\n }\n }\n\n private handleClerkUpdate(): void {\n if (!this.clerk) return;\n\n if (this.clerk.user) {\n const user: User = {\n id: this.clerk.user.id,\n email: this.clerk.user.primaryEmailAddress?.emailAddress,\n name:\n this.clerk.user.fullName ||\n this.clerk.user.firstName ||\n this.clerk.user.username ||\n this.clerk.user.primaryEmailAddress?.emailAddress?.split(\"@\")[0],\n avatar: this.clerk.user.imageUrl,\n metadata: { provider: \"clerk\", subject: this.clerk.user.id },\n credits: { balance: 0, reserved: 0 },\n };\n\n this.updateState({ user, status: \"authenticated\" });\n } else {\n this.updateState({ user: null, status: \"unauthenticated\" });\n }\n }\n\n private updateState(updates: Partial<AuthState>): void {\n this.currentState = { ...this.currentState, ...updates };\n this.listeners.forEach((listener) => listener(this.currentState));\n }\n\n /**\n * Get the underlying Clerk instance for advanced operations.\n */\n getClerkInstance() {\n return this.clerk;\n }\n\n /**\n * Open Clerk user profile modal.\n */\n async openUserProfile(): Promise<void> {\n if (!this.clerk) {\n throw new Error(\"Clerk not initialized\");\n }\n\n await this.clerk.openUserProfile();\n }\n\n /**\n * Open Clerk organization switcher.\n */\n async openOrganizationSwitcher(): Promise<void> {\n if (!this.clerk) {\n throw new Error(\"Clerk not initialized\");\n }\n\n await this.clerk.openOrganizationSwitcher();\n }\n\n /**\n * Verify an email code (after email_code sign in).\n */\n async verifyEmailCode(code: string): Promise<void> {\n if (!this.clerk) {\n throw new Error(\"Clerk not initialized\");\n }\n\n const signIn = this.clerk.client.signIn;\n if (!signIn) {\n throw new Error(\"No active sign in attempt\");\n }\n\n const result = await signIn.attemptFirstFactor({\n strategy: \"email_code\",\n code,\n });\n\n if (result.status === \"complete\") {\n await this.clerk.setActive({ session: result.createdSessionId });\n } else {\n throw new Error(\"Verification failed\");\n }\n }\n}\n"],"mappings":"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","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@weirdfingers/boards-auth-clerk",
|
|
3
|
+
"version": "0.9.13",
|
|
4
|
+
"description": "Clerk authentication provider for Boards",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.mjs",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"scripts": {
|
|
9
|
+
"build": "tsup",
|
|
10
|
+
"dev": "tsup --watch",
|
|
11
|
+
"typecheck": "tsc --noEmit -p tsconfig.typecheck.json",
|
|
12
|
+
"lint": "eslint src --ext .ts,.tsx",
|
|
13
|
+
"test": "vitest --run --passWithNoTests"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"boards",
|
|
17
|
+
"authentication",
|
|
18
|
+
"clerk",
|
|
19
|
+
"auth",
|
|
20
|
+
"react"
|
|
21
|
+
],
|
|
22
|
+
"author": "WeirdFingers",
|
|
23
|
+
"license": "MIT",
|
|
24
|
+
"peerDependencies": {
|
|
25
|
+
"@clerk/clerk-js": "^4.0.0",
|
|
26
|
+
"@weirdfingers/boards": "workspace:*",
|
|
27
|
+
"react": "^18.0.0"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@types/react": "^18.0.0",
|
|
31
|
+
"@typescript-eslint/eslint-plugin": "^8.42.0",
|
|
32
|
+
"@typescript-eslint/parser": "^8.42.0",
|
|
33
|
+
"@weirdfingers/boards": "workspace:*",
|
|
34
|
+
"eslint": "^8.0.0",
|
|
35
|
+
"tsup": "^8.0.0",
|
|
36
|
+
"typescript": "^5.0.0",
|
|
37
|
+
"vitest": "^1.0.0"
|
|
38
|
+
},
|
|
39
|
+
"files": [
|
|
40
|
+
"dist",
|
|
41
|
+
"README.md"
|
|
42
|
+
],
|
|
43
|
+
"repository": {
|
|
44
|
+
"type": "git",
|
|
45
|
+
"url": "https://github.com/weirdfingers/boards.git",
|
|
46
|
+
"directory": "packages/auth-clerk"
|
|
47
|
+
}
|
|
48
|
+
}
|