@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.
- package/LICENSE +373 -0
- package/README.md +25 -2
- package/dist/ClientData.cjs.cjs +52 -0
- package/dist/ClientData.d.ts +84 -0
- package/dist/ClientData.d.ts.map +1 -0
- package/dist/ClientData.es.js +50 -0
- package/dist/DefaultSkin.cjs.cjs +113 -0
- package/dist/DefaultSkin.d.ts +23 -0
- package/dist/DefaultSkin.d.ts.map +1 -0
- package/dist/DefaultSkin.es.js +108 -0
- package/dist/IAuthProvider.cjs.cjs +2 -0
- package/dist/IAuthProvider.d.ts +75 -0
- package/dist/IAuthProvider.d.ts.map +1 -0
- package/dist/IAuthProvider.es.js +0 -0
- package/dist/OfflineAuthProvider.cjs.cjs +190 -0
- package/dist/OfflineAuthProvider.d.ts +77 -0
- package/dist/OfflineAuthProvider.d.ts.map +1 -0
- package/dist/OfflineAuthProvider.es.js +185 -0
- package/dist/index.cjs.cjs +11 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.es.js +4 -0
- package/package.json +61 -3
|
@@ -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,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"}
|