@jsprismarine/auth 0.0.0-stage → 0.14.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.
@@ -0,0 +1,113 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ // src/DefaultSkin.ts
4
+ /** A Bedrock skin texture is always RGBA, and 64x64 is the classic layout. */
5
+ var SKIN_WIDTH = 64;
6
+ var SKIN_HEIGHT = 64;
7
+ var BYTES_PER_PIXEL = 4;
8
+ var SKIN_TONE = [
9
+ 200,
10
+ 159,
11
+ 123
12
+ ];
13
+ var SHIRT = [
14
+ 63,
15
+ 111,
16
+ 168
17
+ ];
18
+ var TROUSERS = [
19
+ 57,
20
+ 63,
21
+ 82
22
+ ];
23
+ var REGIONS = [
24
+ {
25
+ x: 0,
26
+ y: 0,
27
+ width: 32,
28
+ height: 8,
29
+ colour: [
30
+ 74,
31
+ 54,
32
+ 40
33
+ ]
34
+ },
35
+ {
36
+ x: 0,
37
+ y: 8,
38
+ width: 32,
39
+ height: 8,
40
+ colour: SKIN_TONE
41
+ },
42
+ {
43
+ x: 16,
44
+ y: 16,
45
+ width: 24,
46
+ height: 16,
47
+ colour: SHIRT
48
+ },
49
+ {
50
+ x: 40,
51
+ y: 16,
52
+ width: 16,
53
+ height: 16,
54
+ colour: SHIRT
55
+ },
56
+ {
57
+ x: 32,
58
+ y: 48,
59
+ width: 16,
60
+ height: 16,
61
+ colour: SHIRT
62
+ },
63
+ {
64
+ x: 0,
65
+ y: 16,
66
+ width: 16,
67
+ height: 16,
68
+ colour: TROUSERS
69
+ },
70
+ {
71
+ x: 16,
72
+ y: 48,
73
+ width: 16,
74
+ height: 16,
75
+ colour: TROUSERS
76
+ }
77
+ ];
78
+ /**
79
+ * The skin the client wears when nothing else has been supplied.
80
+ *
81
+ * Generated rather than shipped as a PNG, and generated from flat colour blocks that are
82
+ * ours: Mojang's textures cannot be redistributed, and a client that refuses to log in
83
+ * without one would be useless. It is deliberately plain - the point is a valid, original
84
+ * 16 KiB of RGBA, not a good-looking character.
85
+ *
86
+ * @returns 64 * 64 * 4 bytes of RGBA, row major from the top left.
87
+ */
88
+ var createDefaultSkinImage = () => {
89
+ const image = Buffer.alloc(4096 * BYTES_PER_PIXEL);
90
+ for (const region of REGIONS) for (let y = region.y; y < region.y + region.height; y++) for (let x = region.x; x < region.x + region.width; x++) {
91
+ const offset = (y * 64 + x) * BYTES_PER_PIXEL;
92
+ const shade = 1 - (y - region.y) / region.height * .15;
93
+ image[offset] = Math.round(region.colour[0] * shade);
94
+ image[offset + 1] = Math.round(region.colour[1] * shade);
95
+ image[offset + 2] = Math.round(region.colour[2] * shade);
96
+ image[offset + 3] = 255;
97
+ }
98
+ return image;
99
+ };
100
+ /**
101
+ * Which model the client should hang the texture on.
102
+ *
103
+ * `geometry.humanoid.custom` is resolved by the client against a model it already has, so
104
+ * this is a reference rather than geometry we would have to ship. `SkinGeometryData` stays
105
+ * empty for the same reason.
106
+ */
107
+ var DEFAULT_SKIN_RESOURCE_PATCH = JSON.stringify({ geometry: { default: "geometry.humanoid.custom" } });
108
+ exports.DEFAULT_SKIN_RESOURCE_PATCH = DEFAULT_SKIN_RESOURCE_PATCH;
109
+ exports.SKIN_HEIGHT = SKIN_HEIGHT;
110
+ exports.SKIN_WIDTH = SKIN_WIDTH;
111
+ exports.createDefaultSkinImage = createDefaultSkinImage;
112
+
113
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRGVmYXVsdFNraW4uY2pzLmNqcyIsIm5hbWVzIjpbXSwic291cmNlcyI6WyIuLi9zcmMvRGVmYXVsdFNraW4udHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqIEEgQmVkcm9jayBza2luIHRleHR1cmUgaXMgYWx3YXlzIFJHQkEsIGFuZCA2NHg2NCBpcyB0aGUgY2xhc3NpYyBsYXlvdXQuICovXG5leHBvcnQgY29uc3QgU0tJTl9XSURUSCA9IDY0O1xuZXhwb3J0IGNvbnN0IFNLSU5fSEVJR0hUID0gNjQ7XG5jb25zdCBCWVRFU19QRVJfUElYRUwgPSA0O1xuXG4vKipcbiAqIFRoZSByZWdpb25zIG9mIHRoZSA2NHg2NCBzaGVldCB0aGUgY2xhc3NpYyBodW1hbm9pZCBnZW9tZXRyeSBzYW1wbGVzLCBhbmQgd2hhdCB0byBmaWxsXG4gKiBlYWNoIHdpdGguIEV2ZXJ5dGhpbmcgb3V0c2lkZSB0aGVtIGlzIGxlZnQgdHJhbnNwYXJlbnQsIGV4YWN0bHkgYXMgYW4gdW51c2VkIGFyZWEgb2YgYVxuICogcmVhbCBzaGVldCBpcy5cbiAqXG4gKiBDb29yZGluYXRlcyBjb21lIGZyb20gdGhlIGdlb21ldHJ5LCBub3QgZnJvbSBhbnkgTW9qYW5nIGFydHdvcmsgLSBgZ2VvbWV0cnkuaHVtYW5vaWQuY3VzdG9tYFxuICogaXMgYSBuYW1lIHRoZSBjbGllbnQgcmVzb2x2ZXMgYWdhaW5zdCBpdHMgb3duIGJ1aWx0LWluIG1vZGVsLCBhbmQgdGhlIGxheW91dCBpdCBpbXBsaWVzIGlzXG4gKiBhIGZhY3QgYWJvdXQgdGhlIGZvcm1hdCByYXRoZXIgdGhhbiBhbiBhc3NldC4gV2hhdCBmaWxscyB0aGVtIGlzIG91cnMuXG4gKi9cbmludGVyZmFjZSBSZWdpb24ge1xuICAgIHJlYWRvbmx5IHg6IG51bWJlcjtcbiAgICByZWFkb25seSB5OiBudW1iZXI7XG4gICAgcmVhZG9ubHkgd2lkdGg6IG51bWJlcjtcbiAgICByZWFkb25seSBoZWlnaHQ6IG51bWJlcjtcbiAgICByZWFkb25seSBjb2xvdXI6IHJlYWRvbmx5IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXTtcbn1cblxuY29uc3QgU0tJTl9UT05FOiByZWFkb25seSBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0gPSBbMHhjOCwgMHg5ZiwgMHg3Yl07XG5jb25zdCBTSElSVDogcmVhZG9ubHkgW251bWJlciwgbnVtYmVyLCBudW1iZXJdID0gWzB4M2YsIDB4NmYsIDB4YThdO1xuY29uc3QgVFJPVVNFUlM6IHJlYWRvbmx5IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSA9IFsweDM5LCAweDNmLCAweDUyXTtcbmNvbnN0IEhBSVI6IHJlYWRvbmx5IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSA9IFsweDRhLCAweDM2LCAweDI4XTtcblxuY29uc3QgUkVHSU9OUzogcmVhZG9ubHkgUmVnaW9uW10gPSBbXG4gICAgLy8gSGVhZDogdGhlIHRvcCBzdHJpcCBpcyBoYWlyLCB0aGUgcmVzdCBpcyBmYWNlLlxuICAgIHsgeDogMCwgeTogMCwgd2lkdGg6IDMyLCBoZWlnaHQ6IDgsIGNvbG91cjogSEFJUiB9LFxuICAgIHsgeDogMCwgeTogOCwgd2lkdGg6IDMyLCBoZWlnaHQ6IDgsIGNvbG91cjogU0tJTl9UT05FIH0sXG4gICAgLy8gQm9keSBhbmQgYXJtcy5cbiAgICB7IHg6IDE2LCB5OiAxNiwgd2lkdGg6IDI0LCBoZWlnaHQ6IDE2LCBjb2xvdXI6IFNISVJUIH0sXG4gICAgeyB4OiA0MCwgeTogMTYsIHdpZHRoOiAxNiwgaGVpZ2h0OiAxNiwgY29sb3VyOiBTSElSVCB9LFxuICAgIHsgeDogMzIsIHk6IDQ4LCB3aWR0aDogMTYsIGhlaWdodDogMTYsIGNvbG91cjogU0hJUlQgfSxcbiAgICAvLyBMZWdzLlxuICAgIHsgeDogMCwgeTogMTYsIHdpZHRoOiAxNiwgaGVpZ2h0OiAxNiwgY29sb3VyOiBUUk9VU0VSUyB9LFxuICAgIHsgeDogMTYsIHk6IDQ4LCB3aWR0aDogMTYsIGhlaWdodDogMTYsIGNvbG91cjogVFJPVVNFUlMgfVxuXTtcblxuLyoqXG4gKiBUaGUgc2tpbiB0aGUgY2xpZW50IHdlYXJzIHdoZW4gbm90aGluZyBlbHNlIGhhcyBiZWVuIHN1cHBsaWVkLlxuICpcbiAqIEdlbmVyYXRlZCByYXRoZXIgdGhhbiBzaGlwcGVkIGFzIGEgUE5HLCBhbmQgZ2VuZXJhdGVkIGZyb20gZmxhdCBjb2xvdXIgYmxvY2tzIHRoYXQgYXJlXG4gKiBvdXJzOiBNb2phbmcncyB0ZXh0dXJlcyBjYW5ub3QgYmUgcmVkaXN0cmlidXRlZCwgYW5kIGEgY2xpZW50IHRoYXQgcmVmdXNlcyB0byBsb2cgaW5cbiAqIHdpdGhvdXQgb25lIHdvdWxkIGJlIHVzZWxlc3MuIEl0IGlzIGRlbGliZXJhdGVseSBwbGFpbiAtIHRoZSBwb2ludCBpcyBhIHZhbGlkLCBvcmlnaW5hbFxuICogMTYgS2lCIG9mIFJHQkEsIG5vdCBhIGdvb2QtbG9va2luZyBjaGFyYWN0ZXIuXG4gKlxuICogQHJldHVybnMgNjQgKiA2NCAqIDQgYnl0ZXMgb2YgUkdCQSwgcm93IG1ham9yIGZyb20gdGhlIHRvcCBsZWZ0LlxuICovXG5leHBvcnQgY29uc3QgY3JlYXRlRGVmYXVsdFNraW5JbWFnZSA9ICgpOiBCdWZmZXIgPT4ge1xuICAgIGNvbnN0IGltYWdlID0gQnVmZmVyLmFsbG9jKFNLSU5fV0lEVEggKiBTS0lOX0hFSUdIVCAqIEJZVEVTX1BFUl9QSVhFTCk7XG5cbiAgICBmb3IgKGNvbnN0IHJlZ2lvbiBvZiBSRUdJT05TKSB7XG4gICAgICAgIGZvciAobGV0IHkgPSByZWdpb24ueTsgeSA8IHJlZ2lvbi55ICsgcmVnaW9uLmhlaWdodDsgeSsrKSB7XG4gICAgICAgICAgICBmb3IgKGxldCB4ID0gcmVnaW9uLng7IHggPCByZWdpb24ueCArIHJlZ2lvbi53aWR0aDsgeCsrKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb2Zmc2V0ID0gKHkgKiBTS0lOX1dJRFRIICsgeCkgKiBCWVRFU19QRVJfUElYRUw7XG4gICAgICAgICAgICAgICAgLy8gQSB0b3VjaCBvZiB2ZXJ0aWNhbCBzaGFkaW5nLCBzbyB0aGUgbW9kZWwgaXMgbm90IGEgZmxhdCBzaWxob3VldHRlLiBDaGVhcCxcbiAgICAgICAgICAgICAgICAvLyBkZXRlcm1pbmlzdGljLCBhbmQgaXQga2VlcHMgdGhlIGdlbmVyYXRlZCBzaGVldCBmcm9tIGxvb2tpbmcgbGlrZSBhbiBlcnJvci5cbiAgICAgICAgICAgICAgICBjb25zdCBzaGFkZSA9IDEgLSAoKHkgLSByZWdpb24ueSkgLyByZWdpb24uaGVpZ2h0KSAqIDAuMTU7XG4gICAgICAgICAgICAgICAgaW1hZ2Vbb2Zmc2V0XSA9IE1hdGgucm91bmQocmVnaW9uLmNvbG91clswXSAqIHNoYWRlKTtcbiAgICAgICAgICAgICAgICBpbWFnZVtvZmZzZXQgKyAxXSA9IE1hdGgucm91bmQocmVnaW9uLmNvbG91clsxXSAqIHNoYWRlKTtcbiAgICAgICAgICAgICAgICBpbWFnZVtvZmZzZXQgKyAyXSA9IE1hdGgucm91bmQocmVnaW9uLmNvbG91clsyXSAqIHNoYWRlKTtcbiAgICAgICAgICAgICAgICBpbWFnZVtvZmZzZXQgKyAzXSA9IDB4ZmY7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gaW1hZ2U7XG59O1xuXG4vKipcbiAqIFdoaWNoIG1vZGVsIHRoZSBjbGllbnQgc2hvdWxkIGhhbmcgdGhlIHRleHR1cmUgb24uXG4gKlxuICogYGdlb21ldHJ5Lmh1bWFub2lkLmN1c3RvbWAgaXMgcmVzb2x2ZWQgYnkgdGhlIGNsaWVudCBhZ2FpbnN0IGEgbW9kZWwgaXQgYWxyZWFkeSBoYXMsIHNvXG4gKiB0aGlzIGlzIGEgcmVmZXJlbmNlIHJhdGhlciB0aGFuIGdlb21ldHJ5IHdlIHdvdWxkIGhhdmUgdG8gc2hpcC4gYFNraW5HZW9tZXRyeURhdGFgIHN0YXlzXG4gKiBlbXB0eSBmb3IgdGhlIHNhbWUgcmVhc29uLlxuICovXG5leHBvcnQgY29uc3QgREVGQVVMVF9TS0lOX1JFU09VUkNFX1BBVENIID0gSlNPTi5zdHJpbmdpZnkoe1xuICAgIGdlb21ldHJ5OiB7IGRlZmF1bHQ6ICdnZW9tZXRyeS5odW1hbm9pZC5jdXN0b20nIH1cbn0pO1xuIl0sIm1hcHBpbmdzIjoiOzs7O0FBQ0EsSUFBYSxhQUFhO0FBQzFCLElBQWEsY0FBYztBQUMzQixJQUFNLGtCQUFrQjtBQW1CeEIsSUFBTSxZQUErQztDQUFDO0NBQU07Q0FBTTtBQUFJO0FBQ3RFLElBQU0sUUFBMkM7Q0FBQztDQUFNO0NBQU07QUFBSTtBQUNsRSxJQUFNLFdBQThDO0NBQUM7Q0FBTTtDQUFNO0FBQUk7QUFHckUsSUFBTSxVQUE2QjtDQUUvQjtFQUFFLEdBQUc7RUFBRyxHQUFHO0VBQUcsT0FBTztFQUFJLFFBQVE7RUFBRyxRQUFRO0dBSkM7R0FBTTtHQUFNO0VBSWI7Q0FBSztDQUNqRDtFQUFFLEdBQUc7RUFBRyxHQUFHO0VBQUcsT0FBTztFQUFJLFFBQVE7RUFBRyxRQUFRO0NBQVU7Q0FFdEQ7RUFBRSxHQUFHO0VBQUksR0FBRztFQUFJLE9BQU87RUFBSSxRQUFRO0VBQUksUUFBUTtDQUFNO0NBQ3JEO0VBQUUsR0FBRztFQUFJLEdBQUc7RUFBSSxPQUFPO0VBQUksUUFBUTtFQUFJLFFBQVE7Q0FBTTtDQUNyRDtFQUFFLEdBQUc7RUFBSSxHQUFHO0VBQUksT0FBTztFQUFJLFFBQVE7RUFBSSxRQUFRO0NBQU07Q0FFckQ7RUFBRSxHQUFHO0VBQUcsR0FBRztFQUFJLE9BQU87RUFBSSxRQUFRO0VBQUksUUFBUTtDQUFTO0NBQ3ZEO0VBQUUsR0FBRztFQUFJLEdBQUc7RUFBSSxPQUFPO0VBQUksUUFBUTtFQUFJLFFBQVE7Q0FBUztBQUM1RDs7Ozs7Ozs7Ozs7QUFZQSxJQUFhLCtCQUF1QztDQUNoRCxNQUFNLFFBQVEsT0FBTyxNQUFNLE9BQTJCLGVBQWU7Q0FFckUsS0FBSyxNQUFNLFVBQVUsU0FDakIsS0FBSyxJQUFJLElBQUksT0FBTyxHQUFHLElBQUksT0FBTyxJQUFJLE9BQU8sUUFBUSxLQUNqRCxLQUFLLElBQUksSUFBSSxPQUFPLEdBQUcsSUFBSSxPQUFPLElBQUksT0FBTyxPQUFPLEtBQUs7RUFDckQsTUFBTSxVQUFVLElBQUEsS0FBaUIsS0FBSztFQUd0QyxNQUFNLFFBQVEsS0FBTSxJQUFJLE9BQU8sS0FBSyxPQUFPLFNBQVU7RUFDckQsTUFBTSxVQUFVLEtBQUssTUFBTSxPQUFPLE9BQU8sS0FBSyxLQUFLO0VBQ25ELE1BQU0sU0FBUyxLQUFLLEtBQUssTUFBTSxPQUFPLE9BQU8sS0FBSyxLQUFLO0VBQ3ZELE1BQU0sU0FBUyxLQUFLLEtBQUssTUFBTSxPQUFPLE9BQU8sS0FBSyxLQUFLO0VBQ3ZELE1BQU0sU0FBUyxLQUFLO0NBQ3hCO0NBSVIsT0FBTztBQUNYOzs7Ozs7OztBQVNBLElBQWEsOEJBQThCLEtBQUssVUFBVSxFQUN0RCxVQUFVLEVBQUUsU0FBUywyQkFBMkIsRUFDcEQsQ0FBQyJ9
@@ -0,0 +1,23 @@
1
+ /** A Bedrock skin texture is always RGBA, and 64x64 is the classic layout. */
2
+ export declare const SKIN_WIDTH = 64;
3
+ export declare const SKIN_HEIGHT = 64;
4
+ /**
5
+ * The skin the client wears when nothing else has been supplied.
6
+ *
7
+ * Generated rather than shipped as a PNG, and generated from flat colour blocks that are
8
+ * ours: Mojang's textures cannot be redistributed, and a client that refuses to log in
9
+ * without one would be useless. It is deliberately plain - the point is a valid, original
10
+ * 16 KiB of RGBA, not a good-looking character.
11
+ *
12
+ * @returns 64 * 64 * 4 bytes of RGBA, row major from the top left.
13
+ */
14
+ export declare const createDefaultSkinImage: () => Buffer;
15
+ /**
16
+ * Which model the client should hang the texture on.
17
+ *
18
+ * `geometry.humanoid.custom` is resolved by the client against a model it already has, so
19
+ * this is a reference rather than geometry we would have to ship. `SkinGeometryData` stays
20
+ * empty for the same reason.
21
+ */
22
+ export declare const DEFAULT_SKIN_RESOURCE_PATCH: string;
23
+ //# sourceMappingURL=DefaultSkin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DefaultSkin.d.ts","sourceRoot":"","sources":["../src/DefaultSkin.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,eAAO,MAAM,UAAU,KAAK,CAAC;AAC7B,eAAO,MAAM,WAAW,KAAK,CAAC;AAsC9B;;;;;;;;;GASG;AACH,eAAO,MAAM,sBAAsB,QAAO,MAmBzC,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,2BAA2B,QAEtC,CAAC"}
@@ -0,0 +1,108 @@
1
+ // src/DefaultSkin.ts
2
+ /** A Bedrock skin texture is always RGBA, and 64x64 is the classic layout. */
3
+ var SKIN_WIDTH = 64;
4
+ var SKIN_HEIGHT = 64;
5
+ var BYTES_PER_PIXEL = 4;
6
+ var SKIN_TONE = [
7
+ 200,
8
+ 159,
9
+ 123
10
+ ];
11
+ var SHIRT = [
12
+ 63,
13
+ 111,
14
+ 168
15
+ ];
16
+ var TROUSERS = [
17
+ 57,
18
+ 63,
19
+ 82
20
+ ];
21
+ var REGIONS = [
22
+ {
23
+ x: 0,
24
+ y: 0,
25
+ width: 32,
26
+ height: 8,
27
+ colour: [
28
+ 74,
29
+ 54,
30
+ 40
31
+ ]
32
+ },
33
+ {
34
+ x: 0,
35
+ y: 8,
36
+ width: 32,
37
+ height: 8,
38
+ colour: SKIN_TONE
39
+ },
40
+ {
41
+ x: 16,
42
+ y: 16,
43
+ width: 24,
44
+ height: 16,
45
+ colour: SHIRT
46
+ },
47
+ {
48
+ x: 40,
49
+ y: 16,
50
+ width: 16,
51
+ height: 16,
52
+ colour: SHIRT
53
+ },
54
+ {
55
+ x: 32,
56
+ y: 48,
57
+ width: 16,
58
+ height: 16,
59
+ colour: SHIRT
60
+ },
61
+ {
62
+ x: 0,
63
+ y: 16,
64
+ width: 16,
65
+ height: 16,
66
+ colour: TROUSERS
67
+ },
68
+ {
69
+ x: 16,
70
+ y: 48,
71
+ width: 16,
72
+ height: 16,
73
+ colour: TROUSERS
74
+ }
75
+ ];
76
+ /**
77
+ * The skin the client wears when nothing else has been supplied.
78
+ *
79
+ * Generated rather than shipped as a PNG, and generated from flat colour blocks that are
80
+ * ours: Mojang's textures cannot be redistributed, and a client that refuses to log in
81
+ * without one would be useless. It is deliberately plain - the point is a valid, original
82
+ * 16 KiB of RGBA, not a good-looking character.
83
+ *
84
+ * @returns 64 * 64 * 4 bytes of RGBA, row major from the top left.
85
+ */
86
+ var createDefaultSkinImage = () => {
87
+ const image = Buffer.alloc(4096 * BYTES_PER_PIXEL);
88
+ for (const region of REGIONS) for (let y = region.y; y < region.y + region.height; y++) for (let x = region.x; x < region.x + region.width; x++) {
89
+ const offset = (y * 64 + x) * BYTES_PER_PIXEL;
90
+ const shade = 1 - (y - region.y) / region.height * .15;
91
+ image[offset] = Math.round(region.colour[0] * shade);
92
+ image[offset + 1] = Math.round(region.colour[1] * shade);
93
+ image[offset + 2] = Math.round(region.colour[2] * shade);
94
+ image[offset + 3] = 255;
95
+ }
96
+ return image;
97
+ };
98
+ /**
99
+ * Which model the client should hang the texture on.
100
+ *
101
+ * `geometry.humanoid.custom` is resolved by the client against a model it already has, so
102
+ * this is a reference rather than geometry we would have to ship. `SkinGeometryData` stays
103
+ * empty for the same reason.
104
+ */
105
+ var DEFAULT_SKIN_RESOURCE_PATCH = JSON.stringify({ geometry: { default: "geometry.humanoid.custom" } });
106
+ export { DEFAULT_SKIN_RESOURCE_PATCH, SKIN_HEIGHT, SKIN_WIDTH, createDefaultSkinImage };
107
+
108
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRGVmYXVsdFNraW4uZXMuanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vc3JjL0RlZmF1bHRTa2luLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKiBBIEJlZHJvY2sgc2tpbiB0ZXh0dXJlIGlzIGFsd2F5cyBSR0JBLCBhbmQgNjR4NjQgaXMgdGhlIGNsYXNzaWMgbGF5b3V0LiAqL1xuZXhwb3J0IGNvbnN0IFNLSU5fV0lEVEggPSA2NDtcbmV4cG9ydCBjb25zdCBTS0lOX0hFSUdIVCA9IDY0O1xuY29uc3QgQllURVNfUEVSX1BJWEVMID0gNDtcblxuLyoqXG4gKiBUaGUgcmVnaW9ucyBvZiB0aGUgNjR4NjQgc2hlZXQgdGhlIGNsYXNzaWMgaHVtYW5vaWQgZ2VvbWV0cnkgc2FtcGxlcywgYW5kIHdoYXQgdG8gZmlsbFxuICogZWFjaCB3aXRoLiBFdmVyeXRoaW5nIG91dHNpZGUgdGhlbSBpcyBsZWZ0IHRyYW5zcGFyZW50LCBleGFjdGx5IGFzIGFuIHVudXNlZCBhcmVhIG9mIGFcbiAqIHJlYWwgc2hlZXQgaXMuXG4gKlxuICogQ29vcmRpbmF0ZXMgY29tZSBmcm9tIHRoZSBnZW9tZXRyeSwgbm90IGZyb20gYW55IE1vamFuZyBhcnR3b3JrIC0gYGdlb21ldHJ5Lmh1bWFub2lkLmN1c3RvbWBcbiAqIGlzIGEgbmFtZSB0aGUgY2xpZW50IHJlc29sdmVzIGFnYWluc3QgaXRzIG93biBidWlsdC1pbiBtb2RlbCwgYW5kIHRoZSBsYXlvdXQgaXQgaW1wbGllcyBpc1xuICogYSBmYWN0IGFib3V0IHRoZSBmb3JtYXQgcmF0aGVyIHRoYW4gYW4gYXNzZXQuIFdoYXQgZmlsbHMgdGhlbSBpcyBvdXJzLlxuICovXG5pbnRlcmZhY2UgUmVnaW9uIHtcbiAgICByZWFkb25seSB4OiBudW1iZXI7XG4gICAgcmVhZG9ubHkgeTogbnVtYmVyO1xuICAgIHJlYWRvbmx5IHdpZHRoOiBudW1iZXI7XG4gICAgcmVhZG9ubHkgaGVpZ2h0OiBudW1iZXI7XG4gICAgcmVhZG9ubHkgY29sb3VyOiByZWFkb25seSBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl07XG59XG5cbmNvbnN0IFNLSU5fVE9ORTogcmVhZG9ubHkgW251bWJlciwgbnVtYmVyLCBudW1iZXJdID0gWzB4YzgsIDB4OWYsIDB4N2JdO1xuY29uc3QgU0hJUlQ6IHJlYWRvbmx5IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSA9IFsweDNmLCAweDZmLCAweGE4XTtcbmNvbnN0IFRST1VTRVJTOiByZWFkb25seSBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0gPSBbMHgzOSwgMHgzZiwgMHg1Ml07XG5jb25zdCBIQUlSOiByZWFkb25seSBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0gPSBbMHg0YSwgMHgzNiwgMHgyOF07XG5cbmNvbnN0IFJFR0lPTlM6IHJlYWRvbmx5IFJlZ2lvbltdID0gW1xuICAgIC8vIEhlYWQ6IHRoZSB0b3Agc3RyaXAgaXMgaGFpciwgdGhlIHJlc3QgaXMgZmFjZS5cbiAgICB7IHg6IDAsIHk6IDAsIHdpZHRoOiAzMiwgaGVpZ2h0OiA4LCBjb2xvdXI6IEhBSVIgfSxcbiAgICB7IHg6IDAsIHk6IDgsIHdpZHRoOiAzMiwgaGVpZ2h0OiA4LCBjb2xvdXI6IFNLSU5fVE9ORSB9LFxuICAgIC8vIEJvZHkgYW5kIGFybXMuXG4gICAgeyB4OiAxNiwgeTogMTYsIHdpZHRoOiAyNCwgaGVpZ2h0OiAxNiwgY29sb3VyOiBTSElSVCB9LFxuICAgIHsgeDogNDAsIHk6IDE2LCB3aWR0aDogMTYsIGhlaWdodDogMTYsIGNvbG91cjogU0hJUlQgfSxcbiAgICB7IHg6IDMyLCB5OiA0OCwgd2lkdGg6IDE2LCBoZWlnaHQ6IDE2LCBjb2xvdXI6IFNISVJUIH0sXG4gICAgLy8gTGVncy5cbiAgICB7IHg6IDAsIHk6IDE2LCB3aWR0aDogMTYsIGhlaWdodDogMTYsIGNvbG91cjogVFJPVVNFUlMgfSxcbiAgICB7IHg6IDE2LCB5OiA0OCwgd2lkdGg6IDE2LCBoZWlnaHQ6IDE2LCBjb2xvdXI6IFRST1VTRVJTIH1cbl07XG5cbi8qKlxuICogVGhlIHNraW4gdGhlIGNsaWVudCB3ZWFycyB3aGVuIG5vdGhpbmcgZWxzZSBoYXMgYmVlbiBzdXBwbGllZC5cbiAqXG4gKiBHZW5lcmF0ZWQgcmF0aGVyIHRoYW4gc2hpcHBlZCBhcyBhIFBORywgYW5kIGdlbmVyYXRlZCBmcm9tIGZsYXQgY29sb3VyIGJsb2NrcyB0aGF0IGFyZVxuICogb3VyczogTW9qYW5nJ3MgdGV4dHVyZXMgY2Fubm90IGJlIHJlZGlzdHJpYnV0ZWQsIGFuZCBhIGNsaWVudCB0aGF0IHJlZnVzZXMgdG8gbG9nIGluXG4gKiB3aXRob3V0IG9uZSB3b3VsZCBiZSB1c2VsZXNzLiBJdCBpcyBkZWxpYmVyYXRlbHkgcGxhaW4gLSB0aGUgcG9pbnQgaXMgYSB2YWxpZCwgb3JpZ2luYWxcbiAqIDE2IEtpQiBvZiBSR0JBLCBub3QgYSBnb29kLWxvb2tpbmcgY2hhcmFjdGVyLlxuICpcbiAqIEByZXR1cm5zIDY0ICogNjQgKiA0IGJ5dGVzIG9mIFJHQkEsIHJvdyBtYWpvciBmcm9tIHRoZSB0b3AgbGVmdC5cbiAqL1xuZXhwb3J0IGNvbnN0IGNyZWF0ZURlZmF1bHRTa2luSW1hZ2UgPSAoKTogQnVmZmVyID0+IHtcbiAgICBjb25zdCBpbWFnZSA9IEJ1ZmZlci5hbGxvYyhTS0lOX1dJRFRIICogU0tJTl9IRUlHSFQgKiBCWVRFU19QRVJfUElYRUwpO1xuXG4gICAgZm9yIChjb25zdCByZWdpb24gb2YgUkVHSU9OUykge1xuICAgICAgICBmb3IgKGxldCB5ID0gcmVnaW9uLnk7IHkgPCByZWdpb24ueSArIHJlZ2lvbi5oZWlnaHQ7IHkrKykge1xuICAgICAgICAgICAgZm9yIChsZXQgeCA9IHJlZ2lvbi54OyB4IDwgcmVnaW9uLnggKyByZWdpb24ud2lkdGg7IHgrKykge1xuICAgICAgICAgICAgICAgIGNvbnN0IG9mZnNldCA9ICh5ICogU0tJTl9XSURUSCArIHgpICogQllURVNfUEVSX1BJWEVMO1xuICAgICAgICAgICAgICAgIC8vIEEgdG91Y2ggb2YgdmVydGljYWwgc2hhZGluZywgc28gdGhlIG1vZGVsIGlzIG5vdCBhIGZsYXQgc2lsaG91ZXR0ZS4gQ2hlYXAsXG4gICAgICAgICAgICAgICAgLy8gZGV0ZXJtaW5pc3RpYywgYW5kIGl0IGtlZXBzIHRoZSBnZW5lcmF0ZWQgc2hlZXQgZnJvbSBsb29raW5nIGxpa2UgYW4gZXJyb3IuXG4gICAgICAgICAgICAgICAgY29uc3Qgc2hhZGUgPSAxIC0gKCh5IC0gcmVnaW9uLnkpIC8gcmVnaW9uLmhlaWdodCkgKiAwLjE1O1xuICAgICAgICAgICAgICAgIGltYWdlW29mZnNldF0gPSBNYXRoLnJvdW5kKHJlZ2lvbi5jb2xvdXJbMF0gKiBzaGFkZSk7XG4gICAgICAgICAgICAgICAgaW1hZ2Vbb2Zmc2V0ICsgMV0gPSBNYXRoLnJvdW5kKHJlZ2lvbi5jb2xvdXJbMV0gKiBzaGFkZSk7XG4gICAgICAgICAgICAgICAgaW1hZ2Vbb2Zmc2V0ICsgMl0gPSBNYXRoLnJvdW5kKHJlZ2lvbi5jb2xvdXJbMl0gKiBzaGFkZSk7XG4gICAgICAgICAgICAgICAgaW1hZ2Vbb2Zmc2V0ICsgM10gPSAweGZmO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGltYWdlO1xufTtcblxuLyoqXG4gKiBXaGljaCBtb2RlbCB0aGUgY2xpZW50IHNob3VsZCBoYW5nIHRoZSB0ZXh0dXJlIG9uLlxuICpcbiAqIGBnZW9tZXRyeS5odW1hbm9pZC5jdXN0b21gIGlzIHJlc29sdmVkIGJ5IHRoZSBjbGllbnQgYWdhaW5zdCBhIG1vZGVsIGl0IGFscmVhZHkgaGFzLCBzb1xuICogdGhpcyBpcyBhIHJlZmVyZW5jZSByYXRoZXIgdGhhbiBnZW9tZXRyeSB3ZSB3b3VsZCBoYXZlIHRvIHNoaXAuIGBTa2luR2VvbWV0cnlEYXRhYCBzdGF5c1xuICogZW1wdHkgZm9yIHRoZSBzYW1lIHJlYXNvbi5cbiAqL1xuZXhwb3J0IGNvbnN0IERFRkFVTFRfU0tJTl9SRVNPVVJDRV9QQVRDSCA9IEpTT04uc3RyaW5naWZ5KHtcbiAgICBnZW9tZXRyeTogeyBkZWZhdWx0OiAnZ2VvbWV0cnkuaHVtYW5vaWQuY3VzdG9tJyB9XG59KTtcbiJdLCJtYXBwaW5ncyI6Ijs7QUFDQSxJQUFhLGFBQWE7QUFDMUIsSUFBYSxjQUFjO0FBQzNCLElBQU0sa0JBQWtCO0FBbUJ4QixJQUFNLFlBQStDO0NBQUM7Q0FBTTtDQUFNO0FBQUk7QUFDdEUsSUFBTSxRQUEyQztDQUFDO0NBQU07Q0FBTTtBQUFJO0FBQ2xFLElBQU0sV0FBOEM7Q0FBQztDQUFNO0NBQU07QUFBSTtBQUdyRSxJQUFNLFVBQTZCO0NBRS9CO0VBQUUsR0FBRztFQUFHLEdBQUc7RUFBRyxPQUFPO0VBQUksUUFBUTtFQUFHLFFBQVE7R0FKQztHQUFNO0dBQU07RUFJYjtDQUFLO0NBQ2pEO0VBQUUsR0FBRztFQUFHLEdBQUc7RUFBRyxPQUFPO0VBQUksUUFBUTtFQUFHLFFBQVE7Q0FBVTtDQUV0RDtFQUFFLEdBQUc7RUFBSSxHQUFHO0VBQUksT0FBTztFQUFJLFFBQVE7RUFBSSxRQUFRO0NBQU07Q0FDckQ7RUFBRSxHQUFHO0VBQUksR0FBRztFQUFJLE9BQU87RUFBSSxRQUFRO0VBQUksUUFBUTtDQUFNO0NBQ3JEO0VBQUUsR0FBRztFQUFJLEdBQUc7RUFBSSxPQUFPO0VBQUksUUFBUTtFQUFJLFFBQVE7Q0FBTTtDQUVyRDtFQUFFLEdBQUc7RUFBRyxHQUFHO0VBQUksT0FBTztFQUFJLFFBQVE7RUFBSSxRQUFRO0NBQVM7Q0FDdkQ7RUFBRSxHQUFHO0VBQUksR0FBRztFQUFJLE9BQU87RUFBSSxRQUFRO0VBQUksUUFBUTtDQUFTO0FBQzVEOzs7Ozs7Ozs7OztBQVlBLElBQWEsK0JBQXVDO0NBQ2hELE1BQU0sUUFBUSxPQUFPLE1BQU0sT0FBMkIsZUFBZTtDQUVyRSxLQUFLLE1BQU0sVUFBVSxTQUNqQixLQUFLLElBQUksSUFBSSxPQUFPLEdBQUcsSUFBSSxPQUFPLElBQUksT0FBTyxRQUFRLEtBQ2pELEtBQUssSUFBSSxJQUFJLE9BQU8sR0FBRyxJQUFJLE9BQU8sSUFBSSxPQUFPLE9BQU8sS0FBSztFQUNyRCxNQUFNLFVBQVUsSUFBQSxLQUFpQixLQUFLO0VBR3RDLE1BQU0sUUFBUSxLQUFNLElBQUksT0FBTyxLQUFLLE9BQU8sU0FBVTtFQUNyRCxNQUFNLFVBQVUsS0FBSyxNQUFNLE9BQU8sT0FBTyxLQUFLLEtBQUs7RUFDbkQsTUFBTSxTQUFTLEtBQUssS0FBSyxNQUFNLE9BQU8sT0FBTyxLQUFLLEtBQUs7RUFDdkQsTUFBTSxTQUFTLEtBQUssS0FBSyxNQUFNLE9BQU8sT0FBTyxLQUFLLEtBQUs7RUFDdkQsTUFBTSxTQUFTLEtBQUs7Q0FDeEI7Q0FJUixPQUFPO0FBQ1g7Ozs7Ozs7O0FBU0EsSUFBYSw4QkFBOEIsS0FBSyxVQUFVLEVBQ3RELFVBQVUsRUFBRSxTQUFTLDJCQUEyQixFQUNwRCxDQUFDIn0=
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
@@ -0,0 +1,75 @@
1
+ /**
2
+ * The two JWT blobs a `Login` packet carries.
3
+ *
4
+ * Deliberately the *encoded* form rather than the data behind it: an offline provider signs
5
+ * these itself, and an Xbox one receives most of the chain already signed by Mojang and
6
+ * cannot reconstruct it. What they have in common is the pair of strings that goes on the
7
+ * wire, so that is what the interface is about.
8
+ */
9
+ export interface LoginCredentials {
10
+ /**
11
+ * `{"chain": [...]}` - one JWT per link. Offline that is a single self-signed token;
12
+ * authenticated it is the client's own token followed by Mojang's.
13
+ */
14
+ readonly chainData: string;
15
+ /** One JWT: skin, device, language, and the address the client thinks it dialled. */
16
+ readonly clientData: string;
17
+ }
18
+ /** Who the player is, as far as the login is concerned. */
19
+ export interface Identity {
20
+ /** Empty when not authenticated. A server in online mode refuses that. */
21
+ readonly xuid: string;
22
+ /** The uuid the client is known by. The server rejects a login with no identity. */
23
+ readonly identity: string;
24
+ readonly displayName: string;
25
+ readonly titleId?: string;
26
+ }
27
+ export interface LoginRequest {
28
+ /** Where we are connecting, as the client reports it: `host:port`. */
29
+ readonly serverAddress: string;
30
+ /** The protocol version being spoken, echoed into the client data. */
31
+ readonly protocolVersion: number;
32
+ }
33
+ /**
34
+ * Where a login identity comes from.
35
+ *
36
+ * The seam exists so that what the bot harness needs - hundreds of throwaway identities, no
37
+ * network, no token cache - and what a real client needs are the same shape to everything
38
+ * upstream. It is also what keeps Xbox Live out of the headless build: a provider is chosen
39
+ * at the edge, and nothing in the client core imports one.
40
+ */
41
+ export interface IAuthProvider {
42
+ /** For logs and for choosing between cached sessions. */
43
+ readonly name: string;
44
+ /**
45
+ * The identity this provider will log in as.
46
+ *
47
+ * Available before {@link createLoginCredentials} so a caller can label a connection
48
+ * before it has made one - a bot harness reporting which of five hundred it is waiting
49
+ * on, say.
50
+ */
51
+ getIdentity(): Promise<Identity>;
52
+ /**
53
+ * Signs, or fetches, the credentials for one login.
54
+ *
55
+ * Called once per connection attempt rather than cached, because the client data
56
+ * carries the address being dialled and the chain carries an expiry.
57
+ */
58
+ createLoginCredentials(request: LoginRequest): Promise<LoginCredentials>;
59
+ /**
60
+ * The public half of the key the chain is signed with, DER encoded and base64'd - the
61
+ * same string the chain's `identityPublicKey` claim carries.
62
+ *
63
+ * Encryption derives its shared secret from this key, so a provider has to expose it
64
+ * even though nothing in the login itself asks for it separately.
65
+ */
66
+ getIdentityPublicKey(): Promise<string>;
67
+ /**
68
+ * The private key, for the ECDH half of the encryption handshake.
69
+ *
70
+ * Returned as a PEM-encoded PKCS#8 string rather than a `KeyObject` so that a provider
71
+ * backed by something that is not node's crypto stays possible.
72
+ */
73
+ getIdentityPrivateKey(): Promise<string>;
74
+ }
75
+ //# sourceMappingURL=IAuthProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IAuthProvider.d.ts","sourceRoot":"","sources":["../src/IAuthProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,WAAW,gBAAgB;IAC7B;;;OAGG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,qFAAqF;IACrF,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC/B;AAED,2DAA2D;AAC3D,MAAM,WAAW,QAAQ;IACrB,0EAA0E;IAC1E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,oFAAoF;IACpF,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,YAAY;IACzB,sEAAsE;IACtE,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,sEAAsE;IACtE,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;CACpC;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,aAAa;IAC1B,yDAAyD;IACzD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB;;;;;;OAMG;IACH,WAAW,IAAI,OAAO,CAAC,QAAQ,CAAC,CAAC;IAEjC;;;;;OAKG;IACH,sBAAsB,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAEzE;;;;;;OAMG;IACH,oBAAoB,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAExC;;;;;OAKG;IACH,qBAAqB,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;CAC5C"}
File without changes
@@ -0,0 +1,190 @@
1
+ "use strict";
2
+ Object.defineProperties(exports, {
3
+ __esModule: { value: true },
4
+ [Symbol.toStringTag]: { value: "Module" }
5
+ });
6
+ const require_ClientData = require("./ClientData.cjs.cjs");
7
+ let fast_jwt = require("fast-jwt");
8
+ let node_crypto = require("node:crypto");
9
+ // src/OfflineAuthProvider.ts
10
+ /**
11
+ * The curve Bedrock's identity keys use, and the JOSE algorithm that goes with it. Not
12
+ * configurable: a server derives its encryption secret from this key, so both ends have to
13
+ * agree, and the protocol fixes the answer.
14
+ */
15
+ var CURVE = "secp384r1";
16
+ var ALGORITHM = "ES384";
17
+ /** How long a self-signed chain claims to be valid for. */
18
+ var CHAIN_LIFETIME_SECONDS = 21600;
19
+ /**
20
+ * The first protocol whose servers want a multiplayer token rather than a certificate chain.
21
+ *
22
+ * 1.26.10 moved the offline identity out of the chain: what used to be a self-signed link
23
+ * carrying `extraData` is now a self-signed OIDC token in a `Token` field beside a chain that
24
+ * exists only to hold its place. A server at or past this refuses the old shape - and refuses
25
+ * it by going quiet at the RakNet layer rather than by answering, which is why the version
26
+ * this compares against is worth stating rather than discovering.
27
+ */
28
+ var FIRST_TOKEN_PROTOCOL = 944;
29
+ /** What the token says it is for. A server checks the audience even when it verifies nothing else. */
30
+ var MULTIPLAYER_AUDIENCE = "api://auth-minecraft-services/multiplayer";
31
+ /** The value naming a self-signed identity, as opposed to one Xbox Live vouched for. */
32
+ var AUTHENTICATION_TYPE_SELF_SIGNED = 2;
33
+ /**
34
+ * A login identity that talks to nothing.
35
+ *
36
+ * The chain is a single JWT this provider signs with a key it just generated, which is
37
+ * exactly what the real client sends when it is not signed in to Xbox Live. A server in
38
+ * online mode refuses it - there is no XUID to check, and it says so - and a server with
39
+ * `online-mode` off accepts it, which covers JSPrismarine itself, a LAN game, and the
40
+ * whole of the bot harness.
41
+ *
42
+ * The key is generated per instance rather than per login. It is the identity: reusing one
43
+ * across two concurrent connections would have them claim to be the same client, and the
44
+ * encryption handshake would derive the same secret for both.
45
+ *
46
+ * @example
47
+ * ```typescript
48
+ * const auth = new OfflineAuthProvider({ displayName: 'Steve' });
49
+ * const credentials = await auth.createLoginCredentials({ serverAddress: '127.0.0.1:19132', protocolVersion: 748 });
50
+ * ```
51
+ */
52
+ var OfflineAuthProvider = class {
53
+ options;
54
+ name = "offline";
55
+ identity;
56
+ privateKeyPem;
57
+ publicKeyDer;
58
+ clientRandomId;
59
+ constructor(options) {
60
+ this.options = options;
61
+ const { publicKey, privateKey } = (0, node_crypto.generateKeyPairSync)("ec", { namedCurve: CURVE });
62
+ this.publicKeyDer = publicKey.export({
63
+ type: "spki",
64
+ format: "der"
65
+ }).toString("base64");
66
+ this.privateKeyPem = privateKey.export({
67
+ type: "pkcs8",
68
+ format: "pem"
69
+ }).toString();
70
+ this.identity = {
71
+ xuid: "",
72
+ identity: options.identity ?? (0, node_crypto.randomUUID)(),
73
+ displayName: options.displayName
74
+ };
75
+ this.clientRandomId = (0, node_crypto.randomInt)(0, 2147483647);
76
+ }
77
+ async getIdentity() {
78
+ return this.identity;
79
+ }
80
+ async getIdentityPublicKey() {
81
+ return this.publicKeyDer;
82
+ }
83
+ async getIdentityPrivateKey() {
84
+ return this.privateKeyPem;
85
+ }
86
+ async createLoginCredentials(request) {
87
+ return {
88
+ chainData: request.protocolVersion >= FIRST_TOKEN_PROTOCOL ? this.signTokenRequest() : JSON.stringify({ chain: [this.signChainLink()] }),
89
+ clientData: this.signClientData(request)
90
+ };
91
+ }
92
+ /**
93
+ * The identity as a server from 1.26.10 on wants it.
94
+ *
95
+ * The chain is one empty string. That is not a placeholder for something missing: the
96
+ * field is still read, and an offline client has no certificate to put in it, so it holds
97
+ * a link that says nothing while the `Token` beside it carries the identity. `Certificate`
98
+ * is a *string* of JSON rather than an object, which is the shape the server parses.
99
+ */
100
+ signTokenRequest() {
101
+ return JSON.stringify({
102
+ Certificate: JSON.stringify({ chain: [""] }),
103
+ AuthenticationType: AUTHENTICATION_TYPE_SELF_SIGNED,
104
+ Token: this.signMultiplayerToken()
105
+ });
106
+ }
107
+ /**
108
+ * The self-signed token that replaced the chain link.
109
+ *
110
+ * The claim names are short and unobvious because they are an identity provider's, not
111
+ * Minecraft's: `cpk` is the key the encryption handshake will use, `xid` the Xbox id an
112
+ * offline player does not have, `leguuid` the uuid that has to stand in for it. The
113
+ * PlayFab fields are sent empty rather than omitted, because a real client always sends
114
+ * them and a field that is present-and-empty is the smaller departure from that.
115
+ */
116
+ signMultiplayerToken() {
117
+ const now = Math.floor(Date.now() / 1e3);
118
+ return (0, fast_jwt.createSigner)({
119
+ algorithm: ALGORITHM,
120
+ key: this.privateKeyPem,
121
+ header: {
122
+ alg: ALGORITHM,
123
+ x5u: this.publicKeyDer
124
+ }
125
+ })({
126
+ aud: MULTIPLAYER_AUDIENCE,
127
+ nbf: now - CHAIN_LIFETIME_SECONDS,
128
+ exp: now + CHAIN_LIFETIME_SECONDS,
129
+ iat: now,
130
+ ipt: "",
131
+ mid: "",
132
+ tid: "",
133
+ cpk: this.publicKeyDer,
134
+ xid: this.identity.xuid,
135
+ xname: this.identity.displayName,
136
+ leguuid: this.identity.identity
137
+ });
138
+ }
139
+ /**
140
+ * The one link an unauthenticated chain has: self-signed, and vouching for nothing but
141
+ * itself.
142
+ *
143
+ * The `x5u` header and the `identityPublicKey` claim are the same key, which is how a
144
+ * verifier knows the token signed itself. An authenticated chain has Mojang's key in
145
+ * `x5u` and this one in the claim, and the difference between the two is the whole of
146
+ * what online mode checks.
147
+ */
148
+ signChainLink() {
149
+ const now = Math.floor(Date.now() / 1e3);
150
+ return (0, fast_jwt.createSigner)({
151
+ algorithm: ALGORITHM,
152
+ key: this.privateKeyPem,
153
+ header: {
154
+ alg: ALGORITHM,
155
+ x5u: this.publicKeyDer
156
+ }
157
+ })({
158
+ nbf: now - 60,
159
+ exp: now + CHAIN_LIFETIME_SECONDS,
160
+ iat: now,
161
+ identityPublicKey: this.publicKeyDer,
162
+ extraData: {
163
+ XUID: this.identity.xuid,
164
+ identity: this.identity.identity,
165
+ displayName: this.identity.displayName,
166
+ titleId: this.identity.titleId ?? ""
167
+ }
168
+ });
169
+ }
170
+ signClientData(request) {
171
+ return (0, fast_jwt.createSigner)({
172
+ algorithm: ALGORITHM,
173
+ key: this.privateKeyPem,
174
+ header: {
175
+ alg: ALGORITHM,
176
+ x5u: this.publicKeyDer
177
+ },
178
+ noTimestamp: true
179
+ })(require_ClientData.createClientData({
180
+ ...this.options.clientData,
181
+ serverAddress: request.serverAddress,
182
+ clientRandomId: this.clientRandomId,
183
+ selfSignedId: this.identity.identity,
184
+ displayName: this.identity.displayName
185
+ }));
186
+ }
187
+ };
188
+ exports.default = OfflineAuthProvider;
189
+
190
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiT2ZmbGluZUF1dGhQcm92aWRlci5janMuY2pzIiwibmFtZXMiOlsiZ2VuZXJhdGVLZXlQYWlyU3luYyIsInJhbmRvbVVVSUQiLCJyYW5kb21JbnQiLCJjcmVhdGVTaWduZXIiLCJjcmVhdGVDbGllbnREYXRhIl0sInNvdXJjZXMiOlsiLi4vc3JjL09mZmxpbmVBdXRoUHJvdmlkZXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgY3JlYXRlU2lnbmVyIH0gZnJvbSAnZmFzdC1qd3QnO1xuaW1wb3J0IHsgZ2VuZXJhdGVLZXlQYWlyU3luYywgcmFuZG9tSW50LCByYW5kb21VVUlEIH0gZnJvbSAnbm9kZTpjcnlwdG8nO1xuaW1wb3J0IHR5cGUgeyBDbGllbnREYXRhT3B0aW9ucyB9IGZyb20gJy4vQ2xpZW50RGF0YSc7XG5pbXBvcnQgeyBjcmVhdGVDbGllbnREYXRhIH0gZnJvbSAnLi9DbGllbnREYXRhJztcblxuaW1wb3J0IHR5cGUgeyBJQXV0aFByb3ZpZGVyLCBJZGVudGl0eSwgTG9naW5DcmVkZW50aWFscywgTG9naW5SZXF1ZXN0IH0gZnJvbSAnLi9JQXV0aFByb3ZpZGVyJztcblxuLyoqXG4gKiBUaGUgY3VydmUgQmVkcm9jaydzIGlkZW50aXR5IGtleXMgdXNlLCBhbmQgdGhlIEpPU0UgYWxnb3JpdGhtIHRoYXQgZ29lcyB3aXRoIGl0LiBOb3RcbiAqIGNvbmZpZ3VyYWJsZTogYSBzZXJ2ZXIgZGVyaXZlcyBpdHMgZW5jcnlwdGlvbiBzZWNyZXQgZnJvbSB0aGlzIGtleSwgc28gYm90aCBlbmRzIGhhdmUgdG9cbiAqIGFncmVlLCBhbmQgdGhlIHByb3RvY29sIGZpeGVzIHRoZSBhbnN3ZXIuXG4gKi9cbmNvbnN0IENVUlZFID0gJ3NlY3AzODRyMSc7XG5jb25zdCBBTEdPUklUSE0gPSAnRVMzODQnO1xuXG4vKiogSG93IGxvbmcgYSBzZWxmLXNpZ25lZCBjaGFpbiBjbGFpbXMgdG8gYmUgdmFsaWQgZm9yLiAqL1xuY29uc3QgQ0hBSU5fTElGRVRJTUVfU0VDT05EUyA9IDYgKiA2MCAqIDYwO1xuXG4vKipcbiAqIFRoZSBmaXJzdCBwcm90b2NvbCB3aG9zZSBzZXJ2ZXJzIHdhbnQgYSBtdWx0aXBsYXllciB0b2tlbiByYXRoZXIgdGhhbiBhIGNlcnRpZmljYXRlIGNoYWluLlxuICpcbiAqIDEuMjYuMTAgbW92ZWQgdGhlIG9mZmxpbmUgaWRlbnRpdHkgb3V0IG9mIHRoZSBjaGFpbjogd2hhdCB1c2VkIHRvIGJlIGEgc2VsZi1zaWduZWQgbGlua1xuICogY2FycnlpbmcgYGV4dHJhRGF0YWAgaXMgbm93IGEgc2VsZi1zaWduZWQgT0lEQyB0b2tlbiBpbiBhIGBUb2tlbmAgZmllbGQgYmVzaWRlIGEgY2hhaW4gdGhhdFxuICogZXhpc3RzIG9ubHkgdG8gaG9sZCBpdHMgcGxhY2UuIEEgc2VydmVyIGF0IG9yIHBhc3QgdGhpcyByZWZ1c2VzIHRoZSBvbGQgc2hhcGUgLSBhbmQgcmVmdXNlc1xuICogaXQgYnkgZ29pbmcgcXVpZXQgYXQgdGhlIFJha05ldCBsYXllciByYXRoZXIgdGhhbiBieSBhbnN3ZXJpbmcsIHdoaWNoIGlzIHdoeSB0aGUgdmVyc2lvblxuICogdGhpcyBjb21wYXJlcyBhZ2FpbnN0IGlzIHdvcnRoIHN0YXRpbmcgcmF0aGVyIHRoYW4gZGlzY292ZXJpbmcuXG4gKi9cbmNvbnN0IEZJUlNUX1RPS0VOX1BST1RPQ09MID0gOTQ0O1xuXG4vKiogV2hhdCB0aGUgdG9rZW4gc2F5cyBpdCBpcyBmb3IuIEEgc2VydmVyIGNoZWNrcyB0aGUgYXVkaWVuY2UgZXZlbiB3aGVuIGl0IHZlcmlmaWVzIG5vdGhpbmcgZWxzZS4gKi9cbmNvbnN0IE1VTFRJUExBWUVSX0FVRElFTkNFID0gJ2FwaTovL2F1dGgtbWluZWNyYWZ0LXNlcnZpY2VzL211bHRpcGxheWVyJztcblxuLyoqIFRoZSB2YWx1ZSBuYW1pbmcgYSBzZWxmLXNpZ25lZCBpZGVudGl0eSwgYXMgb3Bwb3NlZCB0byBvbmUgWGJveCBMaXZlIHZvdWNoZWQgZm9yLiAqL1xuY29uc3QgQVVUSEVOVElDQVRJT05fVFlQRV9TRUxGX1NJR05FRCA9IDI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgT2ZmbGluZUF1dGhPcHRpb25zIHtcbiAgICAvKiogVGhlIG5hbWUgdGhhdCBzaG93cyB1cCBpbiBjaGF0IGFuZCB0aGUgcGxheWVyIGxpc3QuICovXG4gICAgcmVhZG9ubHkgZGlzcGxheU5hbWU6IHN0cmluZztcbiAgICAvKipcbiAgICAgKiBUaGUgdXVpZCB0aGUgc2VydmVyIGtub3dzIHRoaXMgcGxheWVyIGJ5LCBzdGFibGUgYWNyb3NzIHJlY29ubmVjdHMgaWYgeW91IHN1cHBseSBpdC5cbiAgICAgKlxuICAgICAqIFdvcnRoIHN1cHBseWluZyBmb3IgYSBjbGllbnQgd2l0aCBhIHdvcmxkIHRvIGNvbWUgYmFjayB0bywgYW5kIHdvcnRoICpub3QqIHN1cHBseWluZ1xuICAgICAqIGZvciBhIGJvdCBmbGVldCwgd2hlcmUgZml2ZSBodW5kcmVkIGNvbm5lY3Rpb25zIGVhY2ggbmVlZCB0aGVpciBvd24uXG4gICAgICovXG4gICAgcmVhZG9ubHkgaWRlbnRpdHk/OiBzdHJpbmc7XG4gICAgcmVhZG9ubHkgY2xpZW50RGF0YT86IFBhcnRpYWw8Q2xpZW50RGF0YU9wdGlvbnM+O1xufVxuXG4vKipcbiAqIEEgbG9naW4gaWRlbnRpdHkgdGhhdCB0YWxrcyB0byBub3RoaW5nLlxuICpcbiAqIFRoZSBjaGFpbiBpcyBhIHNpbmdsZSBKV1QgdGhpcyBwcm92aWRlciBzaWducyB3aXRoIGEga2V5IGl0IGp1c3QgZ2VuZXJhdGVkLCB3aGljaCBpc1xuICogZXhhY3RseSB3aGF0IHRoZSByZWFsIGNsaWVudCBzZW5kcyB3aGVuIGl0IGlzIG5vdCBzaWduZWQgaW4gdG8gWGJveCBMaXZlLiBBIHNlcnZlciBpblxuICogb25saW5lIG1vZGUgcmVmdXNlcyBpdCAtIHRoZXJlIGlzIG5vIFhVSUQgdG8gY2hlY2ssIGFuZCBpdCBzYXlzIHNvIC0gYW5kIGEgc2VydmVyIHdpdGhcbiAqIGBvbmxpbmUtbW9kZWAgb2ZmIGFjY2VwdHMgaXQsIHdoaWNoIGNvdmVycyBKU1ByaXNtYXJpbmUgaXRzZWxmLCBhIExBTiBnYW1lLCBhbmQgdGhlXG4gKiB3aG9sZSBvZiB0aGUgYm90IGhhcm5lc3MuXG4gKlxuICogVGhlIGtleSBpcyBnZW5lcmF0ZWQgcGVyIGluc3RhbmNlIHJhdGhlciB0aGFuIHBlciBsb2dpbi4gSXQgaXMgdGhlIGlkZW50aXR5OiByZXVzaW5nIG9uZVxuICogYWNyb3NzIHR3byBjb25jdXJyZW50IGNvbm5lY3Rpb25zIHdvdWxkIGhhdmUgdGhlbSBjbGFpbSB0byBiZSB0aGUgc2FtZSBjbGllbnQsIGFuZCB0aGVcbiAqIGVuY3J5cHRpb24gaGFuZHNoYWtlIHdvdWxkIGRlcml2ZSB0aGUgc2FtZSBzZWNyZXQgZm9yIGJvdGguXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IGF1dGggPSBuZXcgT2ZmbGluZUF1dGhQcm92aWRlcih7IGRpc3BsYXlOYW1lOiAnU3RldmUnIH0pO1xuICogY29uc3QgY3JlZGVudGlhbHMgPSBhd2FpdCBhdXRoLmNyZWF0ZUxvZ2luQ3JlZGVudGlhbHMoeyBzZXJ2ZXJBZGRyZXNzOiAnMTI3LjAuMC4xOjE5MTMyJywgcHJvdG9jb2xWZXJzaW9uOiA3NDggfSk7XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgT2ZmbGluZUF1dGhQcm92aWRlciBpbXBsZW1lbnRzIElBdXRoUHJvdmlkZXIge1xuICAgIHB1YmxpYyByZWFkb25seSBuYW1lID0gJ29mZmxpbmUnO1xuXG4gICAgcHJpdmF0ZSByZWFkb25seSBpZGVudGl0eTogSWRlbnRpdHk7XG4gICAgcHJpdmF0ZSByZWFkb25seSBwcml2YXRlS2V5UGVtOiBzdHJpbmc7XG4gICAgcHJpdmF0ZSByZWFkb25seSBwdWJsaWNLZXlEZXI6IHN0cmluZztcbiAgICBwcml2YXRlIHJlYWRvbmx5IGNsaWVudFJhbmRvbUlkOiBudW1iZXI7XG5cbiAgICBwdWJsaWMgY29uc3RydWN0b3IocHJpdmF0ZSByZWFkb25seSBvcHRpb25zOiBPZmZsaW5lQXV0aE9wdGlvbnMpIHtcbiAgICAgICAgY29uc3QgeyBwdWJsaWNLZXksIHByaXZhdGVLZXkgfSA9IGdlbmVyYXRlS2V5UGFpclN5bmMoJ2VjJywgeyBuYW1lZEN1cnZlOiBDVVJWRSB9KTtcblxuICAgICAgICAvLyBERVIgaW5zaWRlIGJhc2U2NCwgd2hpY2ggaXMgdGhlIGZvcm0gYm90aCB0aGUgYHg1dWAgaGVhZGVyIGFuZCB0aGVcbiAgICAgICAgLy8gYGlkZW50aXR5UHVibGljS2V5YCBjbGFpbSBjYXJyeSAtIG5vdCBQRU0sIGFuZCBub3QgYSBKV0suXG4gICAgICAgIHRoaXMucHVibGljS2V5RGVyID0gcHVibGljS2V5LmV4cG9ydCh7IHR5cGU6ICdzcGtpJywgZm9ybWF0OiAnZGVyJyB9KS50b1N0cmluZygnYmFzZTY0Jyk7XG4gICAgICAgIHRoaXMucHJpdmF0ZUtleVBlbSA9IHByaXZhdGVLZXkuZXhwb3J0KHsgdHlwZTogJ3BrY3M4JywgZm9ybWF0OiAncGVtJyB9KS50b1N0cmluZygpO1xuXG4gICAgICAgIHRoaXMuaWRlbnRpdHkgPSB7XG4gICAgICAgICAgICAvLyBFbXB0eSwgYW5kIHRoYXQgaXMgdGhlIHBvaW50OiBhbiBYVUlEIGlzIHdoYXQgYW4gb2ZmbGluZSBjbGllbnQgY2Fubm90IGhhdmUsXG4gICAgICAgICAgICAvLyBhbmQgaXQgaXMgd2hhdCBhIHNlcnZlciBpbiBvbmxpbmUgbW9kZSBjaGVja3MgZm9yLlxuICAgICAgICAgICAgeHVpZDogJycsXG4gICAgICAgICAgICBpZGVudGl0eTogb3B0aW9ucy5pZGVudGl0eSA/PyByYW5kb21VVUlEKCksXG4gICAgICAgICAgICBkaXNwbGF5TmFtZTogb3B0aW9ucy5kaXNwbGF5TmFtZVxuICAgICAgICB9O1xuXG4gICAgICAgIC8vIE1vamFuZydzIGlzIGEgc2lnbmVkIDMyIGJpdCB2YWx1ZSB0aGUgY2xpZW50IHBpY2tzIG9uY2UgcGVyIHNlc3Npb24gYW5kIHRoZVxuICAgICAgICAvLyBzZXJ2ZXIgc3RvcmVzIGFnYWluc3QgdGhlIHBsYXllcjsgbm90aGluZyBkZXJpdmVzIGZyb20gaXQuXG4gICAgICAgIHRoaXMuY2xpZW50UmFuZG9tSWQgPSByYW5kb21JbnQoMCwgMHg3ZmZmZmZmZik7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIGdldElkZW50aXR5KCk6IFByb21pc2U8SWRlbnRpdHk+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaWRlbnRpdHk7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIGdldElkZW50aXR5UHVibGljS2V5KCk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgICAgIHJldHVybiB0aGlzLnB1YmxpY0tleURlcjtcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgZ2V0SWRlbnRpdHlQcml2YXRlS2V5KCk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgICAgIHJldHVybiB0aGlzLnByaXZhdGVLZXlQZW07XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIGNyZWF0ZUxvZ2luQ3JlZGVudGlhbHMocmVxdWVzdDogTG9naW5SZXF1ZXN0KTogUHJvbWlzZTxMb2dpbkNyZWRlbnRpYWxzPiB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBjaGFpbkRhdGE6XG4gICAgICAgICAgICAgICAgcmVxdWVzdC5wcm90b2NvbFZlcnNpb24gPj0gRklSU1RfVE9LRU5fUFJPVE9DT0xcbiAgICAgICAgICAgICAgICAgICAgPyB0aGlzLnNpZ25Ub2tlblJlcXVlc3QoKVxuICAgICAgICAgICAgICAgICAgICA6IEpTT04uc3RyaW5naWZ5KHsgY2hhaW46IFt0aGlzLnNpZ25DaGFpbkxpbmsoKV0gfSksXG4gICAgICAgICAgICBjbGllbnREYXRhOiB0aGlzLnNpZ25DbGllbnREYXRhKHJlcXVlc3QpXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGlkZW50aXR5IGFzIGEgc2VydmVyIGZyb20gMS4yNi4xMCBvbiB3YW50cyBpdC5cbiAgICAgKlxuICAgICAqIFRoZSBjaGFpbiBpcyBvbmUgZW1wdHkgc3RyaW5nLiBUaGF0IGlzIG5vdCBhIHBsYWNlaG9sZGVyIGZvciBzb21ldGhpbmcgbWlzc2luZzogdGhlXG4gICAgICogZmllbGQgaXMgc3RpbGwgcmVhZCwgYW5kIGFuIG9mZmxpbmUgY2xpZW50IGhhcyBubyBjZXJ0aWZpY2F0ZSB0byBwdXQgaW4gaXQsIHNvIGl0IGhvbGRzXG4gICAgICogYSBsaW5rIHRoYXQgc2F5cyBub3RoaW5nIHdoaWxlIHRoZSBgVG9rZW5gIGJlc2lkZSBpdCBjYXJyaWVzIHRoZSBpZGVudGl0eS4gYENlcnRpZmljYXRlYFxuICAgICAqIGlzIGEgKnN0cmluZyogb2YgSlNPTiByYXRoZXIgdGhhbiBhbiBvYmplY3QsIHdoaWNoIGlzIHRoZSBzaGFwZSB0aGUgc2VydmVyIHBhcnNlcy5cbiAgICAgKi9cbiAgICBwcml2YXRlIHNpZ25Ub2tlblJlcXVlc3QoKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICAgIENlcnRpZmljYXRlOiBKU09OLnN0cmluZ2lmeSh7IGNoYWluOiBbJyddIH0pLFxuICAgICAgICAgICAgQXV0aGVudGljYXRpb25UeXBlOiBBVVRIRU5USUNBVElPTl9UWVBFX1NFTEZfU0lHTkVELFxuICAgICAgICAgICAgVG9rZW46IHRoaXMuc2lnbk11bHRpcGxheWVyVG9rZW4oKVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgc2VsZi1zaWduZWQgdG9rZW4gdGhhdCByZXBsYWNlZCB0aGUgY2hhaW4gbGluay5cbiAgICAgKlxuICAgICAqIFRoZSBjbGFpbSBuYW1lcyBhcmUgc2hvcnQgYW5kIHVub2J2aW91cyBiZWNhdXNlIHRoZXkgYXJlIGFuIGlkZW50aXR5IHByb3ZpZGVyJ3MsIG5vdFxuICAgICAqIE1pbmVjcmFmdCdzOiBgY3BrYCBpcyB0aGUga2V5IHRoZSBlbmNyeXB0aW9uIGhhbmRzaGFrZSB3aWxsIHVzZSwgYHhpZGAgdGhlIFhib3ggaWQgYW5cbiAgICAgKiBvZmZsaW5lIHBsYXllciBkb2VzIG5vdCBoYXZlLCBgbGVndXVpZGAgdGhlIHV1aWQgdGhhdCBoYXMgdG8gc3RhbmQgaW4gZm9yIGl0LiBUaGVcbiAgICAgKiBQbGF5RmFiIGZpZWxkcyBhcmUgc2VudCBlbXB0eSByYXRoZXIgdGhhbiBvbWl0dGVkLCBiZWNhdXNlIGEgcmVhbCBjbGllbnQgYWx3YXlzIHNlbmRzXG4gICAgICogdGhlbSBhbmQgYSBmaWVsZCB0aGF0IGlzIHByZXNlbnQtYW5kLWVtcHR5IGlzIHRoZSBzbWFsbGVyIGRlcGFydHVyZSBmcm9tIHRoYXQuXG4gICAgICovXG4gICAgcHJpdmF0ZSBzaWduTXVsdGlwbGF5ZXJUb2tlbigpOiBzdHJpbmcge1xuICAgICAgICBjb25zdCBub3cgPSBNYXRoLmZsb29yKERhdGUubm93KCkgLyAxMDAwKTtcbiAgICAgICAgY29uc3Qgc2lnbiA9IGNyZWF0ZVNpZ25lcih7XG4gICAgICAgICAgICBhbGdvcml0aG06IEFMR09SSVRITSxcbiAgICAgICAgICAgIGtleTogdGhpcy5wcml2YXRlS2V5UGVtLFxuICAgICAgICAgICAgaGVhZGVyOiB7IGFsZzogQUxHT1JJVEhNLCB4NXU6IHRoaXMucHVibGljS2V5RGVyIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIHNpZ24oe1xuICAgICAgICAgICAgYXVkOiBNVUxUSVBMQVlFUl9BVURJRU5DRSxcbiAgICAgICAgICAgIG5iZjogbm93IC0gQ0hBSU5fTElGRVRJTUVfU0VDT05EUyxcbiAgICAgICAgICAgIGV4cDogbm93ICsgQ0hBSU5fTElGRVRJTUVfU0VDT05EUyxcbiAgICAgICAgICAgIGlhdDogbm93LFxuICAgICAgICAgICAgaXB0OiAnJyxcbiAgICAgICAgICAgIG1pZDogJycsXG4gICAgICAgICAgICB0aWQ6ICcnLFxuICAgICAgICAgICAgY3BrOiB0aGlzLnB1YmxpY0tleURlcixcbiAgICAgICAgICAgIHhpZDogdGhpcy5pZGVudGl0eS54dWlkLFxuICAgICAgICAgICAgeG5hbWU6IHRoaXMuaWRlbnRpdHkuZGlzcGxheU5hbWUsXG4gICAgICAgICAgICBsZWd1dWlkOiB0aGlzLmlkZW50aXR5LmlkZW50aXR5XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBvbmUgbGluayBhbiB1bmF1dGhlbnRpY2F0ZWQgY2hhaW4gaGFzOiBzZWxmLXNpZ25lZCwgYW5kIHZvdWNoaW5nIGZvciBub3RoaW5nIGJ1dFxuICAgICAqIGl0c2VsZi5cbiAgICAgKlxuICAgICAqIFRoZSBgeDV1YCBoZWFkZXIgYW5kIHRoZSBgaWRlbnRpdHlQdWJsaWNLZXlgIGNsYWltIGFyZSB0aGUgc2FtZSBrZXksIHdoaWNoIGlzIGhvdyBhXG4gICAgICogdmVyaWZpZXIga25vd3MgdGhlIHRva2VuIHNpZ25lZCBpdHNlbGYuIEFuIGF1dGhlbnRpY2F0ZWQgY2hhaW4gaGFzIE1vamFuZydzIGtleSBpblxuICAgICAqIGB4NXVgIGFuZCB0aGlzIG9uZSBpbiB0aGUgY2xhaW0sIGFuZCB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSB0d28gaXMgdGhlIHdob2xlIG9mXG4gICAgICogd2hhdCBvbmxpbmUgbW9kZSBjaGVja3MuXG4gICAgICovXG4gICAgcHJpdmF0ZSBzaWduQ2hhaW5MaW5rKCk6IHN0cmluZyB7XG4gICAgICAgIGNvbnN0IG5vdyA9IE1hdGguZmxvb3IoRGF0ZS5ub3coKSAvIDEwMDApO1xuICAgICAgICBjb25zdCBzaWduID0gY3JlYXRlU2lnbmVyKHtcbiAgICAgICAgICAgIGFsZ29yaXRobTogQUxHT1JJVEhNLFxuICAgICAgICAgICAga2V5OiB0aGlzLnByaXZhdGVLZXlQZW0sXG4gICAgICAgICAgICBoZWFkZXI6IHsgYWxnOiBBTEdPUklUSE0sIHg1dTogdGhpcy5wdWJsaWNLZXlEZXIgfVxuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gc2lnbih7XG4gICAgICAgICAgICBuYmY6IG5vdyAtIDYwLFxuICAgICAgICAgICAgZXhwOiBub3cgKyBDSEFJTl9MSUZFVElNRV9TRUNPTkRTLFxuICAgICAgICAgICAgaWF0OiBub3csXG4gICAgICAgICAgICBpZGVudGl0eVB1YmxpY0tleTogdGhpcy5wdWJsaWNLZXlEZXIsXG4gICAgICAgICAgICBleHRyYURhdGE6IHtcbiAgICAgICAgICAgICAgICBYVUlEOiB0aGlzLmlkZW50aXR5Lnh1aWQsXG4gICAgICAgICAgICAgICAgaWRlbnRpdHk6IHRoaXMuaWRlbnRpdHkuaWRlbnRpdHksXG4gICAgICAgICAgICAgICAgZGlzcGxheU5hbWU6IHRoaXMuaWRlbnRpdHkuZGlzcGxheU5hbWUsXG4gICAgICAgICAgICAgICAgdGl0bGVJZDogdGhpcy5pZGVudGl0eS50aXRsZUlkID8/ICcnXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgc2lnbkNsaWVudERhdGEocmVxdWVzdDogTG9naW5SZXF1ZXN0KTogc3RyaW5nIHtcbiAgICAgICAgY29uc3Qgc2lnbiA9IGNyZWF0ZVNpZ25lcih7XG4gICAgICAgICAgICBhbGdvcml0aG06IEFMR09SSVRITSxcbiAgICAgICAgICAgIGtleTogdGhpcy5wcml2YXRlS2V5UGVtLFxuICAgICAgICAgICAgaGVhZGVyOiB7IGFsZzogQUxHT1JJVEhNLCB4NXU6IHRoaXMucHVibGljS2V5RGVyIH0sXG4gICAgICAgICAgICBub1RpbWVzdGFtcDogdHJ1ZVxuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gc2lnbihcbiAgICAgICAgICAgIGNyZWF0ZUNsaWVudERhdGEoe1xuICAgICAgICAgICAgICAgIC4uLnRoaXMub3B0aW9ucy5jbGllbnREYXRhLFxuICAgICAgICAgICAgICAgIHNlcnZlckFkZHJlc3M6IHJlcXVlc3Quc2VydmVyQWRkcmVzcyxcbiAgICAgICAgICAgICAgICBjbGllbnRSYW5kb21JZDogdGhpcy5jbGllbnRSYW5kb21JZCxcbiAgICAgICAgICAgICAgICBzZWxmU2lnbmVkSWQ6IHRoaXMuaWRlbnRpdHkuaWRlbnRpdHksXG4gICAgICAgICAgICAgICAgZGlzcGxheU5hbWU6IHRoaXMuaWRlbnRpdHkuZGlzcGxheU5hbWVcbiAgICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgfVxufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7OztBQVlBLElBQU0sUUFBUTtBQUNkLElBQU0sWUFBWTs7QUFHbEIsSUFBTSx5QkFBeUI7Ozs7Ozs7Ozs7QUFXL0IsSUFBTSx1QkFBdUI7O0FBRzdCLElBQU0sdUJBQXVCOztBQUc3QixJQUFNLGtDQUFrQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFrQ3hDLElBQXFCLHNCQUFyQixNQUFrRTtDQVExQjtDQVBwQyxPQUF1QjtDQUV2QjtDQUNBO0NBQ0E7Q0FDQTtDQUVBLFlBQW1CLFNBQThDO0VBQTdCLEtBQUEsVUFBQTtFQUNoQyxNQUFNLEVBQUUsV0FBVyxnQkFBQSxHQUFlQSxZQUFBQSxvQkFBQUEsQ0FBb0IsTUFBTSxFQUFFLFlBQVksTUFBTSxDQUFDO0VBSWpGLEtBQUssZUFBZSxVQUFVLE9BQU87R0FBRSxNQUFNO0dBQVEsUUFBUTtFQUFNLENBQUMsQ0FBQyxDQUFDLFNBQVMsUUFBUTtFQUN2RixLQUFLLGdCQUFnQixXQUFXLE9BQU87R0FBRSxNQUFNO0dBQVMsUUFBUTtFQUFNLENBQUMsQ0FBQyxDQUFDLFNBQVM7RUFFbEYsS0FBSyxXQUFXO0dBR1osTUFBTTtHQUNOLFVBQVUsUUFBUSxhQUFBLEdBQVlDLFlBQUFBLFdBQUFBLENBQVc7R0FDekMsYUFBYSxRQUFRO0VBQ3pCO0VBSUEsS0FBSyxrQkFBQSxHQUFpQkMsWUFBQUEsVUFBQUEsQ0FBVSxHQUFHLFVBQVU7Q0FDakQ7Q0FFQSxNQUFhLGNBQWlDO0VBQzFDLE9BQU8sS0FBSztDQUNoQjtDQUVBLE1BQWEsdUJBQXdDO0VBQ2pELE9BQU8sS0FBSztDQUNoQjtDQUVBLE1BQWEsd0JBQXlDO0VBQ2xELE9BQU8sS0FBSztDQUNoQjtDQUVBLE1BQWEsdUJBQXVCLFNBQWtEO0VBQ2xGLE9BQU87R0FDSCxXQUNJLFFBQVEsbUJBQW1CLHVCQUNyQixLQUFLLGlCQUFpQixJQUN0QixLQUFLLFVBQVUsRUFBRSxPQUFPLENBQUMsS0FBSyxjQUFjLENBQUMsRUFBRSxDQUFDO0dBQzFELFlBQVksS0FBSyxlQUFlLE9BQU87RUFDM0M7Q0FDSjs7Ozs7Ozs7O0NBVUEsbUJBQW1DO0VBQy9CLE9BQU8sS0FBSyxVQUFVO0dBQ2xCLGFBQWEsS0FBSyxVQUFVLEVBQUUsT0FBTyxDQUFDLEVBQUUsRUFBRSxDQUFDO0dBQzNDLG9CQUFvQjtHQUNwQixPQUFPLEtBQUsscUJBQXFCO0VBQ3JDLENBQUM7Q0FDTDs7Ozs7Ozs7OztDQVdBLHVCQUF1QztFQUNuQyxNQUFNLE1BQU0sS0FBSyxNQUFNLEtBQUssSUFBSSxJQUFJLEdBQUk7RUFPeEMsUUFBQSxHQU5hQyxTQUFBQSxhQUFBQSxDQUFhO0dBQ3RCLFdBQVc7R0FDWCxLQUFLLEtBQUs7R0FDVixRQUFRO0lBQUUsS0FBSztJQUFXLEtBQUssS0FBSztHQUFhO0VBQ3JELENBRU8sQ0FBQSxDQUFLO0dBQ1IsS0FBSztHQUNMLEtBQUssTUFBTTtHQUNYLEtBQUssTUFBTTtHQUNYLEtBQUs7R0FDTCxLQUFLO0dBQ0wsS0FBSztHQUNMLEtBQUs7R0FDTCxLQUFLLEtBQUs7R0FDVixLQUFLLEtBQUssU0FBUztHQUNuQixPQUFPLEtBQUssU0FBUztHQUNyQixTQUFTLEtBQUssU0FBUztFQUMzQixDQUFDO0NBQ0w7Ozs7Ozs7Ozs7Q0FXQSxnQkFBZ0M7RUFDNUIsTUFBTSxNQUFNLEtBQUssTUFBTSxLQUFLLElBQUksSUFBSSxHQUFJO0VBT3hDLFFBQUEsR0FOYUEsU0FBQUEsYUFBQUEsQ0FBYTtHQUN0QixXQUFXO0dBQ1gsS0FBSyxLQUFLO0dBQ1YsUUFBUTtJQUFFLEtBQUs7SUFBVyxLQUFLLEtBQUs7R0FBYTtFQUNyRCxDQUVPLENBQUEsQ0FBSztHQUNSLEtBQUssTUFBTTtHQUNYLEtBQUssTUFBTTtHQUNYLEtBQUs7R0FDTCxtQkFBbUIsS0FBSztHQUN4QixXQUFXO0lBQ1AsTUFBTSxLQUFLLFNBQVM7SUFDcEIsVUFBVSxLQUFLLFNBQVM7SUFDeEIsYUFBYSxLQUFLLFNBQVM7SUFDM0IsU0FBUyxLQUFLLFNBQVMsV0FBVztHQUN0QztFQUNKLENBQUM7Q0FDTDtDQUVBLGVBQXVCLFNBQStCO0VBUWxELFFBQUEsR0FQYUEsU0FBQUEsYUFBQUEsQ0FBYTtHQUN0QixXQUFXO0dBQ1gsS0FBSyxLQUFLO0dBQ1YsUUFBUTtJQUFFLEtBQUs7SUFBVyxLQUFLLEtBQUs7R0FBYTtHQUNqRCxhQUFhO0VBQ2pCLENBRU8sQ0FBQSxDQUNIQyxtQkFBQUEsaUJBQWlCO0dBQ2IsR0FBRyxLQUFLLFFBQVE7R0FDaEIsZUFBZSxRQUFRO0dBQ3ZCLGdCQUFnQixLQUFLO0dBQ3JCLGNBQWMsS0FBSyxTQUFTO0dBQzVCLGFBQWEsS0FBSyxTQUFTO0VBQy9CLENBQUMsQ0FDTDtDQUNKO0FBQ0oifQ==
@@ -0,0 +1,77 @@
1
+ import type { ClientDataOptions } from './ClientData';
2
+ import type { IAuthProvider, Identity, LoginCredentials, LoginRequest } from './IAuthProvider';
3
+ export interface OfflineAuthOptions {
4
+ /** The name that shows up in chat and the player list. */
5
+ readonly displayName: string;
6
+ /**
7
+ * The uuid the server knows this player by, stable across reconnects if you supply it.
8
+ *
9
+ * Worth supplying for a client with a world to come back to, and worth *not* supplying
10
+ * for a bot fleet, where five hundred connections each need their own.
11
+ */
12
+ readonly identity?: string;
13
+ readonly clientData?: Partial<ClientDataOptions>;
14
+ }
15
+ /**
16
+ * A login identity that talks to nothing.
17
+ *
18
+ * The chain is a single JWT this provider signs with a key it just generated, which is
19
+ * exactly what the real client sends when it is not signed in to Xbox Live. A server in
20
+ * online mode refuses it - there is no XUID to check, and it says so - and a server with
21
+ * `online-mode` off accepts it, which covers JSPrismarine itself, a LAN game, and the
22
+ * whole of the bot harness.
23
+ *
24
+ * The key is generated per instance rather than per login. It is the identity: reusing one
25
+ * across two concurrent connections would have them claim to be the same client, and the
26
+ * encryption handshake would derive the same secret for both.
27
+ *
28
+ * @example
29
+ * ```typescript
30
+ * const auth = new OfflineAuthProvider({ displayName: 'Steve' });
31
+ * const credentials = await auth.createLoginCredentials({ serverAddress: '127.0.0.1:19132', protocolVersion: 748 });
32
+ * ```
33
+ */
34
+ export default class OfflineAuthProvider implements IAuthProvider {
35
+ private readonly options;
36
+ readonly name = "offline";
37
+ private readonly identity;
38
+ private readonly privateKeyPem;
39
+ private readonly publicKeyDer;
40
+ private readonly clientRandomId;
41
+ constructor(options: OfflineAuthOptions);
42
+ getIdentity(): Promise<Identity>;
43
+ getIdentityPublicKey(): Promise<string>;
44
+ getIdentityPrivateKey(): Promise<string>;
45
+ createLoginCredentials(request: LoginRequest): Promise<LoginCredentials>;
46
+ /**
47
+ * The identity as a server from 1.26.10 on wants it.
48
+ *
49
+ * The chain is one empty string. That is not a placeholder for something missing: the
50
+ * field is still read, and an offline client has no certificate to put in it, so it holds
51
+ * a link that says nothing while the `Token` beside it carries the identity. `Certificate`
52
+ * is a *string* of JSON rather than an object, which is the shape the server parses.
53
+ */
54
+ private signTokenRequest;
55
+ /**
56
+ * The self-signed token that replaced the chain link.
57
+ *
58
+ * The claim names are short and unobvious because they are an identity provider's, not
59
+ * Minecraft's: `cpk` is the key the encryption handshake will use, `xid` the Xbox id an
60
+ * offline player does not have, `leguuid` the uuid that has to stand in for it. The
61
+ * PlayFab fields are sent empty rather than omitted, because a real client always sends
62
+ * them and a field that is present-and-empty is the smaller departure from that.
63
+ */
64
+ private signMultiplayerToken;
65
+ /**
66
+ * The one link an unauthenticated chain has: self-signed, and vouching for nothing but
67
+ * itself.
68
+ *
69
+ * The `x5u` header and the `identityPublicKey` claim are the same key, which is how a
70
+ * verifier knows the token signed itself. An authenticated chain has Mojang's key in
71
+ * `x5u` and this one in the claim, and the difference between the two is the whole of
72
+ * what online mode checks.
73
+ */
74
+ private signChainLink;
75
+ private signClientData;
76
+ }
77
+ //# sourceMappingURL=OfflineAuthProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OfflineAuthProvider.d.ts","sourceRoot":"","sources":["../src/OfflineAuthProvider.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAGtD,OAAO,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AA8B/F,MAAM,WAAW,kBAAkB;IAC/B,0DAA0D;IAC1D,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC;CACpD;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,CAAC,OAAO,OAAO,mBAAoB,YAAW,aAAa;IAQ1C,OAAO,CAAC,QAAQ,CAAC,OAAO;IAP3C,SAAgB,IAAI,aAAa;IAEjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAW;IACpC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IAExC,YAAoC,OAAO,EAAE,kBAAkB,EAmB9D;IAEY,WAAW,IAAI,OAAO,CAAC,QAAQ,CAAC,CAE5C;IAEY,oBAAoB,IAAI,OAAO,CAAC,MAAM,CAAC,CAEnD;IAEY,qBAAqB,IAAI,OAAO,CAAC,MAAM,CAAC,CAEpD;IAEY,sBAAsB,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAQpF;IAED;;;;;;;OAOG;IACH,OAAO,CAAC,gBAAgB;IAQxB;;;;;;;;OAQG;IACH,OAAO,CAAC,oBAAoB;IAuB5B;;;;;;;;OAQG;IACH,OAAO,CAAC,aAAa;IAsBrB,OAAO,CAAC,cAAc;CAkBzB"}