@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,185 @@
1
+ import { createClientData } from "./ClientData.es.js";
2
+ import { createSigner } from "fast-jwt";
3
+ import { generateKeyPairSync, randomInt, randomUUID } from "node:crypto";
4
+ // src/OfflineAuthProvider.ts
5
+ /**
6
+ * The curve Bedrock's identity keys use, and the JOSE algorithm that goes with it. Not
7
+ * configurable: a server derives its encryption secret from this key, so both ends have to
8
+ * agree, and the protocol fixes the answer.
9
+ */
10
+ var CURVE = "secp384r1";
11
+ var ALGORITHM = "ES384";
12
+ /** How long a self-signed chain claims to be valid for. */
13
+ var CHAIN_LIFETIME_SECONDS = 21600;
14
+ /**
15
+ * The first protocol whose servers want a multiplayer token rather than a certificate chain.
16
+ *
17
+ * 1.26.10 moved the offline identity out of the chain: what used to be a self-signed link
18
+ * carrying `extraData` is now a self-signed OIDC token in a `Token` field beside a chain that
19
+ * exists only to hold its place. A server at or past this refuses the old shape - and refuses
20
+ * it by going quiet at the RakNet layer rather than by answering, which is why the version
21
+ * this compares against is worth stating rather than discovering.
22
+ */
23
+ var FIRST_TOKEN_PROTOCOL = 944;
24
+ /** What the token says it is for. A server checks the audience even when it verifies nothing else. */
25
+ var MULTIPLAYER_AUDIENCE = "api://auth-minecraft-services/multiplayer";
26
+ /** The value naming a self-signed identity, as opposed to one Xbox Live vouched for. */
27
+ var AUTHENTICATION_TYPE_SELF_SIGNED = 2;
28
+ /**
29
+ * A login identity that talks to nothing.
30
+ *
31
+ * The chain is a single JWT this provider signs with a key it just generated, which is
32
+ * exactly what the real client sends when it is not signed in to Xbox Live. A server in
33
+ * online mode refuses it - there is no XUID to check, and it says so - and a server with
34
+ * `online-mode` off accepts it, which covers JSPrismarine itself, a LAN game, and the
35
+ * whole of the bot harness.
36
+ *
37
+ * The key is generated per instance rather than per login. It is the identity: reusing one
38
+ * across two concurrent connections would have them claim to be the same client, and the
39
+ * encryption handshake would derive the same secret for both.
40
+ *
41
+ * @example
42
+ * ```typescript
43
+ * const auth = new OfflineAuthProvider({ displayName: 'Steve' });
44
+ * const credentials = await auth.createLoginCredentials({ serverAddress: '127.0.0.1:19132', protocolVersion: 748 });
45
+ * ```
46
+ */
47
+ var OfflineAuthProvider = class {
48
+ options;
49
+ name = "offline";
50
+ identity;
51
+ privateKeyPem;
52
+ publicKeyDer;
53
+ clientRandomId;
54
+ constructor(options) {
55
+ this.options = options;
56
+ const { publicKey, privateKey } = generateKeyPairSync("ec", { namedCurve: CURVE });
57
+ this.publicKeyDer = publicKey.export({
58
+ type: "spki",
59
+ format: "der"
60
+ }).toString("base64");
61
+ this.privateKeyPem = privateKey.export({
62
+ type: "pkcs8",
63
+ format: "pem"
64
+ }).toString();
65
+ this.identity = {
66
+ xuid: "",
67
+ identity: options.identity ?? randomUUID(),
68
+ displayName: options.displayName
69
+ };
70
+ this.clientRandomId = randomInt(0, 2147483647);
71
+ }
72
+ async getIdentity() {
73
+ return this.identity;
74
+ }
75
+ async getIdentityPublicKey() {
76
+ return this.publicKeyDer;
77
+ }
78
+ async getIdentityPrivateKey() {
79
+ return this.privateKeyPem;
80
+ }
81
+ async createLoginCredentials(request) {
82
+ return {
83
+ chainData: request.protocolVersion >= FIRST_TOKEN_PROTOCOL ? this.signTokenRequest() : JSON.stringify({ chain: [this.signChainLink()] }),
84
+ clientData: this.signClientData(request)
85
+ };
86
+ }
87
+ /**
88
+ * The identity as a server from 1.26.10 on wants it.
89
+ *
90
+ * The chain is one empty string. That is not a placeholder for something missing: the
91
+ * field is still read, and an offline client has no certificate to put in it, so it holds
92
+ * a link that says nothing while the `Token` beside it carries the identity. `Certificate`
93
+ * is a *string* of JSON rather than an object, which is the shape the server parses.
94
+ */
95
+ signTokenRequest() {
96
+ return JSON.stringify({
97
+ Certificate: JSON.stringify({ chain: [""] }),
98
+ AuthenticationType: AUTHENTICATION_TYPE_SELF_SIGNED,
99
+ Token: this.signMultiplayerToken()
100
+ });
101
+ }
102
+ /**
103
+ * The self-signed token that replaced the chain link.
104
+ *
105
+ * The claim names are short and unobvious because they are an identity provider's, not
106
+ * Minecraft's: `cpk` is the key the encryption handshake will use, `xid` the Xbox id an
107
+ * offline player does not have, `leguuid` the uuid that has to stand in for it. The
108
+ * PlayFab fields are sent empty rather than omitted, because a real client always sends
109
+ * them and a field that is present-and-empty is the smaller departure from that.
110
+ */
111
+ signMultiplayerToken() {
112
+ const now = Math.floor(Date.now() / 1e3);
113
+ return createSigner({
114
+ algorithm: ALGORITHM,
115
+ key: this.privateKeyPem,
116
+ header: {
117
+ alg: ALGORITHM,
118
+ x5u: this.publicKeyDer
119
+ }
120
+ })({
121
+ aud: MULTIPLAYER_AUDIENCE,
122
+ nbf: now - CHAIN_LIFETIME_SECONDS,
123
+ exp: now + CHAIN_LIFETIME_SECONDS,
124
+ iat: now,
125
+ ipt: "",
126
+ mid: "",
127
+ tid: "",
128
+ cpk: this.publicKeyDer,
129
+ xid: this.identity.xuid,
130
+ xname: this.identity.displayName,
131
+ leguuid: this.identity.identity
132
+ });
133
+ }
134
+ /**
135
+ * The one link an unauthenticated chain has: self-signed, and vouching for nothing but
136
+ * itself.
137
+ *
138
+ * The `x5u` header and the `identityPublicKey` claim are the same key, which is how a
139
+ * verifier knows the token signed itself. An authenticated chain has Mojang's key in
140
+ * `x5u` and this one in the claim, and the difference between the two is the whole of
141
+ * what online mode checks.
142
+ */
143
+ signChainLink() {
144
+ const now = Math.floor(Date.now() / 1e3);
145
+ return createSigner({
146
+ algorithm: ALGORITHM,
147
+ key: this.privateKeyPem,
148
+ header: {
149
+ alg: ALGORITHM,
150
+ x5u: this.publicKeyDer
151
+ }
152
+ })({
153
+ nbf: now - 60,
154
+ exp: now + CHAIN_LIFETIME_SECONDS,
155
+ iat: now,
156
+ identityPublicKey: this.publicKeyDer,
157
+ extraData: {
158
+ XUID: this.identity.xuid,
159
+ identity: this.identity.identity,
160
+ displayName: this.identity.displayName,
161
+ titleId: this.identity.titleId ?? ""
162
+ }
163
+ });
164
+ }
165
+ signClientData(request) {
166
+ return createSigner({
167
+ algorithm: ALGORITHM,
168
+ key: this.privateKeyPem,
169
+ header: {
170
+ alg: ALGORITHM,
171
+ x5u: this.publicKeyDer
172
+ },
173
+ noTimestamp: true
174
+ })(createClientData({
175
+ ...this.options.clientData,
176
+ serverAddress: request.serverAddress,
177
+ clientRandomId: this.clientRandomId,
178
+ selfSignedId: this.identity.identity,
179
+ displayName: this.identity.displayName
180
+ }));
181
+ }
182
+ };
183
+ export { OfflineAuthProvider as default };
184
+
185
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiT2ZmbGluZUF1dGhQcm92aWRlci5lcy5qcyIsIm5hbWVzIjpbXSwic291cmNlcyI6WyIuLi9zcmMvT2ZmbGluZUF1dGhQcm92aWRlci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBjcmVhdGVTaWduZXIgfSBmcm9tICdmYXN0LWp3dCc7XG5pbXBvcnQgeyBnZW5lcmF0ZUtleVBhaXJTeW5jLCByYW5kb21JbnQsIHJhbmRvbVVVSUQgfSBmcm9tICdub2RlOmNyeXB0byc7XG5pbXBvcnQgdHlwZSB7IENsaWVudERhdGFPcHRpb25zIH0gZnJvbSAnLi9DbGllbnREYXRhJztcbmltcG9ydCB7IGNyZWF0ZUNsaWVudERhdGEgfSBmcm9tICcuL0NsaWVudERhdGEnO1xuXG5pbXBvcnQgdHlwZSB7IElBdXRoUHJvdmlkZXIsIElkZW50aXR5LCBMb2dpbkNyZWRlbnRpYWxzLCBMb2dpblJlcXVlc3QgfSBmcm9tICcuL0lBdXRoUHJvdmlkZXInO1xuXG4vKipcbiAqIFRoZSBjdXJ2ZSBCZWRyb2NrJ3MgaWRlbnRpdHkga2V5cyB1c2UsIGFuZCB0aGUgSk9TRSBhbGdvcml0aG0gdGhhdCBnb2VzIHdpdGggaXQuIE5vdFxuICogY29uZmlndXJhYmxlOiBhIHNlcnZlciBkZXJpdmVzIGl0cyBlbmNyeXB0aW9uIHNlY3JldCBmcm9tIHRoaXMga2V5LCBzbyBib3RoIGVuZHMgaGF2ZSB0b1xuICogYWdyZWUsIGFuZCB0aGUgcHJvdG9jb2wgZml4ZXMgdGhlIGFuc3dlci5cbiAqL1xuY29uc3QgQ1VSVkUgPSAnc2VjcDM4NHIxJztcbmNvbnN0IEFMR09SSVRITSA9ICdFUzM4NCc7XG5cbi8qKiBIb3cgbG9uZyBhIHNlbGYtc2lnbmVkIGNoYWluIGNsYWltcyB0byBiZSB2YWxpZCBmb3IuICovXG5jb25zdCBDSEFJTl9MSUZFVElNRV9TRUNPTkRTID0gNiAqIDYwICogNjA7XG5cbi8qKlxuICogVGhlIGZpcnN0IHByb3RvY29sIHdob3NlIHNlcnZlcnMgd2FudCBhIG11bHRpcGxheWVyIHRva2VuIHJhdGhlciB0aGFuIGEgY2VydGlmaWNhdGUgY2hhaW4uXG4gKlxuICogMS4yNi4xMCBtb3ZlZCB0aGUgb2ZmbGluZSBpZGVudGl0eSBvdXQgb2YgdGhlIGNoYWluOiB3aGF0IHVzZWQgdG8gYmUgYSBzZWxmLXNpZ25lZCBsaW5rXG4gKiBjYXJyeWluZyBgZXh0cmFEYXRhYCBpcyBub3cgYSBzZWxmLXNpZ25lZCBPSURDIHRva2VuIGluIGEgYFRva2VuYCBmaWVsZCBiZXNpZGUgYSBjaGFpbiB0aGF0XG4gKiBleGlzdHMgb25seSB0byBob2xkIGl0cyBwbGFjZS4gQSBzZXJ2ZXIgYXQgb3IgcGFzdCB0aGlzIHJlZnVzZXMgdGhlIG9sZCBzaGFwZSAtIGFuZCByZWZ1c2VzXG4gKiBpdCBieSBnb2luZyBxdWlldCBhdCB0aGUgUmFrTmV0IGxheWVyIHJhdGhlciB0aGFuIGJ5IGFuc3dlcmluZywgd2hpY2ggaXMgd2h5IHRoZSB2ZXJzaW9uXG4gKiB0aGlzIGNvbXBhcmVzIGFnYWluc3QgaXMgd29ydGggc3RhdGluZyByYXRoZXIgdGhhbiBkaXNjb3ZlcmluZy5cbiAqL1xuY29uc3QgRklSU1RfVE9LRU5fUFJPVE9DT0wgPSA5NDQ7XG5cbi8qKiBXaGF0IHRoZSB0b2tlbiBzYXlzIGl0IGlzIGZvci4gQSBzZXJ2ZXIgY2hlY2tzIHRoZSBhdWRpZW5jZSBldmVuIHdoZW4gaXQgdmVyaWZpZXMgbm90aGluZyBlbHNlLiAqL1xuY29uc3QgTVVMVElQTEFZRVJfQVVESUVOQ0UgPSAnYXBpOi8vYXV0aC1taW5lY3JhZnQtc2VydmljZXMvbXVsdGlwbGF5ZXInO1xuXG4vKiogVGhlIHZhbHVlIG5hbWluZyBhIHNlbGYtc2lnbmVkIGlkZW50aXR5LCBhcyBvcHBvc2VkIHRvIG9uZSBYYm94IExpdmUgdm91Y2hlZCBmb3IuICovXG5jb25zdCBBVVRIRU5USUNBVElPTl9UWVBFX1NFTEZfU0lHTkVEID0gMjtcblxuZXhwb3J0IGludGVyZmFjZSBPZmZsaW5lQXV0aE9wdGlvbnMge1xuICAgIC8qKiBUaGUgbmFtZSB0aGF0IHNob3dzIHVwIGluIGNoYXQgYW5kIHRoZSBwbGF5ZXIgbGlzdC4gKi9cbiAgICByZWFkb25seSBkaXNwbGF5TmFtZTogc3RyaW5nO1xuICAgIC8qKlxuICAgICAqIFRoZSB1dWlkIHRoZSBzZXJ2ZXIga25vd3MgdGhpcyBwbGF5ZXIgYnksIHN0YWJsZSBhY3Jvc3MgcmVjb25uZWN0cyBpZiB5b3Ugc3VwcGx5IGl0LlxuICAgICAqXG4gICAgICogV29ydGggc3VwcGx5aW5nIGZvciBhIGNsaWVudCB3aXRoIGEgd29ybGQgdG8gY29tZSBiYWNrIHRvLCBhbmQgd29ydGggKm5vdCogc3VwcGx5aW5nXG4gICAgICogZm9yIGEgYm90IGZsZWV0LCB3aGVyZSBmaXZlIGh1bmRyZWQgY29ubmVjdGlvbnMgZWFjaCBuZWVkIHRoZWlyIG93bi5cbiAgICAgKi9cbiAgICByZWFkb25seSBpZGVudGl0eT86IHN0cmluZztcbiAgICByZWFkb25seSBjbGllbnREYXRhPzogUGFydGlhbDxDbGllbnREYXRhT3B0aW9ucz47XG59XG5cbi8qKlxuICogQSBsb2dpbiBpZGVudGl0eSB0aGF0IHRhbGtzIHRvIG5vdGhpbmcuXG4gKlxuICogVGhlIGNoYWluIGlzIGEgc2luZ2xlIEpXVCB0aGlzIHByb3ZpZGVyIHNpZ25zIHdpdGggYSBrZXkgaXQganVzdCBnZW5lcmF0ZWQsIHdoaWNoIGlzXG4gKiBleGFjdGx5IHdoYXQgdGhlIHJlYWwgY2xpZW50IHNlbmRzIHdoZW4gaXQgaXMgbm90IHNpZ25lZCBpbiB0byBYYm94IExpdmUuIEEgc2VydmVyIGluXG4gKiBvbmxpbmUgbW9kZSByZWZ1c2VzIGl0IC0gdGhlcmUgaXMgbm8gWFVJRCB0byBjaGVjaywgYW5kIGl0IHNheXMgc28gLSBhbmQgYSBzZXJ2ZXIgd2l0aFxuICogYG9ubGluZS1tb2RlYCBvZmYgYWNjZXB0cyBpdCwgd2hpY2ggY292ZXJzIEpTUHJpc21hcmluZSBpdHNlbGYsIGEgTEFOIGdhbWUsIGFuZCB0aGVcbiAqIHdob2xlIG9mIHRoZSBib3QgaGFybmVzcy5cbiAqXG4gKiBUaGUga2V5IGlzIGdlbmVyYXRlZCBwZXIgaW5zdGFuY2UgcmF0aGVyIHRoYW4gcGVyIGxvZ2luLiBJdCBpcyB0aGUgaWRlbnRpdHk6IHJldXNpbmcgb25lXG4gKiBhY3Jvc3MgdHdvIGNvbmN1cnJlbnQgY29ubmVjdGlvbnMgd291bGQgaGF2ZSB0aGVtIGNsYWltIHRvIGJlIHRoZSBzYW1lIGNsaWVudCwgYW5kIHRoZVxuICogZW5jcnlwdGlvbiBoYW5kc2hha2Ugd291bGQgZGVyaXZlIHRoZSBzYW1lIHNlY3JldCBmb3IgYm90aC5cbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgYXV0aCA9IG5ldyBPZmZsaW5lQXV0aFByb3ZpZGVyKHsgZGlzcGxheU5hbWU6ICdTdGV2ZScgfSk7XG4gKiBjb25zdCBjcmVkZW50aWFscyA9IGF3YWl0IGF1dGguY3JlYXRlTG9naW5DcmVkZW50aWFscyh7IHNlcnZlckFkZHJlc3M6ICcxMjcuMC4wLjE6MTkxMzInLCBwcm90b2NvbFZlcnNpb246IDc0OCB9KTtcbiAqIGBgYFxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBPZmZsaW5lQXV0aFByb3ZpZGVyIGltcGxlbWVudHMgSUF1dGhQcm92aWRlciB7XG4gICAgcHVibGljIHJlYWRvbmx5IG5hbWUgPSAnb2ZmbGluZSc7XG5cbiAgICBwcml2YXRlIHJlYWRvbmx5IGlkZW50aXR5OiBJZGVudGl0eTtcbiAgICBwcml2YXRlIHJlYWRvbmx5IHByaXZhdGVLZXlQZW06IHN0cmluZztcbiAgICBwcml2YXRlIHJlYWRvbmx5IHB1YmxpY0tleURlcjogc3RyaW5nO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgY2xpZW50UmFuZG9tSWQ6IG51bWJlcjtcblxuICAgIHB1YmxpYyBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IG9wdGlvbnM6IE9mZmxpbmVBdXRoT3B0aW9ucykge1xuICAgICAgICBjb25zdCB7IHB1YmxpY0tleSwgcHJpdmF0ZUtleSB9ID0gZ2VuZXJhdGVLZXlQYWlyU3luYygnZWMnLCB7IG5hbWVkQ3VydmU6IENVUlZFIH0pO1xuXG4gICAgICAgIC8vIERFUiBpbnNpZGUgYmFzZTY0LCB3aGljaCBpcyB0aGUgZm9ybSBib3RoIHRoZSBgeDV1YCBoZWFkZXIgYW5kIHRoZVxuICAgICAgICAvLyBgaWRlbnRpdHlQdWJsaWNLZXlgIGNsYWltIGNhcnJ5IC0gbm90IFBFTSwgYW5kIG5vdCBhIEpXSy5cbiAgICAgICAgdGhpcy5wdWJsaWNLZXlEZXIgPSBwdWJsaWNLZXkuZXhwb3J0KHsgdHlwZTogJ3Nwa2knLCBmb3JtYXQ6ICdkZXInIH0pLnRvU3RyaW5nKCdiYXNlNjQnKTtcbiAgICAgICAgdGhpcy5wcml2YXRlS2V5UGVtID0gcHJpdmF0ZUtleS5leHBvcnQoeyB0eXBlOiAncGtjczgnLCBmb3JtYXQ6ICdwZW0nIH0pLnRvU3RyaW5nKCk7XG5cbiAgICAgICAgdGhpcy5pZGVudGl0eSA9IHtcbiAgICAgICAgICAgIC8vIEVtcHR5LCBhbmQgdGhhdCBpcyB0aGUgcG9pbnQ6IGFuIFhVSUQgaXMgd2hhdCBhbiBvZmZsaW5lIGNsaWVudCBjYW5ub3QgaGF2ZSxcbiAgICAgICAgICAgIC8vIGFuZCBpdCBpcyB3aGF0IGEgc2VydmVyIGluIG9ubGluZSBtb2RlIGNoZWNrcyBmb3IuXG4gICAgICAgICAgICB4dWlkOiAnJyxcbiAgICAgICAgICAgIGlkZW50aXR5OiBvcHRpb25zLmlkZW50aXR5ID8/IHJhbmRvbVVVSUQoKSxcbiAgICAgICAgICAgIGRpc3BsYXlOYW1lOiBvcHRpb25zLmRpc3BsYXlOYW1lXG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gTW9qYW5nJ3MgaXMgYSBzaWduZWQgMzIgYml0IHZhbHVlIHRoZSBjbGllbnQgcGlja3Mgb25jZSBwZXIgc2Vzc2lvbiBhbmQgdGhlXG4gICAgICAgIC8vIHNlcnZlciBzdG9yZXMgYWdhaW5zdCB0aGUgcGxheWVyOyBub3RoaW5nIGRlcml2ZXMgZnJvbSBpdC5cbiAgICAgICAgdGhpcy5jbGllbnRSYW5kb21JZCA9IHJhbmRvbUludCgwLCAweDdmZmZmZmZmKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgZ2V0SWRlbnRpdHkoKTogUHJvbWlzZTxJZGVudGl0eT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5pZGVudGl0eTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgZ2V0SWRlbnRpdHlQdWJsaWNLZXkoKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMucHVibGljS2V5RGVyO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBnZXRJZGVudGl0eVByaXZhdGVLZXkoKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMucHJpdmF0ZUtleVBlbTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgY3JlYXRlTG9naW5DcmVkZW50aWFscyhyZXF1ZXN0OiBMb2dpblJlcXVlc3QpOiBQcm9taXNlPExvZ2luQ3JlZGVudGlhbHM+IHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNoYWluRGF0YTpcbiAgICAgICAgICAgICAgICByZXF1ZXN0LnByb3RvY29sVmVyc2lvbiA+PSBGSVJTVF9UT0tFTl9QUk9UT0NPTFxuICAgICAgICAgICAgICAgICAgICA/IHRoaXMuc2lnblRva2VuUmVxdWVzdCgpXG4gICAgICAgICAgICAgICAgICAgIDogSlNPTi5zdHJpbmdpZnkoeyBjaGFpbjogW3RoaXMuc2lnbkNoYWluTGluaygpXSB9KSxcbiAgICAgICAgICAgIGNsaWVudERhdGE6IHRoaXMuc2lnbkNsaWVudERhdGEocmVxdWVzdClcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgaWRlbnRpdHkgYXMgYSBzZXJ2ZXIgZnJvbSAxLjI2LjEwIG9uIHdhbnRzIGl0LlxuICAgICAqXG4gICAgICogVGhlIGNoYWluIGlzIG9uZSBlbXB0eSBzdHJpbmcuIFRoYXQgaXMgbm90IGEgcGxhY2Vob2xkZXIgZm9yIHNvbWV0aGluZyBtaXNzaW5nOiB0aGVcbiAgICAgKiBmaWVsZCBpcyBzdGlsbCByZWFkLCBhbmQgYW4gb2ZmbGluZSBjbGllbnQgaGFzIG5vIGNlcnRpZmljYXRlIHRvIHB1dCBpbiBpdCwgc28gaXQgaG9sZHNcbiAgICAgKiBhIGxpbmsgdGhhdCBzYXlzIG5vdGhpbmcgd2hpbGUgdGhlIGBUb2tlbmAgYmVzaWRlIGl0IGNhcnJpZXMgdGhlIGlkZW50aXR5LiBgQ2VydGlmaWNhdGVgXG4gICAgICogaXMgYSAqc3RyaW5nKiBvZiBKU09OIHJhdGhlciB0aGFuIGFuIG9iamVjdCwgd2hpY2ggaXMgdGhlIHNoYXBlIHRoZSBzZXJ2ZXIgcGFyc2VzLlxuICAgICAqL1xuICAgIHByaXZhdGUgc2lnblRva2VuUmVxdWVzdCgpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgQ2VydGlmaWNhdGU6IEpTT04uc3RyaW5naWZ5KHsgY2hhaW46IFsnJ10gfSksXG4gICAgICAgICAgICBBdXRoZW50aWNhdGlvblR5cGU6IEFVVEhFTlRJQ0FUSU9OX1RZUEVfU0VMRl9TSUdORUQsXG4gICAgICAgICAgICBUb2tlbjogdGhpcy5zaWduTXVsdGlwbGF5ZXJUb2tlbigpXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBzZWxmLXNpZ25lZCB0b2tlbiB0aGF0IHJlcGxhY2VkIHRoZSBjaGFpbiBsaW5rLlxuICAgICAqXG4gICAgICogVGhlIGNsYWltIG5hbWVzIGFyZSBzaG9ydCBhbmQgdW5vYnZpb3VzIGJlY2F1c2UgdGhleSBhcmUgYW4gaWRlbnRpdHkgcHJvdmlkZXIncywgbm90XG4gICAgICogTWluZWNyYWZ0J3M6IGBjcGtgIGlzIHRoZSBrZXkgdGhlIGVuY3J5cHRpb24gaGFuZHNoYWtlIHdpbGwgdXNlLCBgeGlkYCB0aGUgWGJveCBpZCBhblxuICAgICAqIG9mZmxpbmUgcGxheWVyIGRvZXMgbm90IGhhdmUsIGBsZWd1dWlkYCB0aGUgdXVpZCB0aGF0IGhhcyB0byBzdGFuZCBpbiBmb3IgaXQuIFRoZVxuICAgICAqIFBsYXlGYWIgZmllbGRzIGFyZSBzZW50IGVtcHR5IHJhdGhlciB0aGFuIG9taXR0ZWQsIGJlY2F1c2UgYSByZWFsIGNsaWVudCBhbHdheXMgc2VuZHNcbiAgICAgKiB0aGVtIGFuZCBhIGZpZWxkIHRoYXQgaXMgcHJlc2VudC1hbmQtZW1wdHkgaXMgdGhlIHNtYWxsZXIgZGVwYXJ0dXJlIGZyb20gdGhhdC5cbiAgICAgKi9cbiAgICBwcml2YXRlIHNpZ25NdWx0aXBsYXllclRva2VuKCk6IHN0cmluZyB7XG4gICAgICAgIGNvbnN0IG5vdyA9IE1hdGguZmxvb3IoRGF0ZS5ub3coKSAvIDEwMDApO1xuICAgICAgICBjb25zdCBzaWduID0gY3JlYXRlU2lnbmVyKHtcbiAgICAgICAgICAgIGFsZ29yaXRobTogQUxHT1JJVEhNLFxuICAgICAgICAgICAga2V5OiB0aGlzLnByaXZhdGVLZXlQZW0sXG4gICAgICAgICAgICBoZWFkZXI6IHsgYWxnOiBBTEdPUklUSE0sIHg1dTogdGhpcy5wdWJsaWNLZXlEZXIgfVxuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gc2lnbih7XG4gICAgICAgICAgICBhdWQ6IE1VTFRJUExBWUVSX0FVRElFTkNFLFxuICAgICAgICAgICAgbmJmOiBub3cgLSBDSEFJTl9MSUZFVElNRV9TRUNPTkRTLFxuICAgICAgICAgICAgZXhwOiBub3cgKyBDSEFJTl9MSUZFVElNRV9TRUNPTkRTLFxuICAgICAgICAgICAgaWF0OiBub3csXG4gICAgICAgICAgICBpcHQ6ICcnLFxuICAgICAgICAgICAgbWlkOiAnJyxcbiAgICAgICAgICAgIHRpZDogJycsXG4gICAgICAgICAgICBjcGs6IHRoaXMucHVibGljS2V5RGVyLFxuICAgICAgICAgICAgeGlkOiB0aGlzLmlkZW50aXR5Lnh1aWQsXG4gICAgICAgICAgICB4bmFtZTogdGhpcy5pZGVudGl0eS5kaXNwbGF5TmFtZSxcbiAgICAgICAgICAgIGxlZ3V1aWQ6IHRoaXMuaWRlbnRpdHkuaWRlbnRpdHlcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIG9uZSBsaW5rIGFuIHVuYXV0aGVudGljYXRlZCBjaGFpbiBoYXM6IHNlbGYtc2lnbmVkLCBhbmQgdm91Y2hpbmcgZm9yIG5vdGhpbmcgYnV0XG4gICAgICogaXRzZWxmLlxuICAgICAqXG4gICAgICogVGhlIGB4NXVgIGhlYWRlciBhbmQgdGhlIGBpZGVudGl0eVB1YmxpY0tleWAgY2xhaW0gYXJlIHRoZSBzYW1lIGtleSwgd2hpY2ggaXMgaG93IGFcbiAgICAgKiB2ZXJpZmllciBrbm93cyB0aGUgdG9rZW4gc2lnbmVkIGl0c2VsZi4gQW4gYXV0aGVudGljYXRlZCBjaGFpbiBoYXMgTW9qYW5nJ3Mga2V5IGluXG4gICAgICogYHg1dWAgYW5kIHRoaXMgb25lIGluIHRoZSBjbGFpbSwgYW5kIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIHR3byBpcyB0aGUgd2hvbGUgb2ZcbiAgICAgKiB3aGF0IG9ubGluZSBtb2RlIGNoZWNrcy5cbiAgICAgKi9cbiAgICBwcml2YXRlIHNpZ25DaGFpbkxpbmsoKTogc3RyaW5nIHtcbiAgICAgICAgY29uc3Qgbm93ID0gTWF0aC5mbG9vcihEYXRlLm5vdygpIC8gMTAwMCk7XG4gICAgICAgIGNvbnN0IHNpZ24gPSBjcmVhdGVTaWduZXIoe1xuICAgICAgICAgICAgYWxnb3JpdGhtOiBBTEdPUklUSE0sXG4gICAgICAgICAgICBrZXk6IHRoaXMucHJpdmF0ZUtleVBlbSxcbiAgICAgICAgICAgIGhlYWRlcjogeyBhbGc6IEFMR09SSVRITSwgeDV1OiB0aGlzLnB1YmxpY0tleURlciB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiBzaWduKHtcbiAgICAgICAgICAgIG5iZjogbm93IC0gNjAsXG4gICAgICAgICAgICBleHA6IG5vdyArIENIQUlOX0xJRkVUSU1FX1NFQ09ORFMsXG4gICAgICAgICAgICBpYXQ6IG5vdyxcbiAgICAgICAgICAgIGlkZW50aXR5UHVibGljS2V5OiB0aGlzLnB1YmxpY0tleURlcixcbiAgICAgICAgICAgIGV4dHJhRGF0YToge1xuICAgICAgICAgICAgICAgIFhVSUQ6IHRoaXMuaWRlbnRpdHkueHVpZCxcbiAgICAgICAgICAgICAgICBpZGVudGl0eTogdGhpcy5pZGVudGl0eS5pZGVudGl0eSxcbiAgICAgICAgICAgICAgICBkaXNwbGF5TmFtZTogdGhpcy5pZGVudGl0eS5kaXNwbGF5TmFtZSxcbiAgICAgICAgICAgICAgICB0aXRsZUlkOiB0aGlzLmlkZW50aXR5LnRpdGxlSWQgPz8gJydcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzaWduQ2xpZW50RGF0YShyZXF1ZXN0OiBMb2dpblJlcXVlc3QpOiBzdHJpbmcge1xuICAgICAgICBjb25zdCBzaWduID0gY3JlYXRlU2lnbmVyKHtcbiAgICAgICAgICAgIGFsZ29yaXRobTogQUxHT1JJVEhNLFxuICAgICAgICAgICAga2V5OiB0aGlzLnByaXZhdGVLZXlQZW0sXG4gICAgICAgICAgICBoZWFkZXI6IHsgYWxnOiBBTEdPUklUSE0sIHg1dTogdGhpcy5wdWJsaWNLZXlEZXIgfSxcbiAgICAgICAgICAgIG5vVGltZXN0YW1wOiB0cnVlXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiBzaWduKFxuICAgICAgICAgICAgY3JlYXRlQ2xpZW50RGF0YSh7XG4gICAgICAgICAgICAgICAgLi4udGhpcy5vcHRpb25zLmNsaWVudERhdGEsXG4gICAgICAgICAgICAgICAgc2VydmVyQWRkcmVzczogcmVxdWVzdC5zZXJ2ZXJBZGRyZXNzLFxuICAgICAgICAgICAgICAgIGNsaWVudFJhbmRvbUlkOiB0aGlzLmNsaWVudFJhbmRvbUlkLFxuICAgICAgICAgICAgICAgIHNlbGZTaWduZWRJZDogdGhpcy5pZGVudGl0eS5pZGVudGl0eSxcbiAgICAgICAgICAgICAgICBkaXNwbGF5TmFtZTogdGhpcy5pZGVudGl0eS5kaXNwbGF5TmFtZVxuICAgICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICB9XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7OztBQVlBLElBQU0sUUFBUTtBQUNkLElBQU0sWUFBWTs7QUFHbEIsSUFBTSx5QkFBeUI7Ozs7Ozs7Ozs7QUFXL0IsSUFBTSx1QkFBdUI7O0FBRzdCLElBQU0sdUJBQXVCOztBQUc3QixJQUFNLGtDQUFrQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFrQ3hDLElBQXFCLHNCQUFyQixNQUFrRTtDQVExQjtDQVBwQyxPQUF1QjtDQUV2QjtDQUNBO0NBQ0E7Q0FDQTtDQUVBLFlBQW1CLFNBQThDO0VBQTdCLEtBQUEsVUFBQTtFQUNoQyxNQUFNLEVBQUUsV0FBVyxlQUFlLG9CQUFvQixNQUFNLEVBQUUsWUFBWSxNQUFNLENBQUM7RUFJakYsS0FBSyxlQUFlLFVBQVUsT0FBTztHQUFFLE1BQU07R0FBUSxRQUFRO0VBQU0sQ0FBQyxDQUFDLENBQUMsU0FBUyxRQUFRO0VBQ3ZGLEtBQUssZ0JBQWdCLFdBQVcsT0FBTztHQUFFLE1BQU07R0FBUyxRQUFRO0VBQU0sQ0FBQyxDQUFDLENBQUMsU0FBUztFQUVsRixLQUFLLFdBQVc7R0FHWixNQUFNO0dBQ04sVUFBVSxRQUFRLFlBQVksV0FBVztHQUN6QyxhQUFhLFFBQVE7RUFDekI7RUFJQSxLQUFLLGlCQUFpQixVQUFVLEdBQUcsVUFBVTtDQUNqRDtDQUVBLE1BQWEsY0FBaUM7RUFDMUMsT0FBTyxLQUFLO0NBQ2hCO0NBRUEsTUFBYSx1QkFBd0M7RUFDakQsT0FBTyxLQUFLO0NBQ2hCO0NBRUEsTUFBYSx3QkFBeUM7RUFDbEQsT0FBTyxLQUFLO0NBQ2hCO0NBRUEsTUFBYSx1QkFBdUIsU0FBa0Q7RUFDbEYsT0FBTztHQUNILFdBQ0ksUUFBUSxtQkFBbUIsdUJBQ3JCLEtBQUssaUJBQWlCLElBQ3RCLEtBQUssVUFBVSxFQUFFLE9BQU8sQ0FBQyxLQUFLLGNBQWMsQ0FBQyxFQUFFLENBQUM7R0FDMUQsWUFBWSxLQUFLLGVBQWUsT0FBTztFQUMzQztDQUNKOzs7Ozs7Ozs7Q0FVQSxtQkFBbUM7RUFDL0IsT0FBTyxLQUFLLFVBQVU7R0FDbEIsYUFBYSxLQUFLLFVBQVUsRUFBRSxPQUFPLENBQUMsRUFBRSxFQUFFLENBQUM7R0FDM0Msb0JBQW9CO0dBQ3BCLE9BQU8sS0FBSyxxQkFBcUI7RUFDckMsQ0FBQztDQUNMOzs7Ozs7Ozs7O0NBV0EsdUJBQXVDO0VBQ25DLE1BQU0sTUFBTSxLQUFLLE1BQU0sS0FBSyxJQUFJLElBQUksR0FBSTtFQU94QyxPQU5hLGFBQWE7R0FDdEIsV0FBVztHQUNYLEtBQUssS0FBSztHQUNWLFFBQVE7SUFBRSxLQUFLO0lBQVcsS0FBSyxLQUFLO0dBQWE7RUFDckQsQ0FFTyxDQUFBLENBQUs7R0FDUixLQUFLO0dBQ0wsS0FBSyxNQUFNO0dBQ1gsS0FBSyxNQUFNO0dBQ1gsS0FBSztHQUNMLEtBQUs7R0FDTCxLQUFLO0dBQ0wsS0FBSztHQUNMLEtBQUssS0FBSztHQUNWLEtBQUssS0FBSyxTQUFTO0dBQ25CLE9BQU8sS0FBSyxTQUFTO0dBQ3JCLFNBQVMsS0FBSyxTQUFTO0VBQzNCLENBQUM7Q0FDTDs7Ozs7Ozs7OztDQVdBLGdCQUFnQztFQUM1QixNQUFNLE1BQU0sS0FBSyxNQUFNLEtBQUssSUFBSSxJQUFJLEdBQUk7RUFPeEMsT0FOYSxhQUFhO0dBQ3RCLFdBQVc7R0FDWCxLQUFLLEtBQUs7R0FDVixRQUFRO0lBQUUsS0FBSztJQUFXLEtBQUssS0FBSztHQUFhO0VBQ3JELENBRU8sQ0FBQSxDQUFLO0dBQ1IsS0FBSyxNQUFNO0dBQ1gsS0FBSyxNQUFNO0dBQ1gsS0FBSztHQUNMLG1CQUFtQixLQUFLO0dBQ3hCLFdBQVc7SUFDUCxNQUFNLEtBQUssU0FBUztJQUNwQixVQUFVLEtBQUssU0FBUztJQUN4QixhQUFhLEtBQUssU0FBUztJQUMzQixTQUFTLEtBQUssU0FBUyxXQUFXO0dBQ3RDO0VBQ0osQ0FBQztDQUNMO0NBRUEsZUFBdUIsU0FBK0I7RUFRbEQsT0FQYSxhQUFhO0dBQ3RCLFdBQVc7R0FDWCxLQUFLLEtBQUs7R0FDVixRQUFRO0lBQUUsS0FBSztJQUFXLEtBQUssS0FBSztHQUFhO0dBQ2pELGFBQWE7RUFDakIsQ0FFTyxDQUFBLENBQ0gsaUJBQWlCO0dBQ2IsR0FBRyxLQUFLLFFBQVE7R0FDaEIsZUFBZSxRQUFRO0dBQ3ZCLGdCQUFnQixLQUFLO0dBQ3JCLGNBQWMsS0FBSyxTQUFTO0dBQzVCLGFBQWEsS0FBSyxTQUFTO0VBQy9CLENBQUMsQ0FDTDtDQUNKO0FBQ0oifQ==
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const require_DefaultSkin = require("./DefaultSkin.cjs.cjs");
4
+ const require_ClientData = require("./ClientData.cjs.cjs");
5
+ const require_OfflineAuthProvider = require("./OfflineAuthProvider.cjs.cjs");
6
+ exports.DEFAULT_SKIN_RESOURCE_PATCH = require_DefaultSkin.DEFAULT_SKIN_RESOURCE_PATCH;
7
+ exports.OfflineAuthProvider = require_OfflineAuthProvider.default;
8
+ exports.SKIN_HEIGHT = require_DefaultSkin.SKIN_HEIGHT;
9
+ exports.SKIN_WIDTH = require_DefaultSkin.SKIN_WIDTH;
10
+ exports.createClientData = require_ClientData.createClientData;
11
+ exports.createDefaultSkinImage = require_DefaultSkin.createDefaultSkinImage;
@@ -0,0 +1,9 @@
1
+ import { createClientData } from './ClientData';
2
+ import { DEFAULT_SKIN_RESOURCE_PATCH, createDefaultSkinImage } from './DefaultSkin';
3
+ import OfflineAuthProvider from './OfflineAuthProvider';
4
+ export { DEFAULT_SKIN_RESOURCE_PATCH, OfflineAuthProvider, createClientData, createDefaultSkinImage };
5
+ export type * from './IAuthProvider';
6
+ export type { AnimatedImage, ClientDataOptions, ClientDataPayload } from './ClientData';
7
+ export type { OfflineAuthOptions } from './OfflineAuthProvider';
8
+ export { SKIN_HEIGHT, SKIN_WIDTH } from './DefaultSkin';
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,2BAA2B,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AACpF,OAAO,mBAAmB,MAAM,uBAAuB,CAAC;AAExD,OAAO,EAAE,2BAA2B,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,CAAC;AAEtG,mBAAmB,iBAAiB,CAAC;AACrC,YAAY,EAAE,aAAa,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACxF,YAAY,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { DEFAULT_SKIN_RESOURCE_PATCH, SKIN_HEIGHT, SKIN_WIDTH, createDefaultSkinImage } from "./DefaultSkin.es.js";
2
+ import { createClientData } from "./ClientData.es.js";
3
+ import OfflineAuthProvider from "./OfflineAuthProvider.es.js";
4
+ export { DEFAULT_SKIN_RESOURCE_PATCH, OfflineAuthProvider, SKIN_HEIGHT, SKIN_WIDTH, createClientData, createDefaultSkinImage };
package/package.json CHANGED
@@ -1,6 +1,64 @@
1
1
  {
2
2
  "name": "@jsprismarine/auth",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.14.1",
4
+ "description": "Minecraft: Bedrock Edition login identity: JWT chains, client data and Xbox Live",
5
+ "sideEffects": false,
6
+ "publishConfig": {
7
+ "access": "public"
8
+ },
9
+ "type": "module",
10
+ "files": [
11
+ "dist",
12
+ "CHANGELOG.md",
13
+ "README.md"
14
+ ],
15
+ "main": "./dist/index.cjs.cjs",
16
+ "module": "./dist/index.es.js",
17
+ "types": "./dist/index.d.ts",
18
+ "exports": {
19
+ ".": {
20
+ "types": "./dist/index.d.ts",
21
+ "import": "./dist/index.es.js",
22
+ "module": "./dist/index.es.js",
23
+ "require": "./dist/index.cjs.cjs"
24
+ },
25
+ "./*": {
26
+ "types": "./dist/*.d.ts",
27
+ "import": "./dist/*.es.js",
28
+ "module": "./dist/*.es.js",
29
+ "require": "./dist/*.cjs.cjs"
30
+ },
31
+ "./package.json": "./package.json"
32
+ },
33
+ "repository": {
34
+ "type": "git",
35
+ "url": "git+https://github.com/JSPrismarine/JSPrismarine.git"
36
+ },
37
+ "keywords": [
38
+ "minecraft",
39
+ "bedrock",
40
+ "authentication",
41
+ "xbox"
42
+ ],
43
+ "author": "JSPrismarine",
44
+ "license": "MIT",
45
+ "homepage": "https://github.com/JSPrismarine/JSPrismarine/tree/master/packages/auth",
46
+ "devDependencies": {
47
+ "@types/node": "24.13.6",
48
+ "glob": "13.0.6",
49
+ "rimraf": "6.1.3",
50
+ "typescript": "7.0.2",
51
+ "vite": "8.3.0",
52
+ "vitest": "5.0.1"
53
+ },
54
+ "dependencies": {
55
+ "@jsprismarine/minecraft": "0.14.2",
56
+ "fast-jwt": "6.3.3"
57
+ },
58
+ "scripts": {
59
+ "clean": "rimraf dist jsp *.tsbuildinfo vite.config.ts.timestamp-* .tsup .turbo",
60
+ "build": "vite build && node ../../scripts/emit-dts.mts",
61
+ "build:watch": "vite build --watch",
62
+ "typecheck": "tsc-ts --noEmit"
63
+ }
6
64
  }