@opys/bifrost 0.1.2
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 +80 -0
- package/dist/index.d.cts +58 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +58 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +80 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +32 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
let node_crypto = require("node:crypto");
|
|
3
|
+
|
|
4
|
+
//#region lib/index.ts
|
|
5
|
+
/**
|
|
6
|
+
* Mint a [Bifrost](https://gitlab.com/harmoniya/bifrost)-compatible JWT
|
|
7
|
+
* locally so opys's `runClient` can launch Minecraft against a self-hosted
|
|
8
|
+
* Yggdrasil server without going through the OAuth `/token` flow.
|
|
9
|
+
*
|
|
10
|
+
* Bifrost validates incoming bearer tokens with a single Ed25519 public key
|
|
11
|
+
* and only requires two claims: `uuid` and `username`. We sign here with
|
|
12
|
+
* the matching Ed25519 private key — same alg (`EdDSA`), same payload shape
|
|
13
|
+
* as Bifrost's own `/token` endpoint (`{ uuid, username, iat, exp }`).
|
|
14
|
+
*/
|
|
15
|
+
const DEFAULT_TTL_SECONDS = 1440 * 60;
|
|
16
|
+
function normalizePrivateKey(raw) {
|
|
17
|
+
if (!raw) throw new Error("bifrost: privateKey is required (got empty/undefined). Set BIFROST_PRIVATE_KEY in your environment, e.g. `export BIFROST_PRIVATE_KEY=\"$(cat path/to/key.pem)\"`.");
|
|
18
|
+
const unescaped = raw.replace(/\\n/g, "\n").trim();
|
|
19
|
+
const key = (0, node_crypto.createPrivateKey)({
|
|
20
|
+
key: unescaped.includes("-----BEGIN ") ? unescaped : `-----BEGIN PRIVATE KEY-----\n${unescaped}\n-----END PRIVATE KEY-----`,
|
|
21
|
+
format: "pem"
|
|
22
|
+
});
|
|
23
|
+
if (key.asymmetricKeyType !== "ed25519") throw new Error(`Bifrost private key must be Ed25519; got ${key.asymmetricKeyType ?? "unknown"}`);
|
|
24
|
+
return key;
|
|
25
|
+
}
|
|
26
|
+
function base64url(input) {
|
|
27
|
+
const buf = typeof input === "string" ? Buffer.from(input, "utf8") : input;
|
|
28
|
+
return Buffer.from(buf).toString("base64").replace(/=+$/, "").replace(/\+/g, "-").replace(/\//g, "_");
|
|
29
|
+
}
|
|
30
|
+
function unixSeconds(t) {
|
|
31
|
+
if (t === void 0) return Math.floor(Date.now() / 1e3);
|
|
32
|
+
const ms = t instanceof Date ? t.getTime() : t;
|
|
33
|
+
return Math.floor(ms / 1e3);
|
|
34
|
+
}
|
|
35
|
+
function sanitizeUuid(uuid) {
|
|
36
|
+
return uuid.replace(/-/g, "").toLowerCase();
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Sign an Ed25519 JWT with `{ uuid, username, iat, exp }` claims and return
|
|
40
|
+
* an auth object ready to spread into `runClient.vars`.
|
|
41
|
+
*
|
|
42
|
+
* ```ts
|
|
43
|
+
* const auth = resolveBifrost({
|
|
44
|
+
* privateKey: process.env.BIFROST_PRIVATE_KEY,
|
|
45
|
+
* username: 'Player',
|
|
46
|
+
* uuid: '00000000-0000-0000-0000-000000000000',
|
|
47
|
+
* });
|
|
48
|
+
* // auth = { username, uuid, token }
|
|
49
|
+
* ```
|
|
50
|
+
*
|
|
51
|
+
* The token mirrors what Bifrost's own `/token` endpoint mints, so it
|
|
52
|
+
* passes `authMiddleware` validation against the matching public key.
|
|
53
|
+
*/
|
|
54
|
+
function resolveBifrost(options) {
|
|
55
|
+
const key = normalizePrivateKey(options.privateKey);
|
|
56
|
+
const uuid = sanitizeUuid(options.uuid);
|
|
57
|
+
const username = options.username;
|
|
58
|
+
const iat = unixSeconds(options.now);
|
|
59
|
+
const ttl = options.expiresIn ?? DEFAULT_TTL_SECONDS;
|
|
60
|
+
const exp = ttl > 0 ? iat + ttl : null;
|
|
61
|
+
const header = {
|
|
62
|
+
alg: "EdDSA",
|
|
63
|
+
typ: "JWT"
|
|
64
|
+
};
|
|
65
|
+
const payload = {
|
|
66
|
+
uuid,
|
|
67
|
+
username,
|
|
68
|
+
iat
|
|
69
|
+
};
|
|
70
|
+
if (exp !== null) payload.exp = exp;
|
|
71
|
+
const signingInput = `${base64url(JSON.stringify(header))}.${base64url(JSON.stringify(payload))}`;
|
|
72
|
+
return {
|
|
73
|
+
username,
|
|
74
|
+
uuid,
|
|
75
|
+
token: `${signingInput}.${base64url((0, node_crypto.sign)(null, Buffer.from(signingInput), key))}`
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
//#endregion
|
|
80
|
+
exports.resolveBifrost = resolveBifrost;
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
//#region lib/index.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Mint a [Bifrost](https://gitlab.com/harmoniya/bifrost)-compatible JWT
|
|
4
|
+
* locally so opys's `runClient` can launch Minecraft against a self-hosted
|
|
5
|
+
* Yggdrasil server without going through the OAuth `/token` flow.
|
|
6
|
+
*
|
|
7
|
+
* Bifrost validates incoming bearer tokens with a single Ed25519 public key
|
|
8
|
+
* and only requires two claims: `uuid` and `username`. We sign here with
|
|
9
|
+
* the matching Ed25519 private key — same alg (`EdDSA`), same payload shape
|
|
10
|
+
* as Bifrost's own `/token` endpoint (`{ uuid, username, iat, exp }`).
|
|
11
|
+
*/
|
|
12
|
+
interface BifrostOptions {
|
|
13
|
+
/**
|
|
14
|
+
* PEM-encoded Ed25519 private key (PKCS8). Single-line keys with literal
|
|
15
|
+
* `\n` separators are accepted (env-var-friendly); a missing
|
|
16
|
+
* `-----BEGIN PRIVATE KEY-----` header is added automatically.
|
|
17
|
+
*/
|
|
18
|
+
privateKey: string;
|
|
19
|
+
/** Player username — used as the `username` claim and mirrored to the result. */
|
|
20
|
+
username: string;
|
|
21
|
+
/** Player UUID. Dashes are stripped before signing (matches Bifrost). */
|
|
22
|
+
uuid: string;
|
|
23
|
+
/**
|
|
24
|
+
* Token lifetime in seconds. Default `86400` (24h, matches Bifrost's
|
|
25
|
+
* `/token`). Pass `0` to omit `exp` entirely.
|
|
26
|
+
*/
|
|
27
|
+
expiresIn?: number;
|
|
28
|
+
/** Override the issued-at timestamp (ms since epoch or `Date`). Defaults to `Date.now()`. */
|
|
29
|
+
now?: number | Date;
|
|
30
|
+
}
|
|
31
|
+
interface BifrostAuth {
|
|
32
|
+
/** Player username, mirrored from input. */
|
|
33
|
+
username: string;
|
|
34
|
+
/** Dashless UUID (32 hex chars). */
|
|
35
|
+
uuid: string;
|
|
36
|
+
/** Signed Ed25519 JWT. Pass as `${token}` in your launch vars. */
|
|
37
|
+
token: string;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Sign an Ed25519 JWT with `{ uuid, username, iat, exp }` claims and return
|
|
41
|
+
* an auth object ready to spread into `runClient.vars`.
|
|
42
|
+
*
|
|
43
|
+
* ```ts
|
|
44
|
+
* const auth = resolveBifrost({
|
|
45
|
+
* privateKey: process.env.BIFROST_PRIVATE_KEY,
|
|
46
|
+
* username: 'Player',
|
|
47
|
+
* uuid: '00000000-0000-0000-0000-000000000000',
|
|
48
|
+
* });
|
|
49
|
+
* // auth = { username, uuid, token }
|
|
50
|
+
* ```
|
|
51
|
+
*
|
|
52
|
+
* The token mirrors what Bifrost's own `/token` endpoint mints, so it
|
|
53
|
+
* passes `authMiddleware` validation against the matching public key.
|
|
54
|
+
*/
|
|
55
|
+
declare function resolveBifrost(options: BifrostOptions): BifrostAuth;
|
|
56
|
+
//#endregion
|
|
57
|
+
export { BifrostAuth, BifrostOptions, resolveBifrost };
|
|
58
|
+
//# sourceMappingURL=index.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../lib/index.ts"],"mappings":";;AAaA;;;;;;;;;UAAiB,cAAA;EAiBI;;AAGrB;;;EAdE,UAAA;EAgBA;EAdA,QAAA;EAkBA;EAhBA,IAAA;EAgBK;AA6DP;;;EAxEE,SAAA;EAwEsC;EAtEtC,GAAA,YAAe,IAAA;AAAA;AAAA,UAGA,WAAA;EAmEmD;EAjElE,QAAA;;EAEA,IAAA;;EAEA,KAAA;AAAA;;;;;;;;;;;;;;;;;iBA6Dc,cAAA,CAAe,OAAA,EAAS,cAAA,GAAiB,WAAA"}
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
//#region lib/index.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Mint a [Bifrost](https://gitlab.com/harmoniya/bifrost)-compatible JWT
|
|
4
|
+
* locally so opys's `runClient` can launch Minecraft against a self-hosted
|
|
5
|
+
* Yggdrasil server without going through the OAuth `/token` flow.
|
|
6
|
+
*
|
|
7
|
+
* Bifrost validates incoming bearer tokens with a single Ed25519 public key
|
|
8
|
+
* and only requires two claims: `uuid` and `username`. We sign here with
|
|
9
|
+
* the matching Ed25519 private key — same alg (`EdDSA`), same payload shape
|
|
10
|
+
* as Bifrost's own `/token` endpoint (`{ uuid, username, iat, exp }`).
|
|
11
|
+
*/
|
|
12
|
+
interface BifrostOptions {
|
|
13
|
+
/**
|
|
14
|
+
* PEM-encoded Ed25519 private key (PKCS8). Single-line keys with literal
|
|
15
|
+
* `\n` separators are accepted (env-var-friendly); a missing
|
|
16
|
+
* `-----BEGIN PRIVATE KEY-----` header is added automatically.
|
|
17
|
+
*/
|
|
18
|
+
privateKey: string;
|
|
19
|
+
/** Player username — used as the `username` claim and mirrored to the result. */
|
|
20
|
+
username: string;
|
|
21
|
+
/** Player UUID. Dashes are stripped before signing (matches Bifrost). */
|
|
22
|
+
uuid: string;
|
|
23
|
+
/**
|
|
24
|
+
* Token lifetime in seconds. Default `86400` (24h, matches Bifrost's
|
|
25
|
+
* `/token`). Pass `0` to omit `exp` entirely.
|
|
26
|
+
*/
|
|
27
|
+
expiresIn?: number;
|
|
28
|
+
/** Override the issued-at timestamp (ms since epoch or `Date`). Defaults to `Date.now()`. */
|
|
29
|
+
now?: number | Date;
|
|
30
|
+
}
|
|
31
|
+
interface BifrostAuth {
|
|
32
|
+
/** Player username, mirrored from input. */
|
|
33
|
+
username: string;
|
|
34
|
+
/** Dashless UUID (32 hex chars). */
|
|
35
|
+
uuid: string;
|
|
36
|
+
/** Signed Ed25519 JWT. Pass as `${token}` in your launch vars. */
|
|
37
|
+
token: string;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Sign an Ed25519 JWT with `{ uuid, username, iat, exp }` claims and return
|
|
41
|
+
* an auth object ready to spread into `runClient.vars`.
|
|
42
|
+
*
|
|
43
|
+
* ```ts
|
|
44
|
+
* const auth = resolveBifrost({
|
|
45
|
+
* privateKey: process.env.BIFROST_PRIVATE_KEY,
|
|
46
|
+
* username: 'Player',
|
|
47
|
+
* uuid: '00000000-0000-0000-0000-000000000000',
|
|
48
|
+
* });
|
|
49
|
+
* // auth = { username, uuid, token }
|
|
50
|
+
* ```
|
|
51
|
+
*
|
|
52
|
+
* The token mirrors what Bifrost's own `/token` endpoint mints, so it
|
|
53
|
+
* passes `authMiddleware` validation against the matching public key.
|
|
54
|
+
*/
|
|
55
|
+
declare function resolveBifrost(options: BifrostOptions): BifrostAuth;
|
|
56
|
+
//#endregion
|
|
57
|
+
export { BifrostAuth, BifrostOptions, resolveBifrost };
|
|
58
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../lib/index.ts"],"mappings":";;AAaA;;;;;;;;;UAAiB,cAAA;EAiBI;;AAGrB;;;EAdE,UAAA;EAgBA;EAdA,QAAA;EAkBA;EAhBA,IAAA;EAgBK;AA6DP;;;EAxEE,SAAA;EAwEsC;EAtEtC,GAAA,YAAe,IAAA;AAAA;AAAA,UAGA,WAAA;EAmEmD;EAjElE,QAAA;;EAEA,IAAA;;EAEA,KAAA;AAAA;;;;;;;;;;;;;;;;;iBA6Dc,cAAA,CAAe,OAAA,EAAS,cAAA,GAAiB,WAAA"}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { createPrivateKey, sign } from "node:crypto";
|
|
2
|
+
|
|
3
|
+
//#region lib/index.ts
|
|
4
|
+
/**
|
|
5
|
+
* Mint a [Bifrost](https://gitlab.com/harmoniya/bifrost)-compatible JWT
|
|
6
|
+
* locally so opys's `runClient` can launch Minecraft against a self-hosted
|
|
7
|
+
* Yggdrasil server without going through the OAuth `/token` flow.
|
|
8
|
+
*
|
|
9
|
+
* Bifrost validates incoming bearer tokens with a single Ed25519 public key
|
|
10
|
+
* and only requires two claims: `uuid` and `username`. We sign here with
|
|
11
|
+
* the matching Ed25519 private key — same alg (`EdDSA`), same payload shape
|
|
12
|
+
* as Bifrost's own `/token` endpoint (`{ uuid, username, iat, exp }`).
|
|
13
|
+
*/
|
|
14
|
+
const DEFAULT_TTL_SECONDS = 1440 * 60;
|
|
15
|
+
function normalizePrivateKey(raw) {
|
|
16
|
+
if (!raw) throw new Error("bifrost: privateKey is required (got empty/undefined). Set BIFROST_PRIVATE_KEY in your environment, e.g. `export BIFROST_PRIVATE_KEY=\"$(cat path/to/key.pem)\"`.");
|
|
17
|
+
const unescaped = raw.replace(/\\n/g, "\n").trim();
|
|
18
|
+
const key = createPrivateKey({
|
|
19
|
+
key: unescaped.includes("-----BEGIN ") ? unescaped : `-----BEGIN PRIVATE KEY-----\n${unescaped}\n-----END PRIVATE KEY-----`,
|
|
20
|
+
format: "pem"
|
|
21
|
+
});
|
|
22
|
+
if (key.asymmetricKeyType !== "ed25519") throw new Error(`Bifrost private key must be Ed25519; got ${key.asymmetricKeyType ?? "unknown"}`);
|
|
23
|
+
return key;
|
|
24
|
+
}
|
|
25
|
+
function base64url(input) {
|
|
26
|
+
const buf = typeof input === "string" ? Buffer.from(input, "utf8") : input;
|
|
27
|
+
return Buffer.from(buf).toString("base64").replace(/=+$/, "").replace(/\+/g, "-").replace(/\//g, "_");
|
|
28
|
+
}
|
|
29
|
+
function unixSeconds(t) {
|
|
30
|
+
if (t === void 0) return Math.floor(Date.now() / 1e3);
|
|
31
|
+
const ms = t instanceof Date ? t.getTime() : t;
|
|
32
|
+
return Math.floor(ms / 1e3);
|
|
33
|
+
}
|
|
34
|
+
function sanitizeUuid(uuid) {
|
|
35
|
+
return uuid.replace(/-/g, "").toLowerCase();
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Sign an Ed25519 JWT with `{ uuid, username, iat, exp }` claims and return
|
|
39
|
+
* an auth object ready to spread into `runClient.vars`.
|
|
40
|
+
*
|
|
41
|
+
* ```ts
|
|
42
|
+
* const auth = resolveBifrost({
|
|
43
|
+
* privateKey: process.env.BIFROST_PRIVATE_KEY,
|
|
44
|
+
* username: 'Player',
|
|
45
|
+
* uuid: '00000000-0000-0000-0000-000000000000',
|
|
46
|
+
* });
|
|
47
|
+
* // auth = { username, uuid, token }
|
|
48
|
+
* ```
|
|
49
|
+
*
|
|
50
|
+
* The token mirrors what Bifrost's own `/token` endpoint mints, so it
|
|
51
|
+
* passes `authMiddleware` validation against the matching public key.
|
|
52
|
+
*/
|
|
53
|
+
function resolveBifrost(options) {
|
|
54
|
+
const key = normalizePrivateKey(options.privateKey);
|
|
55
|
+
const uuid = sanitizeUuid(options.uuid);
|
|
56
|
+
const username = options.username;
|
|
57
|
+
const iat = unixSeconds(options.now);
|
|
58
|
+
const ttl = options.expiresIn ?? DEFAULT_TTL_SECONDS;
|
|
59
|
+
const exp = ttl > 0 ? iat + ttl : null;
|
|
60
|
+
const header = {
|
|
61
|
+
alg: "EdDSA",
|
|
62
|
+
typ: "JWT"
|
|
63
|
+
};
|
|
64
|
+
const payload = {
|
|
65
|
+
uuid,
|
|
66
|
+
username,
|
|
67
|
+
iat
|
|
68
|
+
};
|
|
69
|
+
if (exp !== null) payload.exp = exp;
|
|
70
|
+
const signingInput = `${base64url(JSON.stringify(header))}.${base64url(JSON.stringify(payload))}`;
|
|
71
|
+
return {
|
|
72
|
+
username,
|
|
73
|
+
uuid,
|
|
74
|
+
token: `${signingInput}.${base64url(sign(null, Buffer.from(signingInput), key))}`
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
//#endregion
|
|
79
|
+
export { resolveBifrost };
|
|
80
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../lib/index.ts"],"sourcesContent":["/**\n * Mint a [Bifrost](https://gitlab.com/harmoniya/bifrost)-compatible JWT\n * locally so opys's `runClient` can launch Minecraft against a self-hosted\n * Yggdrasil server without going through the OAuth `/token` flow.\n *\n * Bifrost validates incoming bearer tokens with a single Ed25519 public key\n * and only requires two claims: `uuid` and `username`. We sign here with\n * the matching Ed25519 private key — same alg (`EdDSA`), same payload shape\n * as Bifrost's own `/token` endpoint (`{ uuid, username, iat, exp }`).\n */\n\nimport { createPrivateKey, sign, type KeyObject } from 'node:crypto';\n\nexport interface BifrostOptions {\n /**\n * PEM-encoded Ed25519 private key (PKCS8). Single-line keys with literal\n * `\\n` separators are accepted (env-var-friendly); a missing\n * `-----BEGIN PRIVATE KEY-----` header is added automatically.\n */\n privateKey: string;\n /** Player username — used as the `username` claim and mirrored to the result. */\n username: string;\n /** Player UUID. Dashes are stripped before signing (matches Bifrost). */\n uuid: string;\n /**\n * Token lifetime in seconds. Default `86400` (24h, matches Bifrost's\n * `/token`). Pass `0` to omit `exp` entirely.\n */\n expiresIn?: number;\n /** Override the issued-at timestamp (ms since epoch or `Date`). Defaults to `Date.now()`. */\n now?: number | Date;\n}\n\nexport interface BifrostAuth {\n /** Player username, mirrored from input. */\n username: string;\n /** Dashless UUID (32 hex chars). */\n uuid: string;\n /** Signed Ed25519 JWT. Pass as `${token}` in your launch vars. */\n token: string;\n}\n\nconst DEFAULT_TTL_SECONDS = 24 * 60 * 60;\n\nfunction normalizePrivateKey(raw: string): KeyObject {\n if (!raw) {\n throw new Error(\n 'bifrost: privateKey is required (got empty/undefined). ' +\n 'Set BIFROST_PRIVATE_KEY in your environment, e.g. ' +\n '`export BIFROST_PRIVATE_KEY=\"$(cat path/to/key.pem)\"`.',\n );\n }\n const unescaped = raw.replace(/\\\\n/g, '\\n').trim();\n const pem = unescaped.includes('-----BEGIN ')\n ? unescaped\n : `-----BEGIN PRIVATE KEY-----\\n${unescaped}\\n-----END PRIVATE KEY-----`;\n const key = createPrivateKey({ key: pem, format: 'pem' });\n if (key.asymmetricKeyType !== 'ed25519') {\n throw new Error(\n `Bifrost private key must be Ed25519; got ${key.asymmetricKeyType ?? 'unknown'}`,\n );\n }\n return key;\n}\n\nfunction base64url(input: string | Uint8Array): string {\n const buf = typeof input === 'string' ? Buffer.from(input, 'utf8') : input;\n return Buffer.from(buf)\n .toString('base64')\n .replace(/=+$/, '')\n .replace(/\\+/g, '-')\n .replace(/\\//g, '_');\n}\n\nfunction unixSeconds(t: number | Date | undefined): number {\n if (t === undefined) return Math.floor(Date.now() / 1000);\n const ms = t instanceof Date ? t.getTime() : t;\n return Math.floor(ms / 1000);\n}\n\nfunction sanitizeUuid(uuid: string): string {\n return uuid.replace(/-/g, '').toLowerCase();\n}\n\n/**\n * Sign an Ed25519 JWT with `{ uuid, username, iat, exp }` claims and return\n * an auth object ready to spread into `runClient.vars`.\n *\n * ```ts\n * const auth = resolveBifrost({\n * privateKey: process.env.BIFROST_PRIVATE_KEY,\n * username: 'Player',\n * uuid: '00000000-0000-0000-0000-000000000000',\n * });\n * // auth = { username, uuid, token }\n * ```\n *\n * The token mirrors what Bifrost's own `/token` endpoint mints, so it\n * passes `authMiddleware` validation against the matching public key.\n */\nexport function resolveBifrost(options: BifrostOptions): BifrostAuth {\n const key = normalizePrivateKey(options.privateKey);\n const uuid = sanitizeUuid(options.uuid);\n const username = options.username;\n\n const iat = unixSeconds(options.now);\n const ttl = options.expiresIn ?? DEFAULT_TTL_SECONDS;\n const exp = ttl > 0 ? iat + ttl : null;\n\n const header = { alg: 'EdDSA', typ: 'JWT' };\n const payload: Record<string, unknown> = { uuid, username, iat };\n if (exp !== null) payload.exp = exp;\n\n const headerB64 = base64url(JSON.stringify(header));\n const payloadB64 = base64url(JSON.stringify(payload));\n const signingInput = `${headerB64}.${payloadB64}`;\n const signature = sign(null, Buffer.from(signingInput), key);\n const token = `${signingInput}.${base64url(signature)}`;\n\n return { username, uuid, token };\n}\n"],"mappings":";;;;;;;;;;;;;AA0CA,MAAM,sBAAsB,OAAU;AAEtC,SAAS,oBAAoB,KAAwB;AACnD,KAAI,CAAC,IACH,OAAM,IAAI,MACR,oKAGD;CAEH,MAAM,YAAY,IAAI,QAAQ,QAAQ,KAAK,CAAC,MAAM;CAIlD,MAAM,MAAM,iBAAiB;EAAE,KAHnB,UAAU,SAAS,cAAc,GACzC,YACA,gCAAgC,UAAU;EACL,QAAQ;EAAO,CAAC;AACzD,KAAI,IAAI,sBAAsB,UAC5B,OAAM,IAAI,MACR,4CAA4C,IAAI,qBAAqB,YACtE;AAEH,QAAO;;AAGT,SAAS,UAAU,OAAoC;CACrD,MAAM,MAAM,OAAO,UAAU,WAAW,OAAO,KAAK,OAAO,OAAO,GAAG;AACrE,QAAO,OAAO,KAAK,IAAI,CACpB,SAAS,SAAS,CAClB,QAAQ,OAAO,GAAG,CAClB,QAAQ,OAAO,IAAI,CACnB,QAAQ,OAAO,IAAI;;AAGxB,SAAS,YAAY,GAAsC;AACzD,KAAI,MAAM,OAAW,QAAO,KAAK,MAAM,KAAK,KAAK,GAAG,IAAK;CACzD,MAAM,KAAK,aAAa,OAAO,EAAE,SAAS,GAAG;AAC7C,QAAO,KAAK,MAAM,KAAK,IAAK;;AAG9B,SAAS,aAAa,MAAsB;AAC1C,QAAO,KAAK,QAAQ,MAAM,GAAG,CAAC,aAAa;;;;;;;;;;;;;;;;;;AAmB7C,SAAgB,eAAe,SAAsC;CACnE,MAAM,MAAM,oBAAoB,QAAQ,WAAW;CACnD,MAAM,OAAO,aAAa,QAAQ,KAAK;CACvC,MAAM,WAAW,QAAQ;CAEzB,MAAM,MAAM,YAAY,QAAQ,IAAI;CACpC,MAAM,MAAM,QAAQ,aAAa;CACjC,MAAM,MAAM,MAAM,IAAI,MAAM,MAAM;CAElC,MAAM,SAAS;EAAE,KAAK;EAAS,KAAK;EAAO;CAC3C,MAAM,UAAmC;EAAE;EAAM;EAAU;EAAK;AAChE,KAAI,QAAQ,KAAM,SAAQ,MAAM;CAIhC,MAAM,eAAe,GAFH,UAAU,KAAK,UAAU,OAAO,CAAC,CAEjB,GADf,UAAU,KAAK,UAAU,QAAQ,CAAC;AAKrD,QAAO;EAAE;EAAU;EAAM,OAFX,GAAG,aAAa,GAAG,UADf,KAAK,MAAM,OAAO,KAAK,aAAa,EAAE,IAAI,CACP;EAErB"}
|
package/package.json
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@opys/bifrost",
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": {
|
|
8
|
+
"import": "./dist/index.mjs",
|
|
9
|
+
"require": "./dist/index.cjs"
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "tsdown lib/index.ts --format esm,cjs --dts --clean",
|
|
14
|
+
"typecheck": "tsc --noEmit -p tsconfig.json",
|
|
15
|
+
"test": "vitest run tests/unit --passWithNoTests"
|
|
16
|
+
},
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"tsdown": "*",
|
|
19
|
+
"vitest": "*"
|
|
20
|
+
},
|
|
21
|
+
"files": [
|
|
22
|
+
"dist"
|
|
23
|
+
],
|
|
24
|
+
"engines": {
|
|
25
|
+
"node": ">=20"
|
|
26
|
+
},
|
|
27
|
+
"repository": {
|
|
28
|
+
"type": "git",
|
|
29
|
+
"url": "git+https://github.com/harmoniya-net/opys.git",
|
|
30
|
+
"directory": "packages/bifrost"
|
|
31
|
+
}
|
|
32
|
+
}
|