@smarthivelabs-devs/auth-sdk 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +237 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +55 -0
- package/dist/index.d.ts +55 -0
- package/dist/index.js +208 -0
- package/dist/index.js.map +1 -0
- package/package.json +38 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
SmartHiveAuthError: () => SmartHiveAuthError,
|
|
24
|
+
generateCodeChallenge: () => generateCodeChallenge,
|
|
25
|
+
generateCodeVerifier: () => generateCodeVerifier,
|
|
26
|
+
initAuth: () => initAuth,
|
|
27
|
+
smartHiveAuthStorageKeys: () => smartHiveAuthStorageKeys
|
|
28
|
+
});
|
|
29
|
+
module.exports = __toCommonJS(index_exports);
|
|
30
|
+
var SmartHiveAuthError = class extends Error {
|
|
31
|
+
constructor(code, message) {
|
|
32
|
+
super(message);
|
|
33
|
+
this.code = code;
|
|
34
|
+
this.name = "SmartHiveAuthError";
|
|
35
|
+
}
|
|
36
|
+
code;
|
|
37
|
+
};
|
|
38
|
+
async function generateCodeVerifier() {
|
|
39
|
+
const array = new Uint8Array(32);
|
|
40
|
+
crypto.getRandomValues(array);
|
|
41
|
+
return base64urlEncode(array);
|
|
42
|
+
}
|
|
43
|
+
async function generateCodeChallenge(verifier) {
|
|
44
|
+
const encoder = new TextEncoder();
|
|
45
|
+
const data = encoder.encode(verifier);
|
|
46
|
+
const digest = await crypto.subtle.digest("SHA-256", data);
|
|
47
|
+
return base64urlEncode(new Uint8Array(digest));
|
|
48
|
+
}
|
|
49
|
+
function base64urlEncode(buffer) {
|
|
50
|
+
let str = "";
|
|
51
|
+
for (const byte of buffer) str += String.fromCharCode(byte);
|
|
52
|
+
return btoa(str).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
53
|
+
}
|
|
54
|
+
var smartHiveAuthStorageKeys = {
|
|
55
|
+
session: "smarthive.auth.session",
|
|
56
|
+
pkceVerifier: "smarthive.auth.pkce_verifier",
|
|
57
|
+
pkceState: "smarthive.auth.pkce_state"
|
|
58
|
+
};
|
|
59
|
+
function browserStorage() {
|
|
60
|
+
return {
|
|
61
|
+
getItem: (key) => globalThis.localStorage?.getItem(key) ?? null,
|
|
62
|
+
setItem: (key, value) => globalThis.localStorage?.setItem(key, value),
|
|
63
|
+
removeItem: (key) => globalThis.localStorage?.removeItem(key)
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
function sessionStorageAdapter() {
|
|
67
|
+
return {
|
|
68
|
+
getItem: (key) => globalThis.sessionStorage?.getItem(key) ?? null,
|
|
69
|
+
setItem: (key, value) => globalThis.sessionStorage?.setItem(key, value),
|
|
70
|
+
removeItem: (key) => globalThis.sessionStorage?.removeItem(key)
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
function normalizeBaseUrl(baseUrl) {
|
|
74
|
+
return baseUrl.replace(/\/$/, "");
|
|
75
|
+
}
|
|
76
|
+
function initAuth(config) {
|
|
77
|
+
const baseUrl = normalizeBaseUrl(config.baseUrl);
|
|
78
|
+
const authBase = normalizeBaseUrl(config.authDomain ?? config.baseUrl);
|
|
79
|
+
const storage = config.storage ?? browserStorage();
|
|
80
|
+
const tempStorage = config.temporaryStorage ?? sessionStorageAdapter();
|
|
81
|
+
async function saveSession(session) {
|
|
82
|
+
if (!session) {
|
|
83
|
+
await storage.removeItem(smartHiveAuthStorageKeys.session);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
await storage.setItem(smartHiveAuthStorageKeys.session, JSON.stringify(session));
|
|
87
|
+
}
|
|
88
|
+
async function readSession() {
|
|
89
|
+
const raw = await storage.getItem(smartHiveAuthStorageKeys.session);
|
|
90
|
+
return raw ? JSON.parse(raw) : null;
|
|
91
|
+
}
|
|
92
|
+
const client = {
|
|
93
|
+
async initialize() {
|
|
94
|
+
const response = await fetch(
|
|
95
|
+
`${baseUrl}/sdk/config?projectId=${encodeURIComponent(config.projectId)}&publishableKey=${encodeURIComponent(config.publishableKey)}`
|
|
96
|
+
);
|
|
97
|
+
if (!response.ok) throw new SmartHiveAuthError("project_not_found", "Smart Hive Auth project configuration was not found.");
|
|
98
|
+
},
|
|
99
|
+
async login(options) {
|
|
100
|
+
const redirectUri = options?.redirectUri ?? config.redirectUri ?? globalThis.location?.href;
|
|
101
|
+
const state = options?.state ?? crypto.randomUUID();
|
|
102
|
+
const verifier = await generateCodeVerifier();
|
|
103
|
+
const challenge = await generateCodeChallenge(verifier);
|
|
104
|
+
await tempStorage.setItem(smartHiveAuthStorageKeys.pkceVerifier, verifier);
|
|
105
|
+
await tempStorage.setItem(smartHiveAuthStorageKeys.pkceState, state);
|
|
106
|
+
const url = new URL(`${authBase}/api/auth/oauth2/authorize`);
|
|
107
|
+
url.searchParams.set("project_id", config.projectId);
|
|
108
|
+
url.searchParams.set("publishable_key", config.publishableKey);
|
|
109
|
+
url.searchParams.set("response_type", "code");
|
|
110
|
+
url.searchParams.set("redirect_uri", redirectUri);
|
|
111
|
+
url.searchParams.set("state", state);
|
|
112
|
+
url.searchParams.set("code_challenge", challenge);
|
|
113
|
+
url.searchParams.set("code_challenge_method", "S256");
|
|
114
|
+
globalThis.location.assign(url.toString());
|
|
115
|
+
},
|
|
116
|
+
async handleCallback(options) {
|
|
117
|
+
const href = options?.url ?? globalThis.location?.href;
|
|
118
|
+
if (!href) throw new SmartHiveAuthError("callback_failed", "No URL provided for callback handling.");
|
|
119
|
+
const url = new URL(href);
|
|
120
|
+
const code = url.searchParams.get("code");
|
|
121
|
+
const returnedState = url.searchParams.get("state");
|
|
122
|
+
if (!code) throw new SmartHiveAuthError("callback_failed", "No authorization code in callback URL.");
|
|
123
|
+
const storedState = await tempStorage.getItem(smartHiveAuthStorageKeys.pkceState);
|
|
124
|
+
if (!storedState || !returnedState || storedState !== returnedState) {
|
|
125
|
+
throw new SmartHiveAuthError("state_mismatch", "OAuth state mismatch \u2014 possible CSRF attack.");
|
|
126
|
+
}
|
|
127
|
+
const verifier = await tempStorage.getItem(smartHiveAuthStorageKeys.pkceVerifier);
|
|
128
|
+
if (!verifier) {
|
|
129
|
+
throw new SmartHiveAuthError("pkce_missing", "Missing PKCE verifier for authorization code exchange.");
|
|
130
|
+
}
|
|
131
|
+
const redirectUri = config.redirectUri ?? url.origin + url.pathname;
|
|
132
|
+
const body = new URLSearchParams({
|
|
133
|
+
grant_type: "authorization_code",
|
|
134
|
+
code,
|
|
135
|
+
redirect_uri: redirectUri,
|
|
136
|
+
client_id: config.publishableKey
|
|
137
|
+
});
|
|
138
|
+
body.set("code_verifier", verifier);
|
|
139
|
+
const response = await fetch(`${authBase}/api/auth/oauth2/token`, {
|
|
140
|
+
method: "POST",
|
|
141
|
+
headers: { "content-type": "application/x-www-form-urlencoded" },
|
|
142
|
+
body
|
|
143
|
+
});
|
|
144
|
+
if (!response.ok) {
|
|
145
|
+
const err = await response.json().catch(() => ({}));
|
|
146
|
+
throw new SmartHiveAuthError(err.error ?? "token_error", err.error_description ?? "Token exchange failed.");
|
|
147
|
+
}
|
|
148
|
+
const tokenBody = await response.json();
|
|
149
|
+
const session = {
|
|
150
|
+
accessToken: tokenBody.access_token,
|
|
151
|
+
refreshToken: tokenBody.refresh_token,
|
|
152
|
+
expiresAt: tokenBody.expires_in ? Date.now() + tokenBody.expires_in * 1e3 : void 0
|
|
153
|
+
};
|
|
154
|
+
await saveSession(session);
|
|
155
|
+
await tempStorage.removeItem(smartHiveAuthStorageKeys.pkceVerifier);
|
|
156
|
+
await tempStorage.removeItem(smartHiveAuthStorageKeys.pkceState);
|
|
157
|
+
return session;
|
|
158
|
+
},
|
|
159
|
+
async logout() {
|
|
160
|
+
await saveSession(null);
|
|
161
|
+
await fetch(`${baseUrl}/api/auth/sign-out`, { method: "POST", credentials: "include" });
|
|
162
|
+
},
|
|
163
|
+
getSession: readSession,
|
|
164
|
+
async getAccessToken() {
|
|
165
|
+
const session = await readSession();
|
|
166
|
+
if (!session) return null;
|
|
167
|
+
if (session.expiresAt && Date.now() > session.expiresAt - 3e4) {
|
|
168
|
+
return (await client.refreshSession())?.accessToken ?? null;
|
|
169
|
+
}
|
|
170
|
+
return session.accessToken;
|
|
171
|
+
},
|
|
172
|
+
async getAuthorizationHeader() {
|
|
173
|
+
const token = await client.getAccessToken();
|
|
174
|
+
const headers = {};
|
|
175
|
+
if (token) headers.authorization = `Bearer ${token}`;
|
|
176
|
+
return headers;
|
|
177
|
+
},
|
|
178
|
+
async fetch(input, init = {}) {
|
|
179
|
+
const authHeader = await client.getAuthorizationHeader();
|
|
180
|
+
const headers = new Headers(init.headers);
|
|
181
|
+
for (const [key, value] of Object.entries(authHeader)) {
|
|
182
|
+
headers.set(key, value);
|
|
183
|
+
}
|
|
184
|
+
return fetch(input, { ...init, headers });
|
|
185
|
+
},
|
|
186
|
+
async refreshSession() {
|
|
187
|
+
const session = await readSession();
|
|
188
|
+
if (!session?.refreshToken) return session;
|
|
189
|
+
const response = await fetch(`${baseUrl}/api/auth/oauth2/token`, {
|
|
190
|
+
method: "POST",
|
|
191
|
+
headers: { "content-type": "application/x-www-form-urlencoded" },
|
|
192
|
+
body: new URLSearchParams({
|
|
193
|
+
grant_type: "refresh_token",
|
|
194
|
+
refresh_token: session.refreshToken
|
|
195
|
+
})
|
|
196
|
+
});
|
|
197
|
+
if (!response.ok) {
|
|
198
|
+
await saveSession(null);
|
|
199
|
+
return null;
|
|
200
|
+
}
|
|
201
|
+
const body = await response.json();
|
|
202
|
+
const nextSession = {
|
|
203
|
+
...session,
|
|
204
|
+
accessToken: body.access_token,
|
|
205
|
+
refreshToken: body.refresh_token ?? session.refreshToken,
|
|
206
|
+
expiresAt: body.expires_in ? Date.now() + body.expires_in * 1e3 : session.expiresAt
|
|
207
|
+
};
|
|
208
|
+
await saveSession(nextSession);
|
|
209
|
+
return nextSession;
|
|
210
|
+
},
|
|
211
|
+
async verifyToken(token) {
|
|
212
|
+
if (token.split(".").length !== 3) return false;
|
|
213
|
+
const response = await fetch(`${authBase}/api/auth/oauth2/userinfo`, {
|
|
214
|
+
headers: { authorization: `Bearer ${token}` }
|
|
215
|
+
});
|
|
216
|
+
return response.ok;
|
|
217
|
+
},
|
|
218
|
+
async getUser() {
|
|
219
|
+
const token = await client.getAccessToken();
|
|
220
|
+
if (!token) return null;
|
|
221
|
+
const response = await fetch(`${baseUrl}/api/auth/oauth2/userinfo`, {
|
|
222
|
+
headers: { authorization: `Bearer ${token}` }
|
|
223
|
+
});
|
|
224
|
+
return response.ok ? response.json() : null;
|
|
225
|
+
}
|
|
226
|
+
};
|
|
227
|
+
return client;
|
|
228
|
+
}
|
|
229
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
230
|
+
0 && (module.exports = {
|
|
231
|
+
SmartHiveAuthError,
|
|
232
|
+
generateCodeChallenge,
|
|
233
|
+
generateCodeVerifier,
|
|
234
|
+
initAuth,
|
|
235
|
+
smartHiveAuthStorageKeys
|
|
236
|
+
});
|
|
237
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export interface SmartHiveAuthConfig {\n projectId: string;\n publishableKey: string;\n baseUrl: string;\n /** Custom branded auth domain, e.g. \"https://auth.myapp.com\". Used as the entry point for login/token flows. Falls back to baseUrl. */\n authDomain?: string;\n /** Fallback auth domain if authDomain is unreachable, e.g. \"https://auth.smarthivelabs.dev\". */\n fallbackAuthDomain?: string;\n redirectUri?: string;\n storage?: AuthStorage;\n temporaryStorage?: AuthStorage;\n}\n\nexport interface AuthStorage {\n getItem(key: string): string | null | Promise<string | null>;\n setItem(key: string, value: string): void | Promise<void>;\n removeItem(key: string): void | Promise<void>;\n}\n\nexport interface AuthSession {\n accessToken: string;\n refreshToken?: string;\n expiresAt?: number;\n user?: unknown;\n}\n\nexport interface SmartHiveAuthClient {\n initialize(): Promise<void>;\n login(options?: { redirectUri?: string; state?: string }): Promise<void>;\n handleCallback(options?: { url?: string }): Promise<AuthSession>;\n logout(): Promise<void>;\n getSession(): Promise<AuthSession | null>;\n getAccessToken(): Promise<string | null>;\n getAuthorizationHeader(): Promise<Record<string, string>>;\n fetch(input: string | URL | Request, init?: RequestInit): Promise<Response>;\n refreshSession(): Promise<AuthSession | null>;\n verifyToken(token: string): Promise<boolean>;\n getUser(): Promise<unknown>;\n}\n\nexport class SmartHiveAuthError extends Error {\n constructor(public code: string, message: string) {\n super(message);\n this.name = \"SmartHiveAuthError\";\n }\n}\n\n// ── PKCE helpers (Web Crypto — works in browser + Node 18+) ──────────────────\n\nexport async function generateCodeVerifier(): Promise<string> {\n const array = new Uint8Array(32);\n crypto.getRandomValues(array);\n return base64urlEncode(array);\n}\n\nexport async function generateCodeChallenge(verifier: string): Promise<string> {\n const encoder = new TextEncoder();\n const data = encoder.encode(verifier);\n const digest = await crypto.subtle.digest(\"SHA-256\", data);\n return base64urlEncode(new Uint8Array(digest));\n}\n\nfunction base64urlEncode(buffer: Uint8Array): string {\n let str = \"\";\n for (const byte of buffer) str += String.fromCharCode(byte);\n return btoa(str).replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=+$/, \"\");\n}\n\n// ── Storage keys ─────────────────────────────────────────────────────────────\n\nexport const smartHiveAuthStorageKeys = {\n session: \"smarthive.auth.session\",\n pkceVerifier: \"smarthive.auth.pkce_verifier\",\n pkceState: \"smarthive.auth.pkce_state\"\n} as const;\n\nfunction browserStorage(): AuthStorage {\n return {\n getItem: (key) => globalThis.localStorage?.getItem(key) ?? null,\n setItem: (key, value) => globalThis.localStorage?.setItem(key, value),\n removeItem: (key) => globalThis.localStorage?.removeItem(key)\n };\n}\n\nfunction sessionStorageAdapter(): Pick<AuthStorage, \"getItem\" | \"setItem\" | \"removeItem\"> {\n return {\n getItem: (key) => globalThis.sessionStorage?.getItem(key) ?? null,\n setItem: (key, value) => globalThis.sessionStorage?.setItem(key, value),\n removeItem: (key) => globalThis.sessionStorage?.removeItem(key)\n };\n}\n\nfunction normalizeBaseUrl(baseUrl: string) {\n return baseUrl.replace(/\\/$/, \"\");\n}\n\n// ── Factory ───────────────────────────────────────────────────────────────────\n\nexport function initAuth(config: SmartHiveAuthConfig): SmartHiveAuthClient {\n const baseUrl = normalizeBaseUrl(config.baseUrl);\n const authBase = normalizeBaseUrl(config.authDomain ?? config.baseUrl);\n const storage = config.storage ?? browserStorage();\n const tempStorage = config.temporaryStorage ?? sessionStorageAdapter();\n\n async function saveSession(session: AuthSession | null) {\n if (!session) { await storage.removeItem(smartHiveAuthStorageKeys.session); return; }\n await storage.setItem(smartHiveAuthStorageKeys.session, JSON.stringify(session));\n }\n\n async function readSession(): Promise<AuthSession | null> {\n const raw = await storage.getItem(smartHiveAuthStorageKeys.session);\n return raw ? JSON.parse(raw) as AuthSession : null;\n }\n\n const client: SmartHiveAuthClient = {\n async initialize() {\n const response = await fetch(\n `${baseUrl}/sdk/config?projectId=${encodeURIComponent(config.projectId)}&publishableKey=${encodeURIComponent(config.publishableKey)}`\n );\n if (!response.ok) throw new SmartHiveAuthError(\"project_not_found\", \"Smart Hive Auth project configuration was not found.\");\n },\n\n async login(options) {\n const redirectUri = options?.redirectUri ?? config.redirectUri ?? globalThis.location?.href;\n const state = options?.state ?? crypto.randomUUID();\n const verifier = await generateCodeVerifier();\n const challenge = await generateCodeChallenge(verifier);\n\n await tempStorage.setItem(smartHiveAuthStorageKeys.pkceVerifier, verifier);\n await tempStorage.setItem(smartHiveAuthStorageKeys.pkceState, state);\n\n const url = new URL(`${authBase}/api/auth/oauth2/authorize`);\n url.searchParams.set(\"project_id\", config.projectId);\n url.searchParams.set(\"publishable_key\", config.publishableKey);\n url.searchParams.set(\"response_type\", \"code\");\n url.searchParams.set(\"redirect_uri\", redirectUri);\n url.searchParams.set(\"state\", state);\n url.searchParams.set(\"code_challenge\", challenge);\n url.searchParams.set(\"code_challenge_method\", \"S256\");\n\n globalThis.location.assign(url.toString());\n },\n\n async handleCallback(options) {\n const href = options?.url ?? globalThis.location?.href;\n if (!href) throw new SmartHiveAuthError(\"callback_failed\", \"No URL provided for callback handling.\");\n\n const url = new URL(href);\n const code = url.searchParams.get(\"code\");\n const returnedState = url.searchParams.get(\"state\");\n\n if (!code) throw new SmartHiveAuthError(\"callback_failed\", \"No authorization code in callback URL.\");\n\n const storedState = await tempStorage.getItem(smartHiveAuthStorageKeys.pkceState);\n if (!storedState || !returnedState || storedState !== returnedState) {\n throw new SmartHiveAuthError(\"state_mismatch\", \"OAuth state mismatch — possible CSRF attack.\");\n }\n\n const verifier = await tempStorage.getItem(smartHiveAuthStorageKeys.pkceVerifier);\n if (!verifier) {\n throw new SmartHiveAuthError(\"pkce_missing\", \"Missing PKCE verifier for authorization code exchange.\");\n }\n const redirectUri = config.redirectUri ?? (url.origin + url.pathname);\n\n const body = new URLSearchParams({\n grant_type: \"authorization_code\",\n code,\n redirect_uri: redirectUri,\n client_id: config.publishableKey\n });\n body.set(\"code_verifier\", verifier);\n\n const response = await fetch(`${authBase}/api/auth/oauth2/token`, {\n method: \"POST\",\n headers: { \"content-type\": \"application/x-www-form-urlencoded\" },\n body\n });\n\n if (!response.ok) {\n const err = await response.json().catch(() => ({})) as { error?: string; error_description?: string };\n throw new SmartHiveAuthError(err.error ?? \"token_error\", err.error_description ?? \"Token exchange failed.\");\n }\n\n const tokenBody = await response.json() as {\n access_token: string;\n refresh_token?: string;\n expires_in?: number;\n token_type?: string;\n };\n\n const session: AuthSession = {\n accessToken: tokenBody.access_token,\n refreshToken: tokenBody.refresh_token,\n expiresAt: tokenBody.expires_in ? Date.now() + tokenBody.expires_in * 1000 : undefined\n };\n\n await saveSession(session);\n await tempStorage.removeItem(smartHiveAuthStorageKeys.pkceVerifier);\n await tempStorage.removeItem(smartHiveAuthStorageKeys.pkceState);\n\n return session;\n },\n\n async logout() {\n await saveSession(null);\n await fetch(`${baseUrl}/api/auth/sign-out`, { method: \"POST\", credentials: \"include\" });\n },\n\n getSession: readSession,\n\n async getAccessToken() {\n const session = await readSession();\n if (!session) return null;\n if (session.expiresAt && Date.now() > session.expiresAt - 30000) {\n return (await client.refreshSession())?.accessToken ?? null;\n }\n return session.accessToken;\n },\n\n async getAuthorizationHeader() {\n const token = await client.getAccessToken();\n const headers: Record<string, string> = {};\n if (token) headers.authorization = `Bearer ${token}`;\n return headers;\n },\n\n async fetch(input, init = {}) {\n const authHeader = await client.getAuthorizationHeader();\n const headers = new Headers(init.headers);\n for (const [key, value] of Object.entries(authHeader)) {\n headers.set(key, value);\n }\n return fetch(input, { ...init, headers });\n },\n\n async refreshSession() {\n const session = await readSession();\n if (!session?.refreshToken) return session;\n const response = await fetch(`${baseUrl}/api/auth/oauth2/token`, {\n method: \"POST\",\n headers: { \"content-type\": \"application/x-www-form-urlencoded\" },\n body: new URLSearchParams({\n grant_type: \"refresh_token\",\n refresh_token: session.refreshToken\n })\n });\n if (!response.ok) { await saveSession(null); return null; }\n const body = await response.json() as { access_token: string; refresh_token?: string; expires_in?: number };\n const nextSession: AuthSession = {\n ...session,\n accessToken: body.access_token,\n refreshToken: body.refresh_token ?? session.refreshToken,\n expiresAt: body.expires_in ? Date.now() + body.expires_in * 1000 : session.expiresAt\n };\n await saveSession(nextSession);\n return nextSession;\n },\n\n async verifyToken(token) {\n if (token.split(\".\").length !== 3) return false;\n const response = await fetch(`${authBase}/api/auth/oauth2/userinfo`, {\n headers: { authorization: `Bearer ${token}` }\n });\n return response.ok;\n },\n\n async getUser() {\n const token = await client.getAccessToken();\n if (!token) return null;\n const response = await fetch(`${baseUrl}/api/auth/oauth2/userinfo`, {\n headers: { authorization: `Bearer ${token}` }\n });\n return response.ok ? response.json() : null;\n }\n };\n\n return client;\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
interface SmartHiveAuthConfig {
|
|
2
|
+
projectId: string;
|
|
3
|
+
publishableKey: string;
|
|
4
|
+
baseUrl: string;
|
|
5
|
+
/** Custom branded auth domain, e.g. "https://auth.myapp.com". Used as the entry point for login/token flows. Falls back to baseUrl. */
|
|
6
|
+
authDomain?: string;
|
|
7
|
+
/** Fallback auth domain if authDomain is unreachable, e.g. "https://auth.smarthivelabs.dev". */
|
|
8
|
+
fallbackAuthDomain?: string;
|
|
9
|
+
redirectUri?: string;
|
|
10
|
+
storage?: AuthStorage;
|
|
11
|
+
temporaryStorage?: AuthStorage;
|
|
12
|
+
}
|
|
13
|
+
interface AuthStorage {
|
|
14
|
+
getItem(key: string): string | null | Promise<string | null>;
|
|
15
|
+
setItem(key: string, value: string): void | Promise<void>;
|
|
16
|
+
removeItem(key: string): void | Promise<void>;
|
|
17
|
+
}
|
|
18
|
+
interface AuthSession {
|
|
19
|
+
accessToken: string;
|
|
20
|
+
refreshToken?: string;
|
|
21
|
+
expiresAt?: number;
|
|
22
|
+
user?: unknown;
|
|
23
|
+
}
|
|
24
|
+
interface SmartHiveAuthClient {
|
|
25
|
+
initialize(): Promise<void>;
|
|
26
|
+
login(options?: {
|
|
27
|
+
redirectUri?: string;
|
|
28
|
+
state?: string;
|
|
29
|
+
}): Promise<void>;
|
|
30
|
+
handleCallback(options?: {
|
|
31
|
+
url?: string;
|
|
32
|
+
}): Promise<AuthSession>;
|
|
33
|
+
logout(): Promise<void>;
|
|
34
|
+
getSession(): Promise<AuthSession | null>;
|
|
35
|
+
getAccessToken(): Promise<string | null>;
|
|
36
|
+
getAuthorizationHeader(): Promise<Record<string, string>>;
|
|
37
|
+
fetch(input: string | URL | Request, init?: RequestInit): Promise<Response>;
|
|
38
|
+
refreshSession(): Promise<AuthSession | null>;
|
|
39
|
+
verifyToken(token: string): Promise<boolean>;
|
|
40
|
+
getUser(): Promise<unknown>;
|
|
41
|
+
}
|
|
42
|
+
declare class SmartHiveAuthError extends Error {
|
|
43
|
+
code: string;
|
|
44
|
+
constructor(code: string, message: string);
|
|
45
|
+
}
|
|
46
|
+
declare function generateCodeVerifier(): Promise<string>;
|
|
47
|
+
declare function generateCodeChallenge(verifier: string): Promise<string>;
|
|
48
|
+
declare const smartHiveAuthStorageKeys: {
|
|
49
|
+
readonly session: "smarthive.auth.session";
|
|
50
|
+
readonly pkceVerifier: "smarthive.auth.pkce_verifier";
|
|
51
|
+
readonly pkceState: "smarthive.auth.pkce_state";
|
|
52
|
+
};
|
|
53
|
+
declare function initAuth(config: SmartHiveAuthConfig): SmartHiveAuthClient;
|
|
54
|
+
|
|
55
|
+
export { type AuthSession, type AuthStorage, type SmartHiveAuthClient, type SmartHiveAuthConfig, SmartHiveAuthError, generateCodeChallenge, generateCodeVerifier, initAuth, smartHiveAuthStorageKeys };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
interface SmartHiveAuthConfig {
|
|
2
|
+
projectId: string;
|
|
3
|
+
publishableKey: string;
|
|
4
|
+
baseUrl: string;
|
|
5
|
+
/** Custom branded auth domain, e.g. "https://auth.myapp.com". Used as the entry point for login/token flows. Falls back to baseUrl. */
|
|
6
|
+
authDomain?: string;
|
|
7
|
+
/** Fallback auth domain if authDomain is unreachable, e.g. "https://auth.smarthivelabs.dev". */
|
|
8
|
+
fallbackAuthDomain?: string;
|
|
9
|
+
redirectUri?: string;
|
|
10
|
+
storage?: AuthStorage;
|
|
11
|
+
temporaryStorage?: AuthStorage;
|
|
12
|
+
}
|
|
13
|
+
interface AuthStorage {
|
|
14
|
+
getItem(key: string): string | null | Promise<string | null>;
|
|
15
|
+
setItem(key: string, value: string): void | Promise<void>;
|
|
16
|
+
removeItem(key: string): void | Promise<void>;
|
|
17
|
+
}
|
|
18
|
+
interface AuthSession {
|
|
19
|
+
accessToken: string;
|
|
20
|
+
refreshToken?: string;
|
|
21
|
+
expiresAt?: number;
|
|
22
|
+
user?: unknown;
|
|
23
|
+
}
|
|
24
|
+
interface SmartHiveAuthClient {
|
|
25
|
+
initialize(): Promise<void>;
|
|
26
|
+
login(options?: {
|
|
27
|
+
redirectUri?: string;
|
|
28
|
+
state?: string;
|
|
29
|
+
}): Promise<void>;
|
|
30
|
+
handleCallback(options?: {
|
|
31
|
+
url?: string;
|
|
32
|
+
}): Promise<AuthSession>;
|
|
33
|
+
logout(): Promise<void>;
|
|
34
|
+
getSession(): Promise<AuthSession | null>;
|
|
35
|
+
getAccessToken(): Promise<string | null>;
|
|
36
|
+
getAuthorizationHeader(): Promise<Record<string, string>>;
|
|
37
|
+
fetch(input: string | URL | Request, init?: RequestInit): Promise<Response>;
|
|
38
|
+
refreshSession(): Promise<AuthSession | null>;
|
|
39
|
+
verifyToken(token: string): Promise<boolean>;
|
|
40
|
+
getUser(): Promise<unknown>;
|
|
41
|
+
}
|
|
42
|
+
declare class SmartHiveAuthError extends Error {
|
|
43
|
+
code: string;
|
|
44
|
+
constructor(code: string, message: string);
|
|
45
|
+
}
|
|
46
|
+
declare function generateCodeVerifier(): Promise<string>;
|
|
47
|
+
declare function generateCodeChallenge(verifier: string): Promise<string>;
|
|
48
|
+
declare const smartHiveAuthStorageKeys: {
|
|
49
|
+
readonly session: "smarthive.auth.session";
|
|
50
|
+
readonly pkceVerifier: "smarthive.auth.pkce_verifier";
|
|
51
|
+
readonly pkceState: "smarthive.auth.pkce_state";
|
|
52
|
+
};
|
|
53
|
+
declare function initAuth(config: SmartHiveAuthConfig): SmartHiveAuthClient;
|
|
54
|
+
|
|
55
|
+
export { type AuthSession, type AuthStorage, type SmartHiveAuthClient, type SmartHiveAuthConfig, SmartHiveAuthError, generateCodeChallenge, generateCodeVerifier, initAuth, smartHiveAuthStorageKeys };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
var SmartHiveAuthError = class extends Error {
|
|
3
|
+
constructor(code, message) {
|
|
4
|
+
super(message);
|
|
5
|
+
this.code = code;
|
|
6
|
+
this.name = "SmartHiveAuthError";
|
|
7
|
+
}
|
|
8
|
+
code;
|
|
9
|
+
};
|
|
10
|
+
async function generateCodeVerifier() {
|
|
11
|
+
const array = new Uint8Array(32);
|
|
12
|
+
crypto.getRandomValues(array);
|
|
13
|
+
return base64urlEncode(array);
|
|
14
|
+
}
|
|
15
|
+
async function generateCodeChallenge(verifier) {
|
|
16
|
+
const encoder = new TextEncoder();
|
|
17
|
+
const data = encoder.encode(verifier);
|
|
18
|
+
const digest = await crypto.subtle.digest("SHA-256", data);
|
|
19
|
+
return base64urlEncode(new Uint8Array(digest));
|
|
20
|
+
}
|
|
21
|
+
function base64urlEncode(buffer) {
|
|
22
|
+
let str = "";
|
|
23
|
+
for (const byte of buffer) str += String.fromCharCode(byte);
|
|
24
|
+
return btoa(str).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
25
|
+
}
|
|
26
|
+
var smartHiveAuthStorageKeys = {
|
|
27
|
+
session: "smarthive.auth.session",
|
|
28
|
+
pkceVerifier: "smarthive.auth.pkce_verifier",
|
|
29
|
+
pkceState: "smarthive.auth.pkce_state"
|
|
30
|
+
};
|
|
31
|
+
function browserStorage() {
|
|
32
|
+
return {
|
|
33
|
+
getItem: (key) => globalThis.localStorage?.getItem(key) ?? null,
|
|
34
|
+
setItem: (key, value) => globalThis.localStorage?.setItem(key, value),
|
|
35
|
+
removeItem: (key) => globalThis.localStorage?.removeItem(key)
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
function sessionStorageAdapter() {
|
|
39
|
+
return {
|
|
40
|
+
getItem: (key) => globalThis.sessionStorage?.getItem(key) ?? null,
|
|
41
|
+
setItem: (key, value) => globalThis.sessionStorage?.setItem(key, value),
|
|
42
|
+
removeItem: (key) => globalThis.sessionStorage?.removeItem(key)
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function normalizeBaseUrl(baseUrl) {
|
|
46
|
+
return baseUrl.replace(/\/$/, "");
|
|
47
|
+
}
|
|
48
|
+
function initAuth(config) {
|
|
49
|
+
const baseUrl = normalizeBaseUrl(config.baseUrl);
|
|
50
|
+
const authBase = normalizeBaseUrl(config.authDomain ?? config.baseUrl);
|
|
51
|
+
const storage = config.storage ?? browserStorage();
|
|
52
|
+
const tempStorage = config.temporaryStorage ?? sessionStorageAdapter();
|
|
53
|
+
async function saveSession(session) {
|
|
54
|
+
if (!session) {
|
|
55
|
+
await storage.removeItem(smartHiveAuthStorageKeys.session);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
await storage.setItem(smartHiveAuthStorageKeys.session, JSON.stringify(session));
|
|
59
|
+
}
|
|
60
|
+
async function readSession() {
|
|
61
|
+
const raw = await storage.getItem(smartHiveAuthStorageKeys.session);
|
|
62
|
+
return raw ? JSON.parse(raw) : null;
|
|
63
|
+
}
|
|
64
|
+
const client = {
|
|
65
|
+
async initialize() {
|
|
66
|
+
const response = await fetch(
|
|
67
|
+
`${baseUrl}/sdk/config?projectId=${encodeURIComponent(config.projectId)}&publishableKey=${encodeURIComponent(config.publishableKey)}`
|
|
68
|
+
);
|
|
69
|
+
if (!response.ok) throw new SmartHiveAuthError("project_not_found", "Smart Hive Auth project configuration was not found.");
|
|
70
|
+
},
|
|
71
|
+
async login(options) {
|
|
72
|
+
const redirectUri = options?.redirectUri ?? config.redirectUri ?? globalThis.location?.href;
|
|
73
|
+
const state = options?.state ?? crypto.randomUUID();
|
|
74
|
+
const verifier = await generateCodeVerifier();
|
|
75
|
+
const challenge = await generateCodeChallenge(verifier);
|
|
76
|
+
await tempStorage.setItem(smartHiveAuthStorageKeys.pkceVerifier, verifier);
|
|
77
|
+
await tempStorage.setItem(smartHiveAuthStorageKeys.pkceState, state);
|
|
78
|
+
const url = new URL(`${authBase}/api/auth/oauth2/authorize`);
|
|
79
|
+
url.searchParams.set("project_id", config.projectId);
|
|
80
|
+
url.searchParams.set("publishable_key", config.publishableKey);
|
|
81
|
+
url.searchParams.set("response_type", "code");
|
|
82
|
+
url.searchParams.set("redirect_uri", redirectUri);
|
|
83
|
+
url.searchParams.set("state", state);
|
|
84
|
+
url.searchParams.set("code_challenge", challenge);
|
|
85
|
+
url.searchParams.set("code_challenge_method", "S256");
|
|
86
|
+
globalThis.location.assign(url.toString());
|
|
87
|
+
},
|
|
88
|
+
async handleCallback(options) {
|
|
89
|
+
const href = options?.url ?? globalThis.location?.href;
|
|
90
|
+
if (!href) throw new SmartHiveAuthError("callback_failed", "No URL provided for callback handling.");
|
|
91
|
+
const url = new URL(href);
|
|
92
|
+
const code = url.searchParams.get("code");
|
|
93
|
+
const returnedState = url.searchParams.get("state");
|
|
94
|
+
if (!code) throw new SmartHiveAuthError("callback_failed", "No authorization code in callback URL.");
|
|
95
|
+
const storedState = await tempStorage.getItem(smartHiveAuthStorageKeys.pkceState);
|
|
96
|
+
if (!storedState || !returnedState || storedState !== returnedState) {
|
|
97
|
+
throw new SmartHiveAuthError("state_mismatch", "OAuth state mismatch \u2014 possible CSRF attack.");
|
|
98
|
+
}
|
|
99
|
+
const verifier = await tempStorage.getItem(smartHiveAuthStorageKeys.pkceVerifier);
|
|
100
|
+
if (!verifier) {
|
|
101
|
+
throw new SmartHiveAuthError("pkce_missing", "Missing PKCE verifier for authorization code exchange.");
|
|
102
|
+
}
|
|
103
|
+
const redirectUri = config.redirectUri ?? url.origin + url.pathname;
|
|
104
|
+
const body = new URLSearchParams({
|
|
105
|
+
grant_type: "authorization_code",
|
|
106
|
+
code,
|
|
107
|
+
redirect_uri: redirectUri,
|
|
108
|
+
client_id: config.publishableKey
|
|
109
|
+
});
|
|
110
|
+
body.set("code_verifier", verifier);
|
|
111
|
+
const response = await fetch(`${authBase}/api/auth/oauth2/token`, {
|
|
112
|
+
method: "POST",
|
|
113
|
+
headers: { "content-type": "application/x-www-form-urlencoded" },
|
|
114
|
+
body
|
|
115
|
+
});
|
|
116
|
+
if (!response.ok) {
|
|
117
|
+
const err = await response.json().catch(() => ({}));
|
|
118
|
+
throw new SmartHiveAuthError(err.error ?? "token_error", err.error_description ?? "Token exchange failed.");
|
|
119
|
+
}
|
|
120
|
+
const tokenBody = await response.json();
|
|
121
|
+
const session = {
|
|
122
|
+
accessToken: tokenBody.access_token,
|
|
123
|
+
refreshToken: tokenBody.refresh_token,
|
|
124
|
+
expiresAt: tokenBody.expires_in ? Date.now() + tokenBody.expires_in * 1e3 : void 0
|
|
125
|
+
};
|
|
126
|
+
await saveSession(session);
|
|
127
|
+
await tempStorage.removeItem(smartHiveAuthStorageKeys.pkceVerifier);
|
|
128
|
+
await tempStorage.removeItem(smartHiveAuthStorageKeys.pkceState);
|
|
129
|
+
return session;
|
|
130
|
+
},
|
|
131
|
+
async logout() {
|
|
132
|
+
await saveSession(null);
|
|
133
|
+
await fetch(`${baseUrl}/api/auth/sign-out`, { method: "POST", credentials: "include" });
|
|
134
|
+
},
|
|
135
|
+
getSession: readSession,
|
|
136
|
+
async getAccessToken() {
|
|
137
|
+
const session = await readSession();
|
|
138
|
+
if (!session) return null;
|
|
139
|
+
if (session.expiresAt && Date.now() > session.expiresAt - 3e4) {
|
|
140
|
+
return (await client.refreshSession())?.accessToken ?? null;
|
|
141
|
+
}
|
|
142
|
+
return session.accessToken;
|
|
143
|
+
},
|
|
144
|
+
async getAuthorizationHeader() {
|
|
145
|
+
const token = await client.getAccessToken();
|
|
146
|
+
const headers = {};
|
|
147
|
+
if (token) headers.authorization = `Bearer ${token}`;
|
|
148
|
+
return headers;
|
|
149
|
+
},
|
|
150
|
+
async fetch(input, init = {}) {
|
|
151
|
+
const authHeader = await client.getAuthorizationHeader();
|
|
152
|
+
const headers = new Headers(init.headers);
|
|
153
|
+
for (const [key, value] of Object.entries(authHeader)) {
|
|
154
|
+
headers.set(key, value);
|
|
155
|
+
}
|
|
156
|
+
return fetch(input, { ...init, headers });
|
|
157
|
+
},
|
|
158
|
+
async refreshSession() {
|
|
159
|
+
const session = await readSession();
|
|
160
|
+
if (!session?.refreshToken) return session;
|
|
161
|
+
const response = await fetch(`${baseUrl}/api/auth/oauth2/token`, {
|
|
162
|
+
method: "POST",
|
|
163
|
+
headers: { "content-type": "application/x-www-form-urlencoded" },
|
|
164
|
+
body: new URLSearchParams({
|
|
165
|
+
grant_type: "refresh_token",
|
|
166
|
+
refresh_token: session.refreshToken
|
|
167
|
+
})
|
|
168
|
+
});
|
|
169
|
+
if (!response.ok) {
|
|
170
|
+
await saveSession(null);
|
|
171
|
+
return null;
|
|
172
|
+
}
|
|
173
|
+
const body = await response.json();
|
|
174
|
+
const nextSession = {
|
|
175
|
+
...session,
|
|
176
|
+
accessToken: body.access_token,
|
|
177
|
+
refreshToken: body.refresh_token ?? session.refreshToken,
|
|
178
|
+
expiresAt: body.expires_in ? Date.now() + body.expires_in * 1e3 : session.expiresAt
|
|
179
|
+
};
|
|
180
|
+
await saveSession(nextSession);
|
|
181
|
+
return nextSession;
|
|
182
|
+
},
|
|
183
|
+
async verifyToken(token) {
|
|
184
|
+
if (token.split(".").length !== 3) return false;
|
|
185
|
+
const response = await fetch(`${authBase}/api/auth/oauth2/userinfo`, {
|
|
186
|
+
headers: { authorization: `Bearer ${token}` }
|
|
187
|
+
});
|
|
188
|
+
return response.ok;
|
|
189
|
+
},
|
|
190
|
+
async getUser() {
|
|
191
|
+
const token = await client.getAccessToken();
|
|
192
|
+
if (!token) return null;
|
|
193
|
+
const response = await fetch(`${baseUrl}/api/auth/oauth2/userinfo`, {
|
|
194
|
+
headers: { authorization: `Bearer ${token}` }
|
|
195
|
+
});
|
|
196
|
+
return response.ok ? response.json() : null;
|
|
197
|
+
}
|
|
198
|
+
};
|
|
199
|
+
return client;
|
|
200
|
+
}
|
|
201
|
+
export {
|
|
202
|
+
SmartHiveAuthError,
|
|
203
|
+
generateCodeChallenge,
|
|
204
|
+
generateCodeVerifier,
|
|
205
|
+
initAuth,
|
|
206
|
+
smartHiveAuthStorageKeys
|
|
207
|
+
};
|
|
208
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export interface SmartHiveAuthConfig {\n projectId: string;\n publishableKey: string;\n baseUrl: string;\n /** Custom branded auth domain, e.g. \"https://auth.myapp.com\". Used as the entry point for login/token flows. Falls back to baseUrl. */\n authDomain?: string;\n /** Fallback auth domain if authDomain is unreachable, e.g. \"https://auth.smarthivelabs.dev\". */\n fallbackAuthDomain?: string;\n redirectUri?: string;\n storage?: AuthStorage;\n temporaryStorage?: AuthStorage;\n}\n\nexport interface AuthStorage {\n getItem(key: string): string | null | Promise<string | null>;\n setItem(key: string, value: string): void | Promise<void>;\n removeItem(key: string): void | Promise<void>;\n}\n\nexport interface AuthSession {\n accessToken: string;\n refreshToken?: string;\n expiresAt?: number;\n user?: unknown;\n}\n\nexport interface SmartHiveAuthClient {\n initialize(): Promise<void>;\n login(options?: { redirectUri?: string; state?: string }): Promise<void>;\n handleCallback(options?: { url?: string }): Promise<AuthSession>;\n logout(): Promise<void>;\n getSession(): Promise<AuthSession | null>;\n getAccessToken(): Promise<string | null>;\n getAuthorizationHeader(): Promise<Record<string, string>>;\n fetch(input: string | URL | Request, init?: RequestInit): Promise<Response>;\n refreshSession(): Promise<AuthSession | null>;\n verifyToken(token: string): Promise<boolean>;\n getUser(): Promise<unknown>;\n}\n\nexport class SmartHiveAuthError extends Error {\n constructor(public code: string, message: string) {\n super(message);\n this.name = \"SmartHiveAuthError\";\n }\n}\n\n// ── PKCE helpers (Web Crypto — works in browser + Node 18+) ──────────────────\n\nexport async function generateCodeVerifier(): Promise<string> {\n const array = new Uint8Array(32);\n crypto.getRandomValues(array);\n return base64urlEncode(array);\n}\n\nexport async function generateCodeChallenge(verifier: string): Promise<string> {\n const encoder = new TextEncoder();\n const data = encoder.encode(verifier);\n const digest = await crypto.subtle.digest(\"SHA-256\", data);\n return base64urlEncode(new Uint8Array(digest));\n}\n\nfunction base64urlEncode(buffer: Uint8Array): string {\n let str = \"\";\n for (const byte of buffer) str += String.fromCharCode(byte);\n return btoa(str).replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=+$/, \"\");\n}\n\n// ── Storage keys ─────────────────────────────────────────────────────────────\n\nexport const smartHiveAuthStorageKeys = {\n session: \"smarthive.auth.session\",\n pkceVerifier: \"smarthive.auth.pkce_verifier\",\n pkceState: \"smarthive.auth.pkce_state\"\n} as const;\n\nfunction browserStorage(): AuthStorage {\n return {\n getItem: (key) => globalThis.localStorage?.getItem(key) ?? null,\n setItem: (key, value) => globalThis.localStorage?.setItem(key, value),\n removeItem: (key) => globalThis.localStorage?.removeItem(key)\n };\n}\n\nfunction sessionStorageAdapter(): Pick<AuthStorage, \"getItem\" | \"setItem\" | \"removeItem\"> {\n return {\n getItem: (key) => globalThis.sessionStorage?.getItem(key) ?? null,\n setItem: (key, value) => globalThis.sessionStorage?.setItem(key, value),\n removeItem: (key) => globalThis.sessionStorage?.removeItem(key)\n };\n}\n\nfunction normalizeBaseUrl(baseUrl: string) {\n return baseUrl.replace(/\\/$/, \"\");\n}\n\n// ── Factory ───────────────────────────────────────────────────────────────────\n\nexport function initAuth(config: SmartHiveAuthConfig): SmartHiveAuthClient {\n const baseUrl = normalizeBaseUrl(config.baseUrl);\n const authBase = normalizeBaseUrl(config.authDomain ?? config.baseUrl);\n const storage = config.storage ?? browserStorage();\n const tempStorage = config.temporaryStorage ?? sessionStorageAdapter();\n\n async function saveSession(session: AuthSession | null) {\n if (!session) { await storage.removeItem(smartHiveAuthStorageKeys.session); return; }\n await storage.setItem(smartHiveAuthStorageKeys.session, JSON.stringify(session));\n }\n\n async function readSession(): Promise<AuthSession | null> {\n const raw = await storage.getItem(smartHiveAuthStorageKeys.session);\n return raw ? JSON.parse(raw) as AuthSession : null;\n }\n\n const client: SmartHiveAuthClient = {\n async initialize() {\n const response = await fetch(\n `${baseUrl}/sdk/config?projectId=${encodeURIComponent(config.projectId)}&publishableKey=${encodeURIComponent(config.publishableKey)}`\n );\n if (!response.ok) throw new SmartHiveAuthError(\"project_not_found\", \"Smart Hive Auth project configuration was not found.\");\n },\n\n async login(options) {\n const redirectUri = options?.redirectUri ?? config.redirectUri ?? globalThis.location?.href;\n const state = options?.state ?? crypto.randomUUID();\n const verifier = await generateCodeVerifier();\n const challenge = await generateCodeChallenge(verifier);\n\n await tempStorage.setItem(smartHiveAuthStorageKeys.pkceVerifier, verifier);\n await tempStorage.setItem(smartHiveAuthStorageKeys.pkceState, state);\n\n const url = new URL(`${authBase}/api/auth/oauth2/authorize`);\n url.searchParams.set(\"project_id\", config.projectId);\n url.searchParams.set(\"publishable_key\", config.publishableKey);\n url.searchParams.set(\"response_type\", \"code\");\n url.searchParams.set(\"redirect_uri\", redirectUri);\n url.searchParams.set(\"state\", state);\n url.searchParams.set(\"code_challenge\", challenge);\n url.searchParams.set(\"code_challenge_method\", \"S256\");\n\n globalThis.location.assign(url.toString());\n },\n\n async handleCallback(options) {\n const href = options?.url ?? globalThis.location?.href;\n if (!href) throw new SmartHiveAuthError(\"callback_failed\", \"No URL provided for callback handling.\");\n\n const url = new URL(href);\n const code = url.searchParams.get(\"code\");\n const returnedState = url.searchParams.get(\"state\");\n\n if (!code) throw new SmartHiveAuthError(\"callback_failed\", \"No authorization code in callback URL.\");\n\n const storedState = await tempStorage.getItem(smartHiveAuthStorageKeys.pkceState);\n if (!storedState || !returnedState || storedState !== returnedState) {\n throw new SmartHiveAuthError(\"state_mismatch\", \"OAuth state mismatch — possible CSRF attack.\");\n }\n\n const verifier = await tempStorage.getItem(smartHiveAuthStorageKeys.pkceVerifier);\n if (!verifier) {\n throw new SmartHiveAuthError(\"pkce_missing\", \"Missing PKCE verifier for authorization code exchange.\");\n }\n const redirectUri = config.redirectUri ?? (url.origin + url.pathname);\n\n const body = new URLSearchParams({\n grant_type: \"authorization_code\",\n code,\n redirect_uri: redirectUri,\n client_id: config.publishableKey\n });\n body.set(\"code_verifier\", verifier);\n\n const response = await fetch(`${authBase}/api/auth/oauth2/token`, {\n method: \"POST\",\n headers: { \"content-type\": \"application/x-www-form-urlencoded\" },\n body\n });\n\n if (!response.ok) {\n const err = await response.json().catch(() => ({})) as { error?: string; error_description?: string };\n throw new SmartHiveAuthError(err.error ?? \"token_error\", err.error_description ?? \"Token exchange failed.\");\n }\n\n const tokenBody = await response.json() as {\n access_token: string;\n refresh_token?: string;\n expires_in?: number;\n token_type?: string;\n };\n\n const session: AuthSession = {\n accessToken: tokenBody.access_token,\n refreshToken: tokenBody.refresh_token,\n expiresAt: tokenBody.expires_in ? Date.now() + tokenBody.expires_in * 1000 : undefined\n };\n\n await saveSession(session);\n await tempStorage.removeItem(smartHiveAuthStorageKeys.pkceVerifier);\n await tempStorage.removeItem(smartHiveAuthStorageKeys.pkceState);\n\n return session;\n },\n\n async logout() {\n await saveSession(null);\n await fetch(`${baseUrl}/api/auth/sign-out`, { method: \"POST\", credentials: \"include\" });\n },\n\n getSession: readSession,\n\n async getAccessToken() {\n const session = await readSession();\n if (!session) return null;\n if (session.expiresAt && Date.now() > session.expiresAt - 30000) {\n return (await client.refreshSession())?.accessToken ?? null;\n }\n return session.accessToken;\n },\n\n async getAuthorizationHeader() {\n const token = await client.getAccessToken();\n const headers: Record<string, string> = {};\n if (token) headers.authorization = `Bearer ${token}`;\n return headers;\n },\n\n async fetch(input, init = {}) {\n const authHeader = await client.getAuthorizationHeader();\n const headers = new Headers(init.headers);\n for (const [key, value] of Object.entries(authHeader)) {\n headers.set(key, value);\n }\n return fetch(input, { ...init, headers });\n },\n\n async refreshSession() {\n const session = await readSession();\n if (!session?.refreshToken) return session;\n const response = await fetch(`${baseUrl}/api/auth/oauth2/token`, {\n method: \"POST\",\n headers: { \"content-type\": \"application/x-www-form-urlencoded\" },\n body: new URLSearchParams({\n grant_type: \"refresh_token\",\n refresh_token: session.refreshToken\n })\n });\n if (!response.ok) { await saveSession(null); return null; }\n const body = await response.json() as { access_token: string; refresh_token?: string; expires_in?: number };\n const nextSession: AuthSession = {\n ...session,\n accessToken: body.access_token,\n refreshToken: body.refresh_token ?? session.refreshToken,\n expiresAt: body.expires_in ? Date.now() + body.expires_in * 1000 : session.expiresAt\n };\n await saveSession(nextSession);\n return nextSession;\n },\n\n async verifyToken(token) {\n if (token.split(\".\").length !== 3) return false;\n const response = await fetch(`${authBase}/api/auth/oauth2/userinfo`, {\n headers: { authorization: `Bearer ${token}` }\n });\n return response.ok;\n },\n\n async getUser() {\n const token = await client.getAccessToken();\n if (!token) return null;\n const response = await fetch(`${baseUrl}/api/auth/oauth2/userinfo`, {\n headers: { authorization: `Bearer ${token}` }\n });\n return response.ok ? response.json() : null;\n }\n };\n\n return client;\n}\n"],"mappings":"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","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@smarthivelabs-devs/auth-sdk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "SmartHive Auth JavaScript/TypeScript SDK — core client for browser, Node.js, and React Native",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/smarthivelabs-devs/smarthive-auth-sdk"
|
|
9
|
+
},
|
|
10
|
+
"publishConfig": {
|
|
11
|
+
"access": "public"
|
|
12
|
+
},
|
|
13
|
+
"type": "module",
|
|
14
|
+
"main": "./dist/index.cjs",
|
|
15
|
+
"module": "./dist/index.js",
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"exports": {
|
|
18
|
+
".": {
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"import": "./dist/index.js",
|
|
21
|
+
"require": "./dist/index.cjs"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"dist",
|
|
26
|
+
"README.md",
|
|
27
|
+
"LICENSE"
|
|
28
|
+
],
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"tsup": "^8.3.0",
|
|
31
|
+
"typescript": "^5.7.3"
|
|
32
|
+
},
|
|
33
|
+
"scripts": {
|
|
34
|
+
"build": "tsup",
|
|
35
|
+
"build:watch": "tsup --watch",
|
|
36
|
+
"typecheck": "tsc -p tsconfig.json --noEmit"
|
|
37
|
+
}
|
|
38
|
+
}
|