@bwalletx/connect 0.2.0 → 0.4.1
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/BRAND.md +16 -0
- package/CHANGELOG.md +25 -0
- package/README.md +189 -4
- package/dist/bwalletx-connect.global.js +41 -3
- package/dist/bwalletx-connect.global.js.map +1 -1
- package/dist/bwalletx-shell.global.js +54 -0
- package/dist/bwalletx-shell.global.js.map +1 -0
- package/dist/chunk-7NAKOJGZ.js +442 -0
- package/dist/chunk-7NAKOJGZ.js.map +1 -0
- package/dist/chunk-FUQ46RJV.js +404 -0
- package/dist/chunk-FUQ46RJV.js.map +1 -0
- package/dist/chunk-OMEKHKMM.js +530 -0
- package/dist/chunk-OMEKHKMM.js.map +1 -0
- package/dist/index.cjs +425 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +23 -62
- package/dist/index.d.ts +23 -62
- package/dist/index.js +35 -1
- package/dist/index.js.map +1 -1
- package/dist/manifest-Caj_Raqm.d.cts +81 -0
- package/dist/manifest-Caj_Raqm.d.ts +81 -0
- package/dist/next.cjs +415 -0
- package/dist/next.cjs.map +1 -0
- package/dist/next.d.cts +48 -0
- package/dist/next.d.ts +48 -0
- package/dist/next.js +107 -0
- package/dist/next.js.map +1 -0
- package/dist/react.cjs +586 -36
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +74 -28
- package/dist/react.d.ts +74 -28
- package/dist/react.js +175 -3
- package/dist/react.js.map +1 -1
- package/dist/server.cjs +339 -4
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +204 -2
- package/dist/server.d.ts +204 -2
- package/dist/server.js +36 -107
- package/dist/server.js.map +1 -1
- package/dist/shell-react.cjs +361 -0
- package/dist/shell-react.cjs.map +1 -0
- package/dist/shell-react.d.cts +58 -0
- package/dist/shell-react.d.ts +58 -0
- package/dist/shell-react.js +52 -0
- package/dist/shell-react.js.map +1 -0
- package/dist/shell.cjs +578 -0
- package/dist/shell.cjs.map +1 -0
- package/dist/shell.d.cts +132 -0
- package/dist/shell.d.ts +132 -0
- package/dist/shell.js +51 -0
- package/dist/shell.js.map +1 -0
- package/dist/wallets-VOKIKBbO.d.cts +250 -0
- package/dist/wallets-VOKIKBbO.d.ts +250 -0
- package/package.json +65 -14
- package/schema/bapp.schema.json +95 -0
package/dist/next.js
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import {
|
|
2
|
+
IdentityLinkConflictError,
|
|
3
|
+
assertSecret,
|
|
4
|
+
createChallenge,
|
|
5
|
+
linkIdentity,
|
|
6
|
+
memoryStore,
|
|
7
|
+
originAllowed,
|
|
8
|
+
pgNonceTableSql,
|
|
9
|
+
pgStore,
|
|
10
|
+
readCookie,
|
|
11
|
+
redisStore,
|
|
12
|
+
serializeCookie,
|
|
13
|
+
signInOrLink,
|
|
14
|
+
signSession,
|
|
15
|
+
verifySession,
|
|
16
|
+
verifySignIn
|
|
17
|
+
} from "./chunk-7NAKOJGZ.js";
|
|
18
|
+
|
|
19
|
+
// src/next.ts
|
|
20
|
+
var json = (body2, status = 200, headers = {}) => new Response(JSON.stringify(body2), { status, headers: { "content-type": "application/json", "cache-control": "no-store", ...headers } });
|
|
21
|
+
async function body(req) {
|
|
22
|
+
try {
|
|
23
|
+
const b = await req.json();
|
|
24
|
+
return b && typeof b === "object" ? b : null;
|
|
25
|
+
} catch {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function createBwalletXAuth(o) {
|
|
30
|
+
if (!o.store) throw new Error("createBwalletXAuth needs a nonce store (redisStore, pgStore; memoryStore for dev)");
|
|
31
|
+
const cookieName = o.cookieName ?? "bwx_session";
|
|
32
|
+
const maxAge = o.maxAge ?? 7 * 24 * 3600;
|
|
33
|
+
const secure = o.secureCookie ?? o.origin.startsWith("https:");
|
|
34
|
+
const secret = () => {
|
|
35
|
+
const s = o.secret ?? (typeof process !== "undefined" ? process.env?.[o.secretEnv ?? "BWALLETX_SESSION_SECRET"] : void 0);
|
|
36
|
+
assertSecret(s);
|
|
37
|
+
return s;
|
|
38
|
+
};
|
|
39
|
+
const cookie = (v, age) => serializeCookie(v, { name: cookieName, maxAge: age, secure, sameSite: o.sameSite, domain: o.cookieDomain });
|
|
40
|
+
const badOrigin = (req) => !originAllowed(req.headers.get("origin"), o.origin);
|
|
41
|
+
const fromSource = async (source) => {
|
|
42
|
+
if (typeof source === "string") return readCookie(source, cookieName);
|
|
43
|
+
if (source instanceof Headers) return readCookie(source.get("cookie"), cookieName);
|
|
44
|
+
if (source && typeof source.headers?.get === "function") return readCookie(source.headers.get("cookie"), cookieName);
|
|
45
|
+
const { cookies } = await import("next/headers");
|
|
46
|
+
const jar = await cookies();
|
|
47
|
+
return jar.get(cookieName)?.value ?? null;
|
|
48
|
+
};
|
|
49
|
+
const auth = {
|
|
50
|
+
async challenge(req) {
|
|
51
|
+
secret();
|
|
52
|
+
if (badOrigin(req)) return json({ error: "origin not allowed" }, 403);
|
|
53
|
+
const b = await body(req);
|
|
54
|
+
try {
|
|
55
|
+
return json(await createChallenge({ origin: o.origin, identityKey: b?.identityKey, store: o.store }));
|
|
56
|
+
} catch (e) {
|
|
57
|
+
return json({ error: e.message }, 400);
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
async verify(req) {
|
|
61
|
+
const key = secret();
|
|
62
|
+
if (badOrigin(req)) return json({ error: "origin not allowed" }, 403);
|
|
63
|
+
const b = await body(req);
|
|
64
|
+
const identityKey = await verifySignIn({ origin: o.origin, identityKey: b?.identityKey, nonce: b?.nonce, signature: b?.signature, store: o.store });
|
|
65
|
+
if (!identityKey) return json({ error: "sign-in failed" }, 401);
|
|
66
|
+
let extra = {};
|
|
67
|
+
try {
|
|
68
|
+
const r = await o.onVerified?.(identityKey, req);
|
|
69
|
+
if (r === false) return json({ error: "not allowed" }, 403);
|
|
70
|
+
if (r) extra = r;
|
|
71
|
+
} catch (e) {
|
|
72
|
+
if (e instanceof IdentityLinkConflictError) return json({ error: e.message, code: e.code }, 409);
|
|
73
|
+
throw e;
|
|
74
|
+
}
|
|
75
|
+
const token = await signSession({ ...extra, sub: identityKey }, { secret: key, maxAge });
|
|
76
|
+
return json({ identityKey, uid: extra.uid, handle: extra.handle, paymail: extra.paymail }, 200, { "set-cookie": cookie(token, maxAge) });
|
|
77
|
+
},
|
|
78
|
+
async logout(req) {
|
|
79
|
+
if (badOrigin(req)) return json({ error: "origin not allowed" }, 403);
|
|
80
|
+
return json({ ok: true }, 200, { "set-cookie": cookie("", 0) });
|
|
81
|
+
},
|
|
82
|
+
async session(req) {
|
|
83
|
+
const s = await auth.getSession(req);
|
|
84
|
+
return s ? json({ identityKey: s.sub, uid: s.uid, handle: s.handle, paymail: s.paymail, exp: s.exp }) : json({ identityKey: null }, 200);
|
|
85
|
+
},
|
|
86
|
+
async getSession(source) {
|
|
87
|
+
const key = secret();
|
|
88
|
+
return verifySession(await fromSource(source), { secret: key });
|
|
89
|
+
},
|
|
90
|
+
async sessionCookie(claims) {
|
|
91
|
+
return cookie(await signSession(claims, { secret: secret(), maxAge }), maxAge);
|
|
92
|
+
},
|
|
93
|
+
clearCookie: () => cookie("", 0)
|
|
94
|
+
};
|
|
95
|
+
return auth;
|
|
96
|
+
}
|
|
97
|
+
export {
|
|
98
|
+
IdentityLinkConflictError,
|
|
99
|
+
createBwalletXAuth,
|
|
100
|
+
linkIdentity,
|
|
101
|
+
memoryStore,
|
|
102
|
+
pgNonceTableSql,
|
|
103
|
+
pgStore,
|
|
104
|
+
redisStore,
|
|
105
|
+
signInOrLink
|
|
106
|
+
};
|
|
107
|
+
//# sourceMappingURL=next.js.map
|
package/dist/next.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/next.ts"],"sourcesContent":["/**\n * Next.js App Router adapter. Route handlers use standard Request/Response, so they also work in\n * any Fetch-API server (Hono, Remix, Bun, Workers).\n *\n * // lib/bwalletx.ts\n * export const auth = createBwalletXAuth({ origin: process.env.APP_ORIGIN!, store: pgStore({ query }) });\n * // app/api/bwalletx/challenge/route.ts → export const POST = auth.challenge;\n * // app/api/bwalletx/verify/route.ts → export const POST = auth.verify;\n * // app/api/bwalletx/logout/route.ts → export const POST = auth.logout;\n * // app/api/bwalletx/session/route.ts → export const GET = auth.session;\n * // server component: const s = await auth.getSession();\n */\nimport { IdentityLinkConflictError } from './link.js';\nimport { createChallenge, originAllowed, verifySignIn, type NonceStore } from './server.js';\nimport { assertSecret, readCookie, serializeCookie, signSession, verifySession, type SessionPayload } from './session.js';\n\nexport type { SessionPayload } from './session.js';\n\nexport interface VerifiedExtra {\n /** Your user id (e.g. from signInOrLink). Stored in the session as `uid`. */\n uid?: string;\n handle?: string;\n paymail?: string;\n [claim: string]: unknown;\n}\n\nexport interface BwalletXAuthOptions {\n /** YOUR origin from config, e.g. \"https://example.com\". Never from the request. */\n origin: string;\n /** A shared nonce store: redisStore or pgStore. memoryStore only in development. */\n store: NonceStore;\n /** HMAC secret, 32+ chars. Default: process.env[secretEnv]. There is no fallback; requests throw without it. */\n secret?: string;\n /** Env var holding the secret. Default 'BWALLETX_SESSION_SECRET'. */\n secretEnv?: string;\n /** Cookie name. Default 'bwx_session'. */\n cookieName?: string;\n /** Session lifetime in seconds. Default 7 days. */\n maxAge?: number;\n /** Default: true when origin is https. */\n secureCookie?: boolean;\n sameSite?: 'Lax' | 'Strict' | 'None';\n cookieDomain?: string;\n /**\n * Runs after the signature is verified, before the cookie is set: link to your user, look up a\n * handle. Throw IdentityLinkConflictError to answer 409; return false to refuse (403).\n */\n onVerified?: (identityKey: string, req: Request) => Promise<VerifiedExtra | void | false> | VerifiedExtra | void | false;\n}\n\nexport interface BwalletXAuth {\n challenge(req: Request): Promise<Response>;\n verify(req: Request): Promise<Response>;\n logout(req: Request): Promise<Response>;\n session(req: Request): Promise<Response>;\n /** The session, or null. With no argument it reads cookies() from next/headers. */\n getSession(source?: Request | Headers | string | null): Promise<SessionPayload | null>;\n /** Make a cookie for an identity you verified yourself (e.g. after account linking elsewhere). */\n sessionCookie(claims: Omit<SessionPayload, 'iat' | 'exp'>): Promise<string>;\n clearCookie(): string;\n}\n\nconst json = (body: unknown, status = 200, headers: Record<string, string> = {}) =>\n new Response(JSON.stringify(body), { status, headers: { 'content-type': 'application/json', 'cache-control': 'no-store', ...headers } });\n\nasync function body(req: Request): Promise<Record<string, unknown> | null> {\n try {\n const b = await req.json();\n return b && typeof b === 'object' ? (b as Record<string, unknown>) : null;\n } catch {\n return null;\n }\n}\n\nexport function createBwalletXAuth(o: BwalletXAuthOptions): BwalletXAuth {\n if (!o.store) throw new Error('createBwalletXAuth needs a nonce store (redisStore, pgStore; memoryStore for dev)');\n const cookieName = o.cookieName ?? 'bwx_session';\n const maxAge = o.maxAge ?? 7 * 24 * 3600;\n const secure = o.secureCookie ?? o.origin.startsWith('https:');\n const secret = () => {\n const s = o.secret ?? (typeof process !== 'undefined' ? process.env?.[o.secretEnv ?? 'BWALLETX_SESSION_SECRET'] : undefined);\n assertSecret(s);\n return s;\n };\n const cookie = (v: string, age: number) => serializeCookie(v, { name: cookieName, maxAge: age, secure, sameSite: o.sameSite, domain: o.cookieDomain });\n const badOrigin = (req: Request) => !originAllowed(req.headers.get('origin'), o.origin);\n\n const fromSource = async (source?: Request | Headers | string | null): Promise<string | null> => {\n if (typeof source === 'string') return readCookie(source, cookieName);\n if (source instanceof Headers) return readCookie(source.get('cookie'), cookieName);\n if (source && typeof (source as Request).headers?.get === 'function') return readCookie((source as Request).headers.get('cookie'), cookieName);\n // Server components / route handlers: Next's cookies(). Imported lazily so the package does not require Next.\n const { cookies } = (await import('next/headers')) as { cookies: () => unknown };\n const jar = (await cookies()) as { get(n: string): { value: string } | undefined };\n return jar.get(cookieName)?.value ?? null;\n };\n\n const auth: BwalletXAuth = {\n async challenge(req) {\n secret();\n if (badOrigin(req)) return json({ error: 'origin not allowed' }, 403);\n const b = await body(req);\n try {\n return json(await createChallenge({ origin: o.origin, identityKey: b?.identityKey, store: o.store }));\n } catch (e) {\n return json({ error: (e as Error).message }, 400);\n }\n },\n async verify(req) {\n const key = secret();\n if (badOrigin(req)) return json({ error: 'origin not allowed' }, 403);\n const b = await body(req);\n const identityKey = await verifySignIn({ origin: o.origin, identityKey: b?.identityKey, nonce: b?.nonce, signature: b?.signature, store: o.store });\n if (!identityKey) return json({ error: 'sign-in failed' }, 401);\n let extra: VerifiedExtra = {};\n try {\n const r = await o.onVerified?.(identityKey, req);\n if (r === false) return json({ error: 'not allowed' }, 403);\n if (r) extra = r;\n } catch (e) {\n if (e instanceof IdentityLinkConflictError) return json({ error: e.message, code: e.code }, 409);\n throw e;\n }\n const token = await signSession({ ...extra, sub: identityKey }, { secret: key, maxAge });\n return json({ identityKey, uid: extra.uid, handle: extra.handle, paymail: extra.paymail }, 200, { 'set-cookie': cookie(token, maxAge) });\n },\n async logout(req) {\n if (badOrigin(req)) return json({ error: 'origin not allowed' }, 403);\n return json({ ok: true }, 200, { 'set-cookie': cookie('', 0) });\n },\n async session(req) {\n const s = await auth.getSession(req);\n return s ? json({ identityKey: s.sub, uid: s.uid, handle: s.handle, paymail: s.paymail, exp: s.exp }) : json({ identityKey: null }, 200);\n },\n async getSession(source) {\n const key = secret();\n return verifySession(await fromSource(source), { secret: key });\n },\n async sessionCookie(claims) {\n return cookie(await signSession(claims, { secret: secret(), maxAge }), maxAge);\n },\n clearCookie: () => cookie('', 0),\n };\n return auth;\n}\n\nexport { IdentityLinkConflictError, linkIdentity, signInOrLink } from './link.js';\nexport { memoryStore, redisStore, pgStore, pgNonceTableSql } from './server.js';\n"],"mappings":"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","names":["body"]}
|