@ubean/auth 0.1.2 → 0.1.4
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/core.d.ts +21 -0
- package/dist/core.js +520 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +4 -0
- package/dist/runtime.d.ts +62 -0
- package/dist/runtime.js +155 -0
- package/dist/types-DlL9lr7A.d.ts +220 -0
- package/dist/vite.d.ts +7 -0
- package/dist/vite.js +155 -0
- package/package.json +1 -1
package/dist/core.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { a as AuthState, c as ResolvedAuthOptions, d as UbeanAuthOptions, i as AuthSession, n as AuthClient, o as AuthUser, r as AuthError } from "./types-DlL9lr7A.js";
|
|
2
|
+
import { Context, MiddlewareHandler } from "hono";
|
|
3
|
+
import { BetterAuthOptions } from "better-auth";
|
|
4
|
+
//#region src/core.d.ts
|
|
5
|
+
declare function resolveAuthOptions(options?: UbeanAuthOptions): ResolvedAuthOptions;
|
|
6
|
+
declare function defineAuth(config: UbeanAuthOptions | ((ctx: {
|
|
7
|
+
defaults: BetterAuthOptions;
|
|
8
|
+
}) => UbeanAuthOptions)): UbeanAuthOptions;
|
|
9
|
+
declare function createAuthHandler(options?: UbeanAuthOptions): {
|
|
10
|
+
handler: (request: Request) => Promise<Response>;
|
|
11
|
+
resolveAuth: () => Promise<unknown>;
|
|
12
|
+
getOptions: () => ResolvedAuthOptions;
|
|
13
|
+
};
|
|
14
|
+
declare function authMiddleware(): MiddlewareHandler;
|
|
15
|
+
declare function getUser(): AuthUser | null;
|
|
16
|
+
declare function getSession(): AuthState | null;
|
|
17
|
+
declare function requireAuth(c?: Context): AuthUser;
|
|
18
|
+
declare function createAuthClient(basePath?: string): AuthClient;
|
|
19
|
+
declare function getServerSession(req?: Request): Promise<AuthSession | null>;
|
|
20
|
+
//#endregion
|
|
21
|
+
export { type AuthClient, type AuthError, type AuthSession, type AuthState, type AuthUser, authMiddleware, createAuthClient, createAuthHandler, defineAuth, getServerSession, getSession, getUser, requireAuth, resolveAuthOptions };
|
package/dist/core.js
ADDED
|
@@ -0,0 +1,520 @@
|
|
|
1
|
+
import { consola } from "consola";
|
|
2
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
3
|
+
import { defu } from "defu";
|
|
4
|
+
//#region src/core.ts
|
|
5
|
+
const AUTH_CONTEXT_SYMBOL = Symbol.for("ubean.authContext.v1");
|
|
6
|
+
function getAuthAsyncLocalStorage() {
|
|
7
|
+
const g = globalThis;
|
|
8
|
+
if (!g[AUTH_CONTEXT_SYMBOL]) g[AUTH_CONTEXT_SYMBOL] = new AsyncLocalStorage();
|
|
9
|
+
return g[AUTH_CONTEXT_SYMBOL];
|
|
10
|
+
}
|
|
11
|
+
const authContext = getAuthAsyncLocalStorage();
|
|
12
|
+
const authInstance = {
|
|
13
|
+
handler: null,
|
|
14
|
+
api: null,
|
|
15
|
+
options: null
|
|
16
|
+
};
|
|
17
|
+
function resetAuthInstance() {
|
|
18
|
+
authInstance.handler = null;
|
|
19
|
+
authInstance.api = null;
|
|
20
|
+
authInstance.options = null;
|
|
21
|
+
}
|
|
22
|
+
function resolveAuthOptions(options = {}) {
|
|
23
|
+
return defu(options, {
|
|
24
|
+
enabled: true,
|
|
25
|
+
basePath: "/api/auth",
|
|
26
|
+
baseURL: "",
|
|
27
|
+
secret: process.env.BETTER_AUTH_SECRET || process.env.AUTH_SECRET || "ubean-dev-secret-change-me",
|
|
28
|
+
clientOptions: {
|
|
29
|
+
fetchOptions: {},
|
|
30
|
+
plugins: []
|
|
31
|
+
},
|
|
32
|
+
redirectTo: {
|
|
33
|
+
login: "/login",
|
|
34
|
+
signup: "/signup",
|
|
35
|
+
callback: "/"
|
|
36
|
+
},
|
|
37
|
+
session: {
|
|
38
|
+
cookieName: "ubean_session",
|
|
39
|
+
expiresIn: 3600 * 24 * 7,
|
|
40
|
+
updateAge: 3600 * 24
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
function defineAuth(config) {
|
|
45
|
+
if (typeof config === "function") return config({ defaults: {
|
|
46
|
+
basePath: "/api/auth",
|
|
47
|
+
emailAndPassword: { enabled: true }
|
|
48
|
+
} });
|
|
49
|
+
return config;
|
|
50
|
+
}
|
|
51
|
+
function createFallbackAuth(resolved) {
|
|
52
|
+
consola.warn("[auth] better-auth not installed, using minimal fallback auth implementation");
|
|
53
|
+
consola.warn("[auth] Install better-auth with: pnpm add better-auth");
|
|
54
|
+
const users = /* @__PURE__ */ new Map();
|
|
55
|
+
const sessions = /* @__PURE__ */ new Map();
|
|
56
|
+
function generateId() {
|
|
57
|
+
return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
|
|
58
|
+
}
|
|
59
|
+
function hashPassword(password) {
|
|
60
|
+
return Buffer.from(password).toString("base64");
|
|
61
|
+
}
|
|
62
|
+
function createSession(userId) {
|
|
63
|
+
const token = generateId();
|
|
64
|
+
const expiresAt = new Date(Date.now() + resolved.session.expiresIn * 1e3);
|
|
65
|
+
sessions.set(token, {
|
|
66
|
+
userId,
|
|
67
|
+
token,
|
|
68
|
+
expiresAt
|
|
69
|
+
});
|
|
70
|
+
return {
|
|
71
|
+
token,
|
|
72
|
+
expiresAt
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
function findSessionByToken(token) {
|
|
76
|
+
if (!token) return null;
|
|
77
|
+
const session = sessions.get(token);
|
|
78
|
+
if (!session) return null;
|
|
79
|
+
if (session.expiresAt < /* @__PURE__ */ new Date()) {
|
|
80
|
+
sessions.delete(token);
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
return session;
|
|
84
|
+
}
|
|
85
|
+
const fallbackHandler = async (request) => {
|
|
86
|
+
const path = new URL(request.url).pathname.replace(resolved.basePath, "");
|
|
87
|
+
const method = request.method;
|
|
88
|
+
const setSessionCookie = (token, expiresAt) => {
|
|
89
|
+
const headers = new Headers({ "content-type": "application/json" });
|
|
90
|
+
if (token) headers.append("set-cookie", `${resolved.session.cookieName}=${token}; Path=/; HttpOnly; SameSite=Lax; Expires=${expiresAt?.toUTCString()}`);
|
|
91
|
+
else headers.append("set-cookie", `${resolved.session.cookieName}=; Path=/; HttpOnly; SameSite=Lax; Max-Age=0`);
|
|
92
|
+
return headers;
|
|
93
|
+
};
|
|
94
|
+
const getTokenFromCookie = (req) => {
|
|
95
|
+
return (req.headers.get("cookie") || "").match(new RegExp(`${resolved.session.cookieName}=([^;]+)`))?.[1];
|
|
96
|
+
};
|
|
97
|
+
try {
|
|
98
|
+
if (path === "/sign-up/email" && method === "POST") {
|
|
99
|
+
const { email, password, name } = await request.json().catch(() => ({}));
|
|
100
|
+
if (!email || !password) return new Response(JSON.stringify({ error: "Email and password required" }), {
|
|
101
|
+
status: 400,
|
|
102
|
+
headers: { "content-type": "application/json" }
|
|
103
|
+
});
|
|
104
|
+
for (const [, u] of users) if (u.email === email) return new Response(JSON.stringify({ error: "User already exists" }), {
|
|
105
|
+
status: 400,
|
|
106
|
+
headers: { "content-type": "application/json" }
|
|
107
|
+
});
|
|
108
|
+
const id = generateId();
|
|
109
|
+
users.set(id, {
|
|
110
|
+
id,
|
|
111
|
+
email,
|
|
112
|
+
password: hashPassword(password),
|
|
113
|
+
name: name || email.split("@")[0],
|
|
114
|
+
createdAt: /* @__PURE__ */ new Date()
|
|
115
|
+
});
|
|
116
|
+
const { token, expiresAt } = createSession(id);
|
|
117
|
+
const user = users.get(id);
|
|
118
|
+
return new Response(JSON.stringify({
|
|
119
|
+
token,
|
|
120
|
+
user: {
|
|
121
|
+
id: user.id,
|
|
122
|
+
email: user.email,
|
|
123
|
+
name: user.name,
|
|
124
|
+
emailVerified: false,
|
|
125
|
+
createdAt: user.createdAt,
|
|
126
|
+
updatedAt: user.createdAt
|
|
127
|
+
}
|
|
128
|
+
}), {
|
|
129
|
+
status: 200,
|
|
130
|
+
headers: setSessionCookie(token, expiresAt)
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
if (path === "/sign-in/email" && method === "POST") {
|
|
134
|
+
const { email, password } = await request.json().catch(() => ({}));
|
|
135
|
+
let foundUser = null;
|
|
136
|
+
for (const [, u] of users) if (u.email === email && u.password === hashPassword(password)) {
|
|
137
|
+
foundUser = u;
|
|
138
|
+
break;
|
|
139
|
+
}
|
|
140
|
+
if (!foundUser) return new Response(JSON.stringify({ error: "Invalid credentials" }), {
|
|
141
|
+
status: 401,
|
|
142
|
+
headers: { "content-type": "application/json" }
|
|
143
|
+
});
|
|
144
|
+
const { token, expiresAt } = createSession(foundUser.id);
|
|
145
|
+
return new Response(JSON.stringify({
|
|
146
|
+
token,
|
|
147
|
+
user: {
|
|
148
|
+
id: foundUser.id,
|
|
149
|
+
email: foundUser.email,
|
|
150
|
+
name: foundUser.name,
|
|
151
|
+
emailVerified: false,
|
|
152
|
+
createdAt: foundUser.createdAt,
|
|
153
|
+
updatedAt: foundUser.createdAt
|
|
154
|
+
}
|
|
155
|
+
}), {
|
|
156
|
+
status: 200,
|
|
157
|
+
headers: setSessionCookie(token, expiresAt)
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
if (path === "/sign-out" && method === "POST") {
|
|
161
|
+
const token = getTokenFromCookie(request);
|
|
162
|
+
if (token) sessions.delete(token);
|
|
163
|
+
return new Response(JSON.stringify({ success: true }), {
|
|
164
|
+
status: 200,
|
|
165
|
+
headers: setSessionCookie(null)
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
if (path === "/get-session" && method === "GET") {
|
|
169
|
+
const session = findSessionByToken(getTokenFromCookie(request));
|
|
170
|
+
if (!session) return new Response(JSON.stringify(null), {
|
|
171
|
+
status: 200,
|
|
172
|
+
headers: { "content-type": "application/json" }
|
|
173
|
+
});
|
|
174
|
+
const u = users.get(session.userId);
|
|
175
|
+
return new Response(JSON.stringify({
|
|
176
|
+
session: {
|
|
177
|
+
id: session.token,
|
|
178
|
+
userId: u.id,
|
|
179
|
+
token: session.token,
|
|
180
|
+
expiresAt: session.expiresAt,
|
|
181
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
182
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
183
|
+
},
|
|
184
|
+
user: {
|
|
185
|
+
id: u.id,
|
|
186
|
+
email: u.email,
|
|
187
|
+
name: u.name,
|
|
188
|
+
emailVerified: false,
|
|
189
|
+
createdAt: u.createdAt,
|
|
190
|
+
updatedAt: u.createdAt
|
|
191
|
+
}
|
|
192
|
+
}), {
|
|
193
|
+
status: 200,
|
|
194
|
+
headers: { "content-type": "application/json" }
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
return new Response(JSON.stringify({ error: "Not found" }), {
|
|
198
|
+
status: 404,
|
|
199
|
+
headers: { "content-type": "application/json" }
|
|
200
|
+
});
|
|
201
|
+
} catch {
|
|
202
|
+
return new Response(JSON.stringify({ error: "Internal error" }), {
|
|
203
|
+
status: 500,
|
|
204
|
+
headers: { "content-type": "application/json" }
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
authInstance.handler = fallbackHandler;
|
|
209
|
+
authInstance.api = { getSession: (async (headersInput) => {
|
|
210
|
+
const session = findSessionByToken(((headersInput instanceof Headers ? headersInput : new Headers(headersInput)).get("cookie") || "").match(new RegExp(`${resolved.session.cookieName}=([^;]+)`))?.[1]);
|
|
211
|
+
if (!session) return null;
|
|
212
|
+
const u = users.get(session.userId);
|
|
213
|
+
if (!u) return null;
|
|
214
|
+
return {
|
|
215
|
+
session: {
|
|
216
|
+
id: session.token,
|
|
217
|
+
userId: u.id,
|
|
218
|
+
token: session.token,
|
|
219
|
+
expiresAt: session.expiresAt,
|
|
220
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
221
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
222
|
+
},
|
|
223
|
+
user: {
|
|
224
|
+
id: u.id,
|
|
225
|
+
email: u.email,
|
|
226
|
+
name: u.name,
|
|
227
|
+
emailVerified: false,
|
|
228
|
+
createdAt: u.createdAt,
|
|
229
|
+
updatedAt: u.createdAt
|
|
230
|
+
}
|
|
231
|
+
};
|
|
232
|
+
}) };
|
|
233
|
+
return {
|
|
234
|
+
handler: fallbackHandler,
|
|
235
|
+
api: authInstance.api
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
function createAuthHandler(options = {}) {
|
|
239
|
+
const resolved = resolveAuthOptions(options);
|
|
240
|
+
resetAuthInstance();
|
|
241
|
+
authInstance.options = resolved;
|
|
242
|
+
const hasBetterAuthConfig = !!(resolved.betterAuth && Object.keys(resolved.betterAuth).length > 0) || !!resolved.database;
|
|
243
|
+
async function initBetterAuth() {
|
|
244
|
+
if (!hasBetterAuthConfig) return createFallbackAuth(resolved);
|
|
245
|
+
try {
|
|
246
|
+
const { betterAuth } = await import("better-auth");
|
|
247
|
+
const defaults = {
|
|
248
|
+
baseURL: resolved.baseURL || void 0,
|
|
249
|
+
basePath: resolved.basePath,
|
|
250
|
+
secret: resolved.secret,
|
|
251
|
+
trustedOrigins: resolved.baseURL ? [resolved.baseURL] : [],
|
|
252
|
+
database: resolved.database,
|
|
253
|
+
session: {
|
|
254
|
+
expiresIn: resolved.session.expiresIn,
|
|
255
|
+
updateAge: resolved.session.updateAge
|
|
256
|
+
},
|
|
257
|
+
emailAndPassword: { enabled: true }
|
|
258
|
+
};
|
|
259
|
+
let betterAuthOpts;
|
|
260
|
+
if (typeof options.betterAuth === "function") betterAuthOpts = options.betterAuth({ defaults });
|
|
261
|
+
else betterAuthOpts = defu(options.betterAuth, defaults);
|
|
262
|
+
const auth = betterAuth(betterAuthOpts);
|
|
263
|
+
authInstance.handler = auth.handler;
|
|
264
|
+
authInstance.api = auth.api;
|
|
265
|
+
return auth;
|
|
266
|
+
} catch {
|
|
267
|
+
return createFallbackAuth(resolved);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
let initPromise = null;
|
|
271
|
+
async function resolveAuth() {
|
|
272
|
+
if (!initPromise) initPromise = initBetterAuth();
|
|
273
|
+
return initPromise;
|
|
274
|
+
}
|
|
275
|
+
async function handler(request) {
|
|
276
|
+
await resolveAuth();
|
|
277
|
+
if (authInstance.handler) return authInstance.handler(request);
|
|
278
|
+
return new Response(JSON.stringify({ error: "Auth handler not initialized" }), {
|
|
279
|
+
status: 500,
|
|
280
|
+
headers: { "content-type": "application/json" }
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
return {
|
|
284
|
+
handler,
|
|
285
|
+
resolveAuth,
|
|
286
|
+
getOptions: () => resolved
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
function authMiddleware() {
|
|
290
|
+
return async (c, next) => {
|
|
291
|
+
const opts = authInstance.options || resolveAuthOptions();
|
|
292
|
+
try {
|
|
293
|
+
const request = c.req.raw;
|
|
294
|
+
const sessionCookieMatch = (request.headers.get("cookie") || "").match(new RegExp(`${opts.session.cookieName}=([^;]+)`));
|
|
295
|
+
const bearerMatch = (request.headers.get("authorization") || "").match(/^Bearer\s+(.+)$/i);
|
|
296
|
+
const token = sessionCookieMatch?.[1] || bearerMatch?.[1];
|
|
297
|
+
let user = null;
|
|
298
|
+
let session = null;
|
|
299
|
+
await (authInstance.handler ? Promise.resolve() : Promise.resolve(createAuthHandler(opts)).then(({ resolveAuth }) => resolveAuth()));
|
|
300
|
+
if (authInstance.api?.getSession && token) try {
|
|
301
|
+
const headers = new Headers({ cookie: `${opts.session.cookieName}=${token}` });
|
|
302
|
+
const result = await authInstance.api.getSession(headers);
|
|
303
|
+
if (result) {
|
|
304
|
+
session = result.session;
|
|
305
|
+
user = result.user;
|
|
306
|
+
}
|
|
307
|
+
} catch {}
|
|
308
|
+
if (user) c.set("user", user);
|
|
309
|
+
if (session) c.set("session", session);
|
|
310
|
+
await authContext.run({
|
|
311
|
+
user,
|
|
312
|
+
session
|
|
313
|
+
}, next);
|
|
314
|
+
} catch {
|
|
315
|
+
await next();
|
|
316
|
+
}
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
function getUser() {
|
|
320
|
+
return authContext.getStore()?.user ?? null;
|
|
321
|
+
}
|
|
322
|
+
function getSession() {
|
|
323
|
+
const store = authContext.getStore();
|
|
324
|
+
if (!store?.user || !store?.session) return null;
|
|
325
|
+
return {
|
|
326
|
+
user: store.user,
|
|
327
|
+
session: store.session
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
function requireAuth(c) {
|
|
331
|
+
if (c) {
|
|
332
|
+
const user = c.get("user");
|
|
333
|
+
if (!user) {
|
|
334
|
+
const err = /* @__PURE__ */ new Error("Unauthorized");
|
|
335
|
+
err.status = 401;
|
|
336
|
+
throw err;
|
|
337
|
+
}
|
|
338
|
+
return user;
|
|
339
|
+
}
|
|
340
|
+
const user = getUser();
|
|
341
|
+
if (!user) {
|
|
342
|
+
const err = /* @__PURE__ */ new Error("Unauthorized");
|
|
343
|
+
err.status = 401;
|
|
344
|
+
throw err;
|
|
345
|
+
}
|
|
346
|
+
return user;
|
|
347
|
+
}
|
|
348
|
+
function createAuthClient(basePath = "/api/auth") {
|
|
349
|
+
async function authFetch(path, init) {
|
|
350
|
+
const res = await fetch(`${basePath}${path}`, {
|
|
351
|
+
credentials: "include",
|
|
352
|
+
headers: {
|
|
353
|
+
"content-type": "application/json",
|
|
354
|
+
...init?.headers
|
|
355
|
+
},
|
|
356
|
+
...init
|
|
357
|
+
});
|
|
358
|
+
if (!res.ok) throw await res.json().catch(() => ({ message: res.statusText }));
|
|
359
|
+
return await res.json().catch(() => null);
|
|
360
|
+
}
|
|
361
|
+
function buildFetchOptions(body) {
|
|
362
|
+
return {
|
|
363
|
+
method: "POST",
|
|
364
|
+
body: body ? JSON.stringify(body) : void 0
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
return {
|
|
368
|
+
signIn: {
|
|
369
|
+
email: async ({ email, password, callbackURL, rememberMe }) => {
|
|
370
|
+
try {
|
|
371
|
+
const data = await authFetch("/sign-in/email", buildFetchOptions({
|
|
372
|
+
email,
|
|
373
|
+
password,
|
|
374
|
+
rememberMe
|
|
375
|
+
}));
|
|
376
|
+
if (callbackURL && typeof window !== "undefined") window.location.href = callbackURL;
|
|
377
|
+
return { data };
|
|
378
|
+
} catch (error) {
|
|
379
|
+
return { error };
|
|
380
|
+
}
|
|
381
|
+
},
|
|
382
|
+
social: (provider, opts) => {
|
|
383
|
+
if (typeof window === "undefined") return Promise.resolve();
|
|
384
|
+
const redirect = opts?.callbackURL || window.location.href;
|
|
385
|
+
window.location.href = `${basePath}/sign-in/social/${provider}?callbackURL=${encodeURIComponent(redirect)}`;
|
|
386
|
+
return Promise.resolve();
|
|
387
|
+
}
|
|
388
|
+
},
|
|
389
|
+
signUp: { email: async ({ email, password, name, callbackURL }) => {
|
|
390
|
+
try {
|
|
391
|
+
const data = await authFetch("/sign-up/email", buildFetchOptions({
|
|
392
|
+
email,
|
|
393
|
+
password,
|
|
394
|
+
name
|
|
395
|
+
}));
|
|
396
|
+
if (callbackURL && typeof window !== "undefined") window.location.href = callbackURL;
|
|
397
|
+
return { data };
|
|
398
|
+
} catch (error) {
|
|
399
|
+
return { error };
|
|
400
|
+
}
|
|
401
|
+
} },
|
|
402
|
+
signOut: async () => {
|
|
403
|
+
try {
|
|
404
|
+
return { data: await authFetch("/sign-out", buildFetchOptions()) };
|
|
405
|
+
} catch (error) {
|
|
406
|
+
return { error };
|
|
407
|
+
}
|
|
408
|
+
},
|
|
409
|
+
getSession: async () => {
|
|
410
|
+
try {
|
|
411
|
+
return await authFetch("/get-session");
|
|
412
|
+
} catch {
|
|
413
|
+
return null;
|
|
414
|
+
}
|
|
415
|
+
},
|
|
416
|
+
sendVerificationEmail: async (email, opts) => {
|
|
417
|
+
try {
|
|
418
|
+
return { data: await authFetch("/send-verification-email", buildFetchOptions({
|
|
419
|
+
email,
|
|
420
|
+
...opts
|
|
421
|
+
})) };
|
|
422
|
+
} catch (error) {
|
|
423
|
+
return { error };
|
|
424
|
+
}
|
|
425
|
+
},
|
|
426
|
+
resetPassword: async (newPassword, token) => {
|
|
427
|
+
try {
|
|
428
|
+
return { data: await authFetch("/reset-password", buildFetchOptions({
|
|
429
|
+
newPassword,
|
|
430
|
+
token
|
|
431
|
+
})) };
|
|
432
|
+
} catch (error) {
|
|
433
|
+
return { error };
|
|
434
|
+
}
|
|
435
|
+
},
|
|
436
|
+
forgetPassword: async (email, opts) => {
|
|
437
|
+
try {
|
|
438
|
+
return { data: await authFetch("/forget-password", buildFetchOptions({
|
|
439
|
+
email,
|
|
440
|
+
...opts
|
|
441
|
+
})) };
|
|
442
|
+
} catch (error) {
|
|
443
|
+
return { error };
|
|
444
|
+
}
|
|
445
|
+
},
|
|
446
|
+
updateUser: async (data) => {
|
|
447
|
+
try {
|
|
448
|
+
return { data: (await authFetch("/update-user", buildFetchOptions(data))).user };
|
|
449
|
+
} catch (error) {
|
|
450
|
+
return { error };
|
|
451
|
+
}
|
|
452
|
+
},
|
|
453
|
+
changeEmail: async (newEmail, callbackURL) => {
|
|
454
|
+
try {
|
|
455
|
+
return { data: await authFetch("/change-email", buildFetchOptions({
|
|
456
|
+
newEmail,
|
|
457
|
+
callbackURL
|
|
458
|
+
})) };
|
|
459
|
+
} catch (error) {
|
|
460
|
+
return { error };
|
|
461
|
+
}
|
|
462
|
+
},
|
|
463
|
+
changePassword: async (currentPassword, newPassword, revokeOtherSessions) => {
|
|
464
|
+
try {
|
|
465
|
+
return { data: await authFetch("/change-password", buildFetchOptions({
|
|
466
|
+
currentPassword,
|
|
467
|
+
newPassword,
|
|
468
|
+
revokeOtherSessions
|
|
469
|
+
})) };
|
|
470
|
+
} catch (error) {
|
|
471
|
+
return { error };
|
|
472
|
+
}
|
|
473
|
+
},
|
|
474
|
+
listSessions: async () => {
|
|
475
|
+
try {
|
|
476
|
+
return { data: (await authFetch("/list-sessions")).sessions };
|
|
477
|
+
} catch (error) {
|
|
478
|
+
return { error };
|
|
479
|
+
}
|
|
480
|
+
},
|
|
481
|
+
revokeSession: async (sessionId) => {
|
|
482
|
+
try {
|
|
483
|
+
return { data: await authFetch("/revoke-session", buildFetchOptions({ sessionId })) };
|
|
484
|
+
} catch (error) {
|
|
485
|
+
return { error };
|
|
486
|
+
}
|
|
487
|
+
},
|
|
488
|
+
revokeSessions: async () => {
|
|
489
|
+
try {
|
|
490
|
+
return { data: await authFetch("/revoke-sessions", buildFetchOptions()) };
|
|
491
|
+
} catch (error) {
|
|
492
|
+
return { error };
|
|
493
|
+
}
|
|
494
|
+
},
|
|
495
|
+
$fetch: (input, init) => fetch(input, {
|
|
496
|
+
credentials: "include",
|
|
497
|
+
...init
|
|
498
|
+
})
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
async function getServerSession(req) {
|
|
502
|
+
if (!authInstance.handler) createAuthHandler();
|
|
503
|
+
await new Promise((resolve) => {
|
|
504
|
+
if (authInstance.handler) resolve();
|
|
505
|
+
else setTimeout(() => resolve(), 100);
|
|
506
|
+
});
|
|
507
|
+
const current = authContext.getStore();
|
|
508
|
+
if (current?.user && current?.session) return {
|
|
509
|
+
session: current.session,
|
|
510
|
+
user: current.user
|
|
511
|
+
};
|
|
512
|
+
if (req && authInstance.api?.getSession) try {
|
|
513
|
+
return await authInstance.api.getSession(req.headers);
|
|
514
|
+
} catch {
|
|
515
|
+
return null;
|
|
516
|
+
}
|
|
517
|
+
return null;
|
|
518
|
+
}
|
|
519
|
+
//#endregion
|
|
520
|
+
export { authMiddleware, createAuthClient, createAuthHandler, defineAuth, getServerSession, getSession, getUser, requireAuth, resolveAuthOptions };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { a as AuthState, c as ResolvedAuthOptions, d as UbeanAuthOptions, f as UseAuthReturn, i as AuthSession, l as Session, m as Verification, n as AuthClient, o as AuthUser, p as User, r as AuthError, s as BetterAuthOptions, t as Account, u as SocialProviderConfig } from "./types-DlL9lr7A.js";
|
|
2
|
+
import { authMiddleware, createAuthClient, createAuthHandler, defineAuth, getServerSession, getSession, getUser, requireAuth, resolveAuthOptions } from "./core.js";
|
|
3
|
+
import ubeanAuthPlugin, { defineAuthConfig } from "./vite.js";
|
|
4
|
+
import { getSessionFromHeaders, protectRoute, useAuth, useSession } from "./runtime.js";
|
|
5
|
+
export { type Account, type AuthClient, type AuthError, type AuthSession, type AuthState, type AuthUser, type BetterAuthOptions as BetterAuthConfig, type BetterAuthOptions, type ResolvedAuthOptions, type Session, type SocialProviderConfig, type UbeanAuthOptions, type UseAuthReturn, type User, type Verification, authMiddleware, createAuthClient, createAuthHandler, defineAuth, defineAuthConfig, getSession as getAuthSession, getServerSession, getSessionFromHeaders, getUser, protectRoute, requireAuth, resolveAuthOptions, ubeanAuthPlugin, useAuth, useSession };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { authMiddleware, createAuthClient, createAuthHandler, defineAuth, getServerSession, getSession, getUser, requireAuth, resolveAuthOptions } from "./core.js";
|
|
2
|
+
import ubeanAuthPlugin, { defineAuthConfig } from "./vite.js";
|
|
3
|
+
import { getSessionFromHeaders, protectRoute, useAuth, useSession } from "./runtime.js";
|
|
4
|
+
export { authMiddleware, createAuthClient, createAuthHandler, defineAuth, defineAuthConfig, getSession as getAuthSession, getServerSession, getSessionFromHeaders, getUser, protectRoute, requireAuth, resolveAuthOptions, ubeanAuthPlugin, useAuth, useSession };
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { f as UseAuthReturn, i as AuthSession, n as AuthClient, p as User, r as AuthError } from "./types-DlL9lr7A.js";
|
|
2
|
+
import { createAuthClient } from "./core.js";
|
|
3
|
+
//#region src/runtime.d.ts
|
|
4
|
+
declare function useAuth(basePath?: string): UseAuthReturn;
|
|
5
|
+
declare function useSession(basePath?: string): {
|
|
6
|
+
data: import("vue").Ref<{
|
|
7
|
+
session: {
|
|
8
|
+
id: string;
|
|
9
|
+
createdAt: Date;
|
|
10
|
+
updatedAt: Date;
|
|
11
|
+
userId: string;
|
|
12
|
+
expiresAt: Date;
|
|
13
|
+
token: string;
|
|
14
|
+
ipAddress?: string | null | undefined;
|
|
15
|
+
userAgent?: string | null | undefined;
|
|
16
|
+
};
|
|
17
|
+
user: {
|
|
18
|
+
id: string;
|
|
19
|
+
createdAt: Date;
|
|
20
|
+
updatedAt: Date;
|
|
21
|
+
email: string;
|
|
22
|
+
emailVerified: boolean;
|
|
23
|
+
name: string;
|
|
24
|
+
image?: string | null | undefined;
|
|
25
|
+
};
|
|
26
|
+
} | null, AuthSession | {
|
|
27
|
+
session: {
|
|
28
|
+
id: string;
|
|
29
|
+
createdAt: Date;
|
|
30
|
+
updatedAt: Date;
|
|
31
|
+
userId: string;
|
|
32
|
+
expiresAt: Date;
|
|
33
|
+
token: string;
|
|
34
|
+
ipAddress?: string | null | undefined;
|
|
35
|
+
userAgent?: string | null | undefined;
|
|
36
|
+
};
|
|
37
|
+
user: {
|
|
38
|
+
id: string;
|
|
39
|
+
createdAt: Date;
|
|
40
|
+
updatedAt: Date;
|
|
41
|
+
email: string;
|
|
42
|
+
emailVerified: boolean;
|
|
43
|
+
name: string;
|
|
44
|
+
image?: string | null | undefined;
|
|
45
|
+
};
|
|
46
|
+
} | null>;
|
|
47
|
+
isPending: import("vue").Ref<boolean, boolean>;
|
|
48
|
+
error: import("vue").Ref<{
|
|
49
|
+
message: string;
|
|
50
|
+
code?: string | undefined;
|
|
51
|
+
statusCode?: number | undefined;
|
|
52
|
+
} | null, AuthError | {
|
|
53
|
+
message: string;
|
|
54
|
+
code?: string | undefined;
|
|
55
|
+
statusCode?: number | undefined;
|
|
56
|
+
} | null>;
|
|
57
|
+
refetch: () => Promise<void>;
|
|
58
|
+
};
|
|
59
|
+
declare function getSessionFromHeaders(headers: Headers, basePath?: string): Promise<AuthSession | null>;
|
|
60
|
+
declare function protectRoute(redirectTo?: string): void;
|
|
61
|
+
//#endregion
|
|
62
|
+
export { type AuthClient, type AuthError, type AuthSession, type UseAuthReturn, type User, createAuthClient, getSessionFromHeaders, protectRoute, useAuth, useSession };
|
package/dist/runtime.js
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { createAuthClient } from "./core.js";
|
|
2
|
+
import { computed, onMounted, ref } from "vue";
|
|
3
|
+
//#region src/runtime.ts
|
|
4
|
+
function useAuth(basePath = "/api/auth") {
|
|
5
|
+
const client = createAuthClient(basePath);
|
|
6
|
+
const session = ref(null);
|
|
7
|
+
const isLoading = ref(false);
|
|
8
|
+
const isPending = ref(true);
|
|
9
|
+
const error = ref(null);
|
|
10
|
+
const user = computed(() => session.value?.user || null);
|
|
11
|
+
const isAuthenticated = computed(() => !!session.value?.user);
|
|
12
|
+
async function fetchSession() {
|
|
13
|
+
if (typeof window === "undefined") return;
|
|
14
|
+
isLoading.value = true;
|
|
15
|
+
isPending.value = true;
|
|
16
|
+
error.value = null;
|
|
17
|
+
try {
|
|
18
|
+
const result = await client.getSession();
|
|
19
|
+
session.value = result;
|
|
20
|
+
} catch (err) {
|
|
21
|
+
session.value = null;
|
|
22
|
+
error.value = err;
|
|
23
|
+
} finally {
|
|
24
|
+
isLoading.value = false;
|
|
25
|
+
isPending.value = false;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
const signIn = {
|
|
29
|
+
email: async ({ email, password, callbackURL }) => {
|
|
30
|
+
isLoading.value = true;
|
|
31
|
+
try {
|
|
32
|
+
const result = await client.signIn.email({
|
|
33
|
+
email,
|
|
34
|
+
password,
|
|
35
|
+
callbackURL
|
|
36
|
+
});
|
|
37
|
+
if (result.data) {
|
|
38
|
+
session.value = result.data;
|
|
39
|
+
if (callbackURL && typeof window !== "undefined") window.location.href = callbackURL;
|
|
40
|
+
}
|
|
41
|
+
if (result.error) error.value = result.error;
|
|
42
|
+
return result;
|
|
43
|
+
} finally {
|
|
44
|
+
isLoading.value = false;
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
social: (provider, opts) => {
|
|
48
|
+
return client.signIn.social(provider, opts);
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
const signUp = { email: async ({ email, password, name, callbackURL }) => {
|
|
52
|
+
isLoading.value = true;
|
|
53
|
+
try {
|
|
54
|
+
const result = await client.signUp.email({
|
|
55
|
+
email,
|
|
56
|
+
password,
|
|
57
|
+
name,
|
|
58
|
+
callbackURL
|
|
59
|
+
});
|
|
60
|
+
if (result.data) {
|
|
61
|
+
session.value = result.data;
|
|
62
|
+
if (callbackURL && typeof window !== "undefined") window.location.href = callbackURL;
|
|
63
|
+
}
|
|
64
|
+
if (result.error) error.value = result.error;
|
|
65
|
+
return result;
|
|
66
|
+
} finally {
|
|
67
|
+
isLoading.value = false;
|
|
68
|
+
}
|
|
69
|
+
} };
|
|
70
|
+
async function signOut() {
|
|
71
|
+
isLoading.value = true;
|
|
72
|
+
try {
|
|
73
|
+
const result = await client.signOut();
|
|
74
|
+
session.value = null;
|
|
75
|
+
return result;
|
|
76
|
+
} finally {
|
|
77
|
+
isLoading.value = false;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
async function refreshSession() {
|
|
81
|
+
await fetchSession();
|
|
82
|
+
}
|
|
83
|
+
onMounted(() => {
|
|
84
|
+
fetchSession();
|
|
85
|
+
if (typeof window !== "undefined") {
|
|
86
|
+
window.addEventListener("focus", fetchSession);
|
|
87
|
+
document.addEventListener("visibilitychange", () => {
|
|
88
|
+
if (document.visibilityState === "visible") fetchSession();
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
return {
|
|
93
|
+
session,
|
|
94
|
+
user,
|
|
95
|
+
isLoading,
|
|
96
|
+
isPending,
|
|
97
|
+
isAuthenticated,
|
|
98
|
+
error,
|
|
99
|
+
signIn,
|
|
100
|
+
signUp,
|
|
101
|
+
signOut,
|
|
102
|
+
getSession: client.getSession,
|
|
103
|
+
updateUser: client.updateUser,
|
|
104
|
+
refreshSession
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
function useSession(basePath = "/api/auth") {
|
|
108
|
+
const data = ref(null);
|
|
109
|
+
const isPending = ref(true);
|
|
110
|
+
const error = ref(null);
|
|
111
|
+
const client = createAuthClient(basePath);
|
|
112
|
+
const refetch = async () => {
|
|
113
|
+
isPending.value = true;
|
|
114
|
+
error.value = null;
|
|
115
|
+
try {
|
|
116
|
+
data.value = await client.getSession();
|
|
117
|
+
} catch (err) {
|
|
118
|
+
data.value = null;
|
|
119
|
+
error.value = err;
|
|
120
|
+
} finally {
|
|
121
|
+
isPending.value = false;
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
onMounted(refetch);
|
|
125
|
+
if (typeof window !== "undefined") {
|
|
126
|
+
window.addEventListener("focus", refetch);
|
|
127
|
+
document.addEventListener("visibilitychange", () => {
|
|
128
|
+
if (document.visibilityState === "visible") refetch();
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
return {
|
|
132
|
+
data,
|
|
133
|
+
isPending,
|
|
134
|
+
error,
|
|
135
|
+
refetch
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
function getSessionFromHeaders(headers, basePath = "/api/auth") {
|
|
139
|
+
return fetch(`${basePath}/get-session`, {
|
|
140
|
+
headers: { cookie: headers.get("cookie") || "" },
|
|
141
|
+
credentials: "include"
|
|
142
|
+
}).then((r) => r.json()).then((data) => {
|
|
143
|
+
if (data?.session && data?.user) return data;
|
|
144
|
+
return null;
|
|
145
|
+
}).catch(() => null);
|
|
146
|
+
}
|
|
147
|
+
function protectRoute(redirectTo = "/login") {
|
|
148
|
+
const auth = useAuth();
|
|
149
|
+
if (typeof window !== "undefined" && !auth.isPending.value && !auth.isAuthenticated.value) {
|
|
150
|
+
const redirectUrl = `${redirectTo}?redirect=${encodeURIComponent(window.location.pathname)}`;
|
|
151
|
+
window.location.href = redirectUrl;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
//#endregion
|
|
155
|
+
export { createAuthClient, getSessionFromHeaders, protectRoute, useAuth, useSession };
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import { Account, BetterAuthOptions as BetterAuthOptions$1, Session, User, Verification } from "better-auth";
|
|
2
|
+
//#region src/types.d.ts
|
|
3
|
+
interface AuthUser {
|
|
4
|
+
id: string;
|
|
5
|
+
email: string;
|
|
6
|
+
emailVerified: boolean;
|
|
7
|
+
name: string;
|
|
8
|
+
image?: string | null;
|
|
9
|
+
createdAt: string | Date;
|
|
10
|
+
updatedAt: string | Date;
|
|
11
|
+
[key: string]: unknown;
|
|
12
|
+
}
|
|
13
|
+
interface AuthState {
|
|
14
|
+
session: Session;
|
|
15
|
+
user: AuthUser;
|
|
16
|
+
}
|
|
17
|
+
interface UbeanAuthOptions {
|
|
18
|
+
enabled?: boolean;
|
|
19
|
+
basePath?: string;
|
|
20
|
+
baseURL?: string;
|
|
21
|
+
secret?: string;
|
|
22
|
+
betterAuth?: Omit<BetterAuthOptions$1, 'baseURL' | 'basePath' | 'trustedOrigins'> | ((ctx: {
|
|
23
|
+
defaults: BetterAuthOptions$1;
|
|
24
|
+
}) => BetterAuthOptions$1);
|
|
25
|
+
clientOptions?: {
|
|
26
|
+
fetchOptions?: Record<string, unknown>;
|
|
27
|
+
plugins?: Array<{
|
|
28
|
+
id: string;
|
|
29
|
+
[key: string]: unknown;
|
|
30
|
+
}>;
|
|
31
|
+
};
|
|
32
|
+
redirectTo?: {
|
|
33
|
+
login?: string;
|
|
34
|
+
signup?: string;
|
|
35
|
+
callback?: string;
|
|
36
|
+
};
|
|
37
|
+
session?: {
|
|
38
|
+
cookieName?: string;
|
|
39
|
+
expiresIn?: number;
|
|
40
|
+
updateAge?: number;
|
|
41
|
+
};
|
|
42
|
+
socialProviders?: Record<string, SocialProviderConfig>;
|
|
43
|
+
database?: BetterAuthOptions$1['database'];
|
|
44
|
+
}
|
|
45
|
+
interface SocialProviderConfig {
|
|
46
|
+
clientId: string;
|
|
47
|
+
clientSecret: string;
|
|
48
|
+
redirectURI?: string;
|
|
49
|
+
[key: string]: unknown;
|
|
50
|
+
}
|
|
51
|
+
interface ResolvedAuthOptions extends Required<Omit<UbeanAuthOptions, 'betterAuth' | 'socialProviders' | 'database'>> {
|
|
52
|
+
enabled: boolean;
|
|
53
|
+
basePath: string;
|
|
54
|
+
baseURL: string;
|
|
55
|
+
secret: string;
|
|
56
|
+
clientOptions: {
|
|
57
|
+
fetchOptions: Record<string, unknown>;
|
|
58
|
+
plugins: Array<{
|
|
59
|
+
id: string;
|
|
60
|
+
[key: string]: unknown;
|
|
61
|
+
}>;
|
|
62
|
+
};
|
|
63
|
+
redirectTo: {
|
|
64
|
+
login: string;
|
|
65
|
+
signup: string;
|
|
66
|
+
callback: string;
|
|
67
|
+
};
|
|
68
|
+
session: {
|
|
69
|
+
cookieName: string;
|
|
70
|
+
expiresIn: number;
|
|
71
|
+
updateAge: number;
|
|
72
|
+
};
|
|
73
|
+
betterAuth?: BetterAuthOptions$1;
|
|
74
|
+
database?: BetterAuthOptions$1['database'];
|
|
75
|
+
socialProviders?: Record<string, SocialProviderConfig>;
|
|
76
|
+
}
|
|
77
|
+
interface AuthSession {
|
|
78
|
+
session: Session;
|
|
79
|
+
user: User;
|
|
80
|
+
}
|
|
81
|
+
interface AuthClient {
|
|
82
|
+
signIn: {
|
|
83
|
+
email: (credentials: {
|
|
84
|
+
email: string;
|
|
85
|
+
password: string;
|
|
86
|
+
callbackURL?: string;
|
|
87
|
+
rememberMe?: boolean;
|
|
88
|
+
}) => Promise<{
|
|
89
|
+
data?: AuthSession;
|
|
90
|
+
error?: AuthError;
|
|
91
|
+
}>;
|
|
92
|
+
social: (provider: string, opts?: {
|
|
93
|
+
callbackURL?: string;
|
|
94
|
+
}) => Promise<void>;
|
|
95
|
+
};
|
|
96
|
+
signUp: {
|
|
97
|
+
email: (credentials: {
|
|
98
|
+
email: string;
|
|
99
|
+
password: string;
|
|
100
|
+
name: string;
|
|
101
|
+
callbackURL?: string;
|
|
102
|
+
}) => Promise<{
|
|
103
|
+
data?: AuthSession;
|
|
104
|
+
error?: AuthError;
|
|
105
|
+
}>;
|
|
106
|
+
};
|
|
107
|
+
signOut: () => Promise<{
|
|
108
|
+
data?: {
|
|
109
|
+
success: boolean;
|
|
110
|
+
};
|
|
111
|
+
error?: AuthError;
|
|
112
|
+
}>;
|
|
113
|
+
getSession: () => Promise<AuthSession | null>;
|
|
114
|
+
sendVerificationEmail: (email: string, opts?: {
|
|
115
|
+
callbackURL?: string;
|
|
116
|
+
}) => Promise<{
|
|
117
|
+
data?: {
|
|
118
|
+
status: boolean;
|
|
119
|
+
};
|
|
120
|
+
error?: AuthError;
|
|
121
|
+
}>;
|
|
122
|
+
resetPassword: (newPassword: string, token: string) => Promise<{
|
|
123
|
+
data?: {
|
|
124
|
+
status: boolean;
|
|
125
|
+
};
|
|
126
|
+
error?: AuthError;
|
|
127
|
+
}>;
|
|
128
|
+
forgetPassword: (email: string, opts?: {
|
|
129
|
+
redirectTo?: string;
|
|
130
|
+
}) => Promise<{
|
|
131
|
+
data?: {
|
|
132
|
+
status: boolean;
|
|
133
|
+
};
|
|
134
|
+
error?: AuthError;
|
|
135
|
+
}>;
|
|
136
|
+
updateUser: (data: Partial<User> & {
|
|
137
|
+
currentPassword?: string;
|
|
138
|
+
newPassword?: string;
|
|
139
|
+
}) => Promise<{
|
|
140
|
+
data?: User;
|
|
141
|
+
error?: AuthError;
|
|
142
|
+
}>;
|
|
143
|
+
changeEmail: (newEmail: string, callbackURL?: string) => Promise<{
|
|
144
|
+
data?: {
|
|
145
|
+
status: boolean;
|
|
146
|
+
};
|
|
147
|
+
error?: AuthError;
|
|
148
|
+
}>;
|
|
149
|
+
changePassword: (currentPassword: string, newPassword: string, revokeOtherSessions?: boolean) => Promise<{
|
|
150
|
+
data?: {
|
|
151
|
+
status: boolean;
|
|
152
|
+
};
|
|
153
|
+
error?: AuthError;
|
|
154
|
+
}>;
|
|
155
|
+
listSessions: () => Promise<{
|
|
156
|
+
data?: Session[];
|
|
157
|
+
error?: AuthError;
|
|
158
|
+
}>;
|
|
159
|
+
revokeSession: (sessionId: string) => Promise<{
|
|
160
|
+
data?: {
|
|
161
|
+
status: boolean;
|
|
162
|
+
};
|
|
163
|
+
error?: AuthError;
|
|
164
|
+
}>;
|
|
165
|
+
revokeSessions: () => Promise<{
|
|
166
|
+
data?: {
|
|
167
|
+
status: boolean;
|
|
168
|
+
};
|
|
169
|
+
error?: AuthError;
|
|
170
|
+
}>;
|
|
171
|
+
$fetch: typeof fetch;
|
|
172
|
+
}
|
|
173
|
+
interface AuthError {
|
|
174
|
+
message: string;
|
|
175
|
+
code?: string;
|
|
176
|
+
statusCode?: number;
|
|
177
|
+
}
|
|
178
|
+
interface UseAuthReturn {
|
|
179
|
+
session: import('vue').Ref<AuthSession | null>;
|
|
180
|
+
user: import('vue').ComputedRef<User | null>;
|
|
181
|
+
isLoading: import('vue').Ref<boolean>;
|
|
182
|
+
isPending: import('vue').Ref<boolean>;
|
|
183
|
+
isAuthenticated: import('vue').ComputedRef<boolean>;
|
|
184
|
+
error: import('vue').Ref<AuthError | null>;
|
|
185
|
+
signIn: {
|
|
186
|
+
email: (credentials: {
|
|
187
|
+
email: string;
|
|
188
|
+
password: string;
|
|
189
|
+
callbackURL?: string;
|
|
190
|
+
}) => Promise<{
|
|
191
|
+
data?: AuthSession;
|
|
192
|
+
error?: AuthError;
|
|
193
|
+
}>;
|
|
194
|
+
social: (provider: string, opts?: {
|
|
195
|
+
callbackURL?: string;
|
|
196
|
+
}) => Promise<void>;
|
|
197
|
+
};
|
|
198
|
+
signUp: {
|
|
199
|
+
email: (credentials: {
|
|
200
|
+
email: string;
|
|
201
|
+
password: string;
|
|
202
|
+
name: string;
|
|
203
|
+
callbackURL?: string;
|
|
204
|
+
}) => Promise<{
|
|
205
|
+
data?: AuthSession;
|
|
206
|
+
error?: AuthError;
|
|
207
|
+
}>;
|
|
208
|
+
};
|
|
209
|
+
signOut: () => Promise<{
|
|
210
|
+
data?: {
|
|
211
|
+
success: boolean;
|
|
212
|
+
};
|
|
213
|
+
error?: AuthError;
|
|
214
|
+
}>;
|
|
215
|
+
getSession: () => Promise<AuthSession | null>;
|
|
216
|
+
updateUser: AuthClient['updateUser'];
|
|
217
|
+
refreshSession: () => Promise<void>;
|
|
218
|
+
}
|
|
219
|
+
//#endregion
|
|
220
|
+
export { AuthState as a, ResolvedAuthOptions as c, UbeanAuthOptions as d, UseAuthReturn as f, AuthSession as i, Session as l, Verification as m, AuthClient as n, AuthUser as o, User as p, AuthError as r, BetterAuthOptions$1 as s, Account as t, SocialProviderConfig as u };
|
package/dist/vite.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { d as UbeanAuthOptions } from "./types-DlL9lr7A.js";
|
|
2
|
+
import { Plugin } from "vite";
|
|
3
|
+
//#region src/vite.d.ts
|
|
4
|
+
declare function ubeanAuthPlugin(userOptions?: UbeanAuthOptions): Plugin;
|
|
5
|
+
declare function defineAuthConfig(options: UbeanAuthOptions): UbeanAuthOptions;
|
|
6
|
+
//#endregion
|
|
7
|
+
export { ubeanAuthPlugin as default, ubeanAuthPlugin, defineAuthConfig };
|
package/dist/vite.js
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { resolveAuthOptions } from "./core.js";
|
|
2
|
+
import { consola } from "consola";
|
|
3
|
+
//#region src/vite.ts
|
|
4
|
+
const VIRTUAL_AUTH_CLIENT_ID = "virtual:ubean-auth/client";
|
|
5
|
+
const RESOLVED_VIRTUAL_AUTH_CLIENT_ID = `\0${VIRTUAL_AUTH_CLIENT_ID}`;
|
|
6
|
+
const VIRTUAL_AUTH_SERVER_ID = "virtual:ubean-auth/server";
|
|
7
|
+
const RESOLVED_VIRTUAL_AUTH_SERVER_ID = `\0${VIRTUAL_AUTH_SERVER_ID}`;
|
|
8
|
+
function ubeanAuthPlugin(userOptions = {}) {
|
|
9
|
+
const options = resolveAuthOptions(userOptions);
|
|
10
|
+
let authHandlerInstance = null;
|
|
11
|
+
return {
|
|
12
|
+
name: "ubean:auth",
|
|
13
|
+
enforce: "pre",
|
|
14
|
+
resolveId(id) {
|
|
15
|
+
if (id === VIRTUAL_AUTH_CLIENT_ID) return RESOLVED_VIRTUAL_AUTH_CLIENT_ID;
|
|
16
|
+
if (id === VIRTUAL_AUTH_SERVER_ID) return RESOLVED_VIRTUAL_AUTH_SERVER_ID;
|
|
17
|
+
return null;
|
|
18
|
+
},
|
|
19
|
+
load(id) {
|
|
20
|
+
if (id === RESOLVED_VIRTUAL_AUTH_CLIENT_ID) return generateClientCode(options);
|
|
21
|
+
if (id === RESOLVED_VIRTUAL_AUTH_SERVER_ID) return generateServerCode(options);
|
|
22
|
+
return null;
|
|
23
|
+
},
|
|
24
|
+
configureServer(server) {
|
|
25
|
+
if (!options.enabled) return;
|
|
26
|
+
server.middlewares.use((req, res, next) => {
|
|
27
|
+
const url = req.url || "";
|
|
28
|
+
if (!url.startsWith(options.basePath)) return next();
|
|
29
|
+
Promise.resolve().then(async () => {
|
|
30
|
+
if (!authHandlerInstance) {
|
|
31
|
+
const { createAuthHandler } = await import("./core.js");
|
|
32
|
+
authHandlerInstance = createAuthHandler(userOptions);
|
|
33
|
+
await authHandlerInstance.resolveAuth();
|
|
34
|
+
}
|
|
35
|
+
const fullUrl = `${server.config.server.https ? "https" : "http"}://${req.headers.host || "localhost"}${url}`;
|
|
36
|
+
const request = new Request(fullUrl, {
|
|
37
|
+
method: req.method,
|
|
38
|
+
headers: new Headers(req.headers),
|
|
39
|
+
body: req.method !== "GET" && req.method !== "HEAD" ? req : void 0,
|
|
40
|
+
duplex: "half"
|
|
41
|
+
});
|
|
42
|
+
const response = await authHandlerInstance.handler(request);
|
|
43
|
+
res.statusCode = response.status;
|
|
44
|
+
response.headers.forEach((value, key) => {
|
|
45
|
+
res.setHeader(key, value);
|
|
46
|
+
});
|
|
47
|
+
const text = await response.text();
|
|
48
|
+
res.end(text);
|
|
49
|
+
}).catch((error) => {
|
|
50
|
+
consola.error("[auth] Error handling auth request:", error);
|
|
51
|
+
res.statusCode = 500;
|
|
52
|
+
res.end(JSON.stringify({ error: "Internal auth error" }));
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
consola.success(`[auth] Better Auth routes mounted at ${options.basePath}/*`);
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
function generateClientCode(options) {
|
|
60
|
+
return `
|
|
61
|
+
const BASE_URL = ${JSON.stringify(options.basePath)};
|
|
62
|
+
|
|
63
|
+
async function authFetch(path, init = {}) {
|
|
64
|
+
const res = await fetch(BASE_URL + path, {
|
|
65
|
+
credentials: 'include',
|
|
66
|
+
headers: { 'content-type': 'application/json', ...(init.headers || {}) },
|
|
67
|
+
...init
|
|
68
|
+
});
|
|
69
|
+
if (!res.ok) {
|
|
70
|
+
let err = { message: res.statusText };
|
|
71
|
+
try { err = await res.json(); } catch (_) {}
|
|
72
|
+
throw err;
|
|
73
|
+
}
|
|
74
|
+
return res.json().catch(() => null);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function buildBody(body) {
|
|
78
|
+
return { method: 'POST', body: body ? JSON.stringify(body) : undefined };
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export const authClient = {
|
|
82
|
+
signIn: {
|
|
83
|
+
email: async ({ email, password, callbackURL, rememberMe }) => {
|
|
84
|
+
try {
|
|
85
|
+
const data = await authFetch('/sign-in/email', buildBody({ email, password, rememberMe }));
|
|
86
|
+
if (callbackURL && typeof window !== 'undefined') window.location.href = callbackURL;
|
|
87
|
+
return { data };
|
|
88
|
+
} catch (error) { return { error }; }
|
|
89
|
+
},
|
|
90
|
+
social: (provider, opts) => {
|
|
91
|
+
if (typeof window === 'undefined') return Promise.resolve();
|
|
92
|
+
const redirect = opts?.callbackURL || window.location.href;
|
|
93
|
+
window.location.href = BASE_URL + '/sign-in/social/' + provider + '?callbackURL=' + encodeURIComponent(redirect);
|
|
94
|
+
return Promise.resolve();
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
signUp: {
|
|
98
|
+
email: async ({ email, password, name, callbackURL }) => {
|
|
99
|
+
try {
|
|
100
|
+
const data = await authFetch('/sign-up/email', buildBody({ email, password, name }));
|
|
101
|
+
if (callbackURL && typeof window !== 'undefined') window.location.href = callbackURL;
|
|
102
|
+
return { data };
|
|
103
|
+
} catch (error) { return { error }; }
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
signOut: async () => {
|
|
107
|
+
try { const data = await authFetch('/sign-out', buildBody()); return { data }; }
|
|
108
|
+
catch (error) { return { error }; }
|
|
109
|
+
},
|
|
110
|
+
getSession: async () => {
|
|
111
|
+
try { return await authFetch('/get-session'); } catch (_) { return null; }
|
|
112
|
+
},
|
|
113
|
+
forgetPassword: async (email, opts) => {
|
|
114
|
+
try { const data = await authFetch('/forget-password', buildBody({ email, ...opts })); return { data }; }
|
|
115
|
+
catch (error) { return { error }; }
|
|
116
|
+
},
|
|
117
|
+
resetPassword: async (newPassword, token) => {
|
|
118
|
+
try { const data = await authFetch('/reset-password', buildBody({ newPassword, token })); return { data }; }
|
|
119
|
+
catch (error) { return { error }; }
|
|
120
|
+
},
|
|
121
|
+
updateUser: async (data) => {
|
|
122
|
+
try { const r = await authFetch('/update-user', buildBody(data)); return { data: r.user }; }
|
|
123
|
+
catch (error) { return { error }; }
|
|
124
|
+
},
|
|
125
|
+
changePassword: async (currentPassword, newPassword, revokeOtherSessions) => {
|
|
126
|
+
try { const data = await authFetch('/change-password', buildBody({ currentPassword, newPassword, revokeOtherSessions })); return { data }; }
|
|
127
|
+
catch (error) { return { error }; }
|
|
128
|
+
},
|
|
129
|
+
listSessions: async () => {
|
|
130
|
+
try { const d = await authFetch('/list-sessions'); return { data: d.sessions }; }
|
|
131
|
+
catch (error) { return { error }; }
|
|
132
|
+
},
|
|
133
|
+
revokeSession: async (sessionId) => {
|
|
134
|
+
try { const data = await authFetch('/revoke-session', buildBody({ sessionId })); return { data }; }
|
|
135
|
+
catch (error) { return { error }; }
|
|
136
|
+
},
|
|
137
|
+
revokeSessions: async () => {
|
|
138
|
+
try { const data = await authFetch('/revoke-sessions', buildBody()); return { data }; }
|
|
139
|
+
catch (error) { return { error }; }
|
|
140
|
+
},
|
|
141
|
+
$fetch: (input, init) => fetch(input, { credentials: 'include', ...init })
|
|
142
|
+
};
|
|
143
|
+
export default authClient;
|
|
144
|
+
`;
|
|
145
|
+
}
|
|
146
|
+
function generateServerCode(_options) {
|
|
147
|
+
return `
|
|
148
|
+
export { createAuthHandler, authMiddleware, getUser, getSession, requireAuth, getServerSession, defineAuth } from '@ubean/auth/core';
|
|
149
|
+
`;
|
|
150
|
+
}
|
|
151
|
+
function defineAuthConfig(options) {
|
|
152
|
+
return options;
|
|
153
|
+
}
|
|
154
|
+
//#endregion
|
|
155
|
+
export { ubeanAuthPlugin as default, ubeanAuthPlugin, defineAuthConfig };
|