parse-server 7.5.1 → 7.5.3

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.
Files changed (39) hide show
  1. package/lib/Adapters/Auth/AuthAdapter.js +16 -9
  2. package/lib/Adapters/Auth/BaseCodeAuthAdapter.js +99 -0
  3. package/lib/Adapters/Auth/apple.js +45 -1
  4. package/lib/Adapters/Auth/facebook.js +61 -1
  5. package/lib/Adapters/Auth/gcenter.js +201 -157
  6. package/lib/Adapters/Auth/github.js +119 -31
  7. package/lib/Adapters/Auth/google.js +45 -1
  8. package/lib/Adapters/Auth/gpgames.js +120 -27
  9. package/lib/Adapters/Auth/index.js +33 -33
  10. package/lib/Adapters/Auth/instagram.js +114 -24
  11. package/lib/Adapters/Auth/janraincapture.js +45 -1
  12. package/lib/Adapters/Auth/janrainengage.js +12 -2
  13. package/lib/Adapters/Auth/keycloak.js +68 -35
  14. package/lib/Adapters/Auth/ldap.js +75 -1
  15. package/lib/Adapters/Auth/line.js +119 -32
  16. package/lib/Adapters/Auth/linkedin.js +111 -35
  17. package/lib/Adapters/Auth/meetup.js +16 -8
  18. package/lib/Adapters/Auth/mfa.js +80 -2
  19. package/lib/Adapters/Auth/microsoft.js +105 -30
  20. package/lib/Adapters/Auth/oauth2.js +100 -110
  21. package/lib/Adapters/Auth/phantauth.js +16 -8
  22. package/lib/Adapters/Auth/qq.js +107 -36
  23. package/lib/Adapters/Auth/spotify.js +108 -39
  24. package/lib/Adapters/Auth/twitter.js +187 -40
  25. package/lib/Adapters/Auth/vkontakte.js +21 -13
  26. package/lib/Adapters/Auth/wechat.js +105 -25
  27. package/lib/Adapters/Auth/weibo.js +135 -37
  28. package/lib/Auth.js +27 -17
  29. package/lib/Config.js +14 -1
  30. package/lib/Deprecator/Deprecations.js +4 -1
  31. package/lib/GraphQL/ParseGraphQLServer.js +33 -3
  32. package/lib/Options/Definitions.js +13 -1
  33. package/lib/Options/docs.js +3 -1
  34. package/lib/Options/index.js +1 -1
  35. package/lib/RestWrite.js +4 -5
  36. package/lib/Security/CheckGroups/CheckGroupServerConfig.js +19 -1
  37. package/lib/cli/parse-server.js +1 -1
  38. package/lib/middlewares.js +1 -1
  39. package/package.json +9 -9
@@ -1,173 +1,217 @@
1
1
  "use strict";
2
2
 
3
- /* Apple Game Center Auth
4
- https://developer.apple.com/documentation/gamekit/gklocalplayer/1515407-generateidentityverificationsign#discussion
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _crypto = _interopRequireDefault(require("crypto"));
8
+ var _nodeForge = require("node-forge");
9
+ var _AuthAdapter = _interopRequireDefault(require("./AuthAdapter"));
10
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
11
+ /**
12
+ * Parse Server authentication adapter for Apple Game Center.
13
+ *
14
+ * @class AppleGameCenterAdapter
15
+ * @param {Object} options - Configuration options for the adapter.
16
+ * @param {string} options.bundleId - Your Apple Game Center bundle ID. Required for secure authentication.
17
+ * @param {boolean} [options.enableInsecureAuth=false] - **[DEPRECATED]** Enable insecure authentication (not recommended).
18
+ *
19
+ * @param {Object} authData - The authentication data provided by the client.
20
+ * @param {string} authData.id - The user ID obtained from Apple Game Center.
21
+ * @param {string} authData.publicKeyUrl - The public key URL obtained from Apple Game Center.
22
+ * @param {string} authData.timestamp - The timestamp obtained from Apple Game Center.
23
+ * @param {string} authData.signature - The signature obtained from Apple Game Center.
24
+ * @param {string} authData.salt - The salt obtained from Apple Game Center.
25
+ * @param {string} [authData.bundleId] - **[DEPRECATED]** The bundle ID obtained from Apple Game Center (required for insecure authentication).
26
+ *
27
+ * @description
28
+ * ## Parse Server Configuration
29
+ * The following `authData` fields are required:
30
+ * `id`, `publicKeyUrl`, `timestamp`, `signature`, and `salt`. These fields are validated against the configured `bundleId` for additional security.
31
+ *
32
+ * To configure Parse Server for Apple Game Center authentication, use the following structure:
33
+ * ```json
34
+ * {
35
+ * "auth": {
36
+ * "gcenter": {
37
+ * "bundleId": "com.valid.app"
38
+ * }
39
+ * }
40
+ * ```
41
+ *
42
+ * ## Insecure Authentication (Not Recommended)
43
+ * The following `authData` fields are required for insecure authentication:
44
+ * `id`, `publicKeyUrl`, `timestamp`, `signature`, `salt`, and `bundleId` (**[DEPRECATED]**). This flow is insecure and poses potential security risks.
45
+ *
46
+ * To configure Parse Server for insecure authentication, use the following structure:
47
+ * ```json
48
+ * {
49
+ * "auth": {
50
+ * "gcenter": {
51
+ * "enableInsecureAuth": true
52
+ * }
53
+ * }
54
+ * ```
55
+ *
56
+ * ### Deprecation Notice
57
+ * The `enableInsecureAuth` option and `authData.bundleId` parameter are deprecated and may be removed in future releases. Use secure authentication with the `bundleId` configured in the `options` object instead.
58
+ *
59
+ *
60
+ * @example <caption>Secure Authentication Example</caption>
61
+ * // Example authData for secure authentication:
62
+ * const authData = {
63
+ * gcenter: {
64
+ * id: "1234567",
65
+ * publicKeyUrl: "https://valid.apple.com/public/timeout.cer",
66
+ * timestamp: 1460981421303,
67
+ * salt: "saltST==",
68
+ * signature: "PoDwf39DCN464B49jJCU0d9Y0J"
69
+ * }
70
+ * };
71
+ *
72
+ * @example <caption>Insecure Authentication Example (Not Recommended)</caption>
73
+ * // Example authData for insecure authentication:
74
+ * const authData = {
75
+ * gcenter: {
76
+ * id: "1234567",
77
+ * publicKeyUrl: "https://valid.apple.com/public/timeout.cer",
78
+ * timestamp: 1460981421303,
79
+ * salt: "saltST==",
80
+ * signature: "PoDwf39DCN464B49jJCU0d9Y0J",
81
+ * bundleId: "com.valid.app" // Deprecated.
82
+ * }
83
+ * };
84
+ *
85
+ * @see {@link https://developer.apple.com/documentation/gamekit/gklocalplayer/3516283-fetchitems Apple Game Center Documentation}
86
+ */
87
+ /* global BigInt */
5
88
 
6
- const authData = {
7
- publicKeyUrl: 'https://valid.apple.com/public/timeout.cer',
8
- timestamp: 1460981421303,
9
- signature: 'PoDwf39DCN464B49jJCU0d9Y0J',
10
- salt: 'saltST==',
11
- bundleId: 'com.valid.app'
12
- id: 'playerId',
13
- };
14
- */
15
-
16
- const {
17
- Parse
18
- } = require('parse/node');
19
- const crypto = require('crypto');
20
- const https = require('https');
21
- const {
22
- pki
23
- } = require('node-forge');
24
- const ca = {
25
- cert: null,
26
- url: null
27
- };
28
- const cache = {}; // (publicKey -> cert) cache
29
-
30
- function verifyPublicKeyUrl(publicKeyUrl) {
31
- try {
32
- const regex = /^https:\/\/(?:[-_A-Za-z0-9]+\.){0,}apple\.com\/.*\.cer$/;
33
- return regex.test(publicKeyUrl);
34
- } catch (error) {
35
- return false;
89
+ class GameCenterAuth extends _AuthAdapter.default {
90
+ constructor() {
91
+ super();
92
+ this.ca = {
93
+ cert: null,
94
+ url: null
95
+ };
96
+ this.cache = {};
97
+ this.bundleId = '';
36
98
  }
37
- }
38
- function convertX509CertToPEM(X509Cert) {
39
- const pemPreFix = '-----BEGIN CERTIFICATE-----\n';
40
- const pemPostFix = '-----END CERTIFICATE-----';
41
- const base64 = X509Cert;
42
- const certBody = base64.match(new RegExp('.{0,64}', 'g')).join('\n');
43
- return pemPreFix + certBody + pemPostFix;
44
- }
45
- async function getAppleCertificate(publicKeyUrl) {
46
- if (!verifyPublicKeyUrl(publicKeyUrl)) {
47
- throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `Apple Game Center - invalid publicKeyUrl: ${publicKeyUrl}`);
48
- }
49
- if (cache[publicKeyUrl]) {
50
- return cache[publicKeyUrl];
51
- }
52
- const url = new URL(publicKeyUrl);
53
- const headOptions = {
54
- hostname: url.hostname,
55
- path: url.pathname,
56
- method: 'HEAD'
57
- };
58
- const cert_headers = await new Promise((resolve, reject) => https.get(headOptions, res => resolve(res.headers)).on('error', reject));
59
- const validContentTypes = ['application/x-x509-ca-cert', 'application/pkix-cert'];
60
- if (!validContentTypes.includes(cert_headers['content-type']) || cert_headers['content-length'] == null || cert_headers['content-length'] > 10000) {
61
- throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `Apple Game Center - invalid publicKeyUrl: ${publicKeyUrl}`);
99
+ validateOptions(options) {
100
+ if (!options) {
101
+ throw new Error('Game center auth options are required.');
102
+ }
103
+ if (!this.loadingPromise) {
104
+ this.loadingPromise = this.loadCertificate(options);
105
+ }
106
+ this.enableInsecureAuth = options.enableInsecureAuth;
107
+ this.bundleId = options.bundleId;
108
+ if (!this.enableInsecureAuth && !this.bundleId) {
109
+ throw new Error('bundleId is required for secure auth.');
110
+ }
62
111
  }
63
- const {
64
- certificate,
65
- headers
66
- } = await getCertificate(publicKeyUrl);
67
- if (headers['cache-control']) {
68
- const expire = headers['cache-control'].match(/max-age=([0-9]+)/);
69
- if (expire) {
70
- cache[publicKeyUrl] = certificate;
71
- // we'll expire the cache entry later, as per max-age
72
- setTimeout(() => {
73
- delete cache[publicKeyUrl];
74
- }, parseInt(expire[1], 10) * 1000);
112
+ async loadCertificate(options) {
113
+ const rootCertificateUrl = options.rootCertificateUrl || 'https://cacerts.digicert.com/DigiCertTrustedG4CodeSigningRSA4096SHA3842021CA1.crt.pem';
114
+ if (this.ca.url === rootCertificateUrl) {
115
+ return rootCertificateUrl;
116
+ }
117
+ const {
118
+ certificate,
119
+ headers
120
+ } = await this.fetchCertificate(rootCertificateUrl);
121
+ if (headers.get('content-type') !== 'application/x-pem-file' || !headers.get('content-length') || parseInt(headers.get('content-length'), 10) > 10000) {
122
+ throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Invalid rootCertificateURL.');
75
123
  }
124
+ this.ca.cert = _nodeForge.pki.certificateFromPem(certificate);
125
+ this.ca.url = rootCertificateUrl;
126
+ return rootCertificateUrl;
76
127
  }
77
- return verifyPublicKeyIssuer(certificate, publicKeyUrl);
78
- }
79
- function getCertificate(url, buffer) {
80
- return new Promise((resolve, reject) => {
81
- https.get(url, res => {
82
- const data = [];
83
- res.on('data', chunk => {
84
- data.push(chunk);
85
- });
86
- res.on('end', () => {
87
- if (buffer) {
88
- resolve({
89
- certificate: Buffer.concat(data),
90
- headers: res.headers
91
- });
92
- return;
93
- }
94
- let cert = '';
95
- for (const chunk of data) {
96
- cert += chunk.toString('base64');
97
- }
98
- const certificate = convertX509CertToPEM(cert);
99
- resolve({
100
- certificate,
101
- headers: res.headers
102
- });
103
- });
104
- }).on('error', reject);
105
- });
106
- }
107
- function convertTimestampToBigEndian(timestamp) {
108
- const buffer = Buffer.alloc(8);
109
- const high = ~~(timestamp / 0xffffffff);
110
- const low = timestamp % (0xffffffff + 0x1);
111
- buffer.writeUInt32BE(parseInt(high, 10), 0);
112
- buffer.writeUInt32BE(parseInt(low, 10), 4);
113
- return buffer;
114
- }
115
- function verifySignature(publicKey, authData) {
116
- const verifier = crypto.createVerify('sha256');
117
- verifier.update(authData.playerId, 'utf8');
118
- verifier.update(authData.bundleId, 'utf8');
119
- verifier.update(convertTimestampToBigEndian(authData.timestamp));
120
- verifier.update(authData.salt, 'base64');
121
- if (!verifier.verify(publicKey, authData.signature, 'base64')) {
122
- throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Apple Game Center - invalid signature');
128
+ verifyPublicKeyUrl(publicKeyUrl) {
129
+ const regex = /^https:\/\/(?:[-_A-Za-z0-9]+\.){0,}apple\.com\/.*\.cer$/;
130
+ return regex.test(publicKeyUrl);
123
131
  }
124
- }
125
- function verifyPublicKeyIssuer(cert, publicKeyUrl) {
126
- const publicKeyCert = pki.certificateFromPem(cert);
127
- if (!ca.cert) {
128
- throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Apple Game Center auth adapter parameter `rootCertificateURL` is invalid.');
132
+ async fetchCertificate(url) {
133
+ const response = await fetch(url);
134
+ if (!response.ok) {
135
+ throw new Error(`Failed to fetch certificate: ${url}`);
136
+ }
137
+ const contentType = response.headers.get('content-type');
138
+ const isPem = contentType === null || contentType === void 0 ? void 0 : contentType.includes('application/x-pem-file');
139
+ if (isPem) {
140
+ const certificate = await response.text();
141
+ return {
142
+ certificate,
143
+ headers: response.headers
144
+ };
145
+ }
146
+ const data = await response.arrayBuffer();
147
+ const binaryData = Buffer.from(data);
148
+ const asn1Cert = _nodeForge.asn1.fromDer(binaryData.toString('binary'));
149
+ const forgeCert = _nodeForge.pki.certificateFromAsn1(asn1Cert);
150
+ const certificate = _nodeForge.pki.certificateToPem(forgeCert);
151
+ return {
152
+ certificate,
153
+ headers: response.headers
154
+ };
129
155
  }
130
- try {
131
- if (!ca.cert.verify(publicKeyCert)) {
132
- throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `Apple Game Center - invalid publicKeyUrl: ${publicKeyUrl}`);
156
+ async getAppleCertificate(publicKeyUrl) {
157
+ if (!this.verifyPublicKeyUrl(publicKeyUrl)) {
158
+ throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `Invalid publicKeyUrl: ${publicKeyUrl}`);
133
159
  }
134
- } catch (e) {
135
- throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `Apple Game Center - invalid publicKeyUrl: ${publicKeyUrl}`);
160
+ if (this.cache[publicKeyUrl]) {
161
+ return this.cache[publicKeyUrl];
162
+ }
163
+ const {
164
+ certificate,
165
+ headers
166
+ } = await this.fetchCertificate(publicKeyUrl);
167
+ const cacheControl = headers.get('cache-control');
168
+ const expire = cacheControl === null || cacheControl === void 0 ? void 0 : cacheControl.match(/max-age=([0-9]+)/);
169
+ this.verifyPublicKeyIssuer(certificate, publicKeyUrl);
170
+ if (expire) {
171
+ this.cache[publicKeyUrl] = certificate;
172
+ setTimeout(() => delete this.cache[publicKeyUrl], parseInt(expire[1], 10) * 1000);
173
+ }
174
+ return certificate;
136
175
  }
137
- return cert;
138
- }
139
-
140
- // Returns a promise that fulfills if this user id is valid.
141
- async function validateAuthData(authData) {
142
- if (!authData.id) {
143
- throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Apple Game Center - authData id missing');
176
+ verifyPublicKeyIssuer(cert, publicKeyUrl) {
177
+ const publicKeyCert = _nodeForge.pki.certificateFromPem(cert);
178
+ if (!this.ca.cert) {
179
+ throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Root certificate is invalid or missing.');
180
+ }
181
+ if (!this.ca.cert.verify(publicKeyCert)) {
182
+ throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `Invalid publicKeyUrl: ${publicKeyUrl}`);
183
+ }
144
184
  }
145
- authData.playerId = authData.id;
146
- const publicKey = await getAppleCertificate(authData.publicKeyUrl);
147
- return verifySignature(publicKey, authData);
148
- }
149
-
150
- // Returns a promise that fulfills if this app id is valid.
151
- async function validateAppId(appIds, authData, options = {}) {
152
- if (!options.rootCertificateUrl) {
153
- options.rootCertificateUrl = 'https://cacerts.digicert.com/DigiCertTrustedG4CodeSigningRSA4096SHA3842021CA1.crt.pem';
185
+ verifySignature(publicKey, authData) {
186
+ const bundleId = this.bundleId || this.enableInsecureAuth && authData.bundleId;
187
+ const verifier = _crypto.default.createVerify('sha256');
188
+ verifier.update(Buffer.from(authData.id, 'utf8'));
189
+ verifier.update(Buffer.from(bundleId, 'utf8'));
190
+ verifier.update(this.convertTimestampToBigEndian(authData.timestamp));
191
+ verifier.update(Buffer.from(authData.salt, 'base64'));
192
+ if (!verifier.verify(publicKey, authData.signature, 'base64')) {
193
+ throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Invalid signature.');
194
+ }
154
195
  }
155
- if (ca.url === options.rootCertificateUrl) {
156
- return;
196
+ async validateAuthData(authData) {
197
+ const requiredKeys = ['id', 'publicKeyUrl', 'timestamp', 'signature', 'salt'];
198
+ if (this.enableInsecureAuth) {
199
+ requiredKeys.push('bundleId');
200
+ }
201
+ for (const key of requiredKeys) {
202
+ if (!authData[key]) {
203
+ throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `AuthData ${key} is missing.`);
204
+ }
205
+ }
206
+ await this.loadingPromise;
207
+ const publicKey = await this.getAppleCertificate(authData.publicKeyUrl);
208
+ this.verifySignature(publicKey, authData);
157
209
  }
158
- const {
159
- certificate,
160
- headers
161
- } = await getCertificate(options.rootCertificateUrl, true);
162
- if (headers['content-type'] !== 'application/x-pem-file' || headers['content-length'] == null || headers['content-length'] > 10000) {
163
- throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Apple Game Center auth adapter parameter `rootCertificateURL` is invalid.');
210
+ convertTimestampToBigEndian(timestamp) {
211
+ const buffer = Buffer.alloc(8);
212
+ buffer.writeBigUInt64BE(BigInt(timestamp));
213
+ return buffer;
164
214
  }
165
- ca.cert = pki.certificateFromPem(certificate);
166
- ca.url = options.rootCertificateUrl;
167
215
  }
168
- module.exports = {
169
- validateAppId,
170
- validateAuthData,
171
- cache
172
- };
173
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJQYXJzZSIsInJlcXVpcmUiLCJjcnlwdG8iLCJodHRwcyIsInBraSIsImNhIiwiY2VydCIsInVybCIsImNhY2hlIiwidmVyaWZ5UHVibGljS2V5VXJsIiwicHVibGljS2V5VXJsIiwicmVnZXgiLCJ0ZXN0IiwiZXJyb3IiLCJjb252ZXJ0WDUwOUNlcnRUb1BFTSIsIlg1MDlDZXJ0IiwicGVtUHJlRml4IiwicGVtUG9zdEZpeCIsImJhc2U2NCIsImNlcnRCb2R5IiwibWF0Y2giLCJSZWdFeHAiLCJqb2luIiwiZ2V0QXBwbGVDZXJ0aWZpY2F0ZSIsIkVycm9yIiwiT0JKRUNUX05PVF9GT1VORCIsIlVSTCIsImhlYWRPcHRpb25zIiwiaG9zdG5hbWUiLCJwYXRoIiwicGF0aG5hbWUiLCJtZXRob2QiLCJjZXJ0X2hlYWRlcnMiLCJQcm9taXNlIiwicmVzb2x2ZSIsInJlamVjdCIsImdldCIsInJlcyIsImhlYWRlcnMiLCJvbiIsInZhbGlkQ29udGVudFR5cGVzIiwiaW5jbHVkZXMiLCJjZXJ0aWZpY2F0ZSIsImdldENlcnRpZmljYXRlIiwiZXhwaXJlIiwic2V0VGltZW91dCIsInBhcnNlSW50IiwidmVyaWZ5UHVibGljS2V5SXNzdWVyIiwiYnVmZmVyIiwiZGF0YSIsImNodW5rIiwicHVzaCIsIkJ1ZmZlciIsImNvbmNhdCIsInRvU3RyaW5nIiwiY29udmVydFRpbWVzdGFtcFRvQmlnRW5kaWFuIiwidGltZXN0YW1wIiwiYWxsb2MiLCJoaWdoIiwibG93Iiwid3JpdGVVSW50MzJCRSIsInZlcmlmeVNpZ25hdHVyZSIsInB1YmxpY0tleSIsImF1dGhEYXRhIiwidmVyaWZpZXIiLCJjcmVhdGVWZXJpZnkiLCJ1cGRhdGUiLCJwbGF5ZXJJZCIsImJ1bmRsZUlkIiwic2FsdCIsInZlcmlmeSIsInNpZ25hdHVyZSIsInB1YmxpY0tleUNlcnQiLCJjZXJ0aWZpY2F0ZUZyb21QZW0iLCJlIiwidmFsaWRhdGVBdXRoRGF0YSIsImlkIiwidmFsaWRhdGVBcHBJZCIsImFwcElkcyIsIm9wdGlvbnMiLCJyb290Q2VydGlmaWNhdGVVcmwiLCJtb2R1bGUiLCJleHBvcnRzIl0sInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL0FkYXB0ZXJzL0F1dGgvZ2NlbnRlci5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKiBBcHBsZSBHYW1lIENlbnRlciBBdXRoXG5odHRwczovL2RldmVsb3Blci5hcHBsZS5jb20vZG9jdW1lbnRhdGlvbi9nYW1la2l0L2drbG9jYWxwbGF5ZXIvMTUxNTQwNy1nZW5lcmF0ZWlkZW50aXR5dmVyaWZpY2F0aW9uc2lnbiNkaXNjdXNzaW9uXG5cbmNvbnN0IGF1dGhEYXRhID0ge1xuICBwdWJsaWNLZXlVcmw6ICdodHRwczovL3ZhbGlkLmFwcGxlLmNvbS9wdWJsaWMvdGltZW91dC5jZXInLFxuICB0aW1lc3RhbXA6IDE0NjA5ODE0MjEzMDMsXG4gIHNpZ25hdHVyZTogJ1BvRHdmMzlEQ040NjRCNDlqSkNVMGQ5WTBKJyxcbiAgc2FsdDogJ3NhbHRTVD09JyxcbiAgYnVuZGxlSWQ6ICdjb20udmFsaWQuYXBwJ1xuICBpZDogJ3BsYXllcklkJyxcbn07XG4qL1xuXG5jb25zdCB7IFBhcnNlIH0gPSByZXF1aXJlKCdwYXJzZS9ub2RlJyk7XG5jb25zdCBjcnlwdG8gPSByZXF1aXJlKCdjcnlwdG8nKTtcbmNvbnN0IGh0dHBzID0gcmVxdWlyZSgnaHR0cHMnKTtcbmNvbnN0IHsgcGtpIH0gPSByZXF1aXJlKCdub2RlLWZvcmdlJyk7XG5jb25zdCBjYSA9IHsgY2VydDogbnVsbCwgdXJsOiBudWxsIH07XG5jb25zdCBjYWNoZSA9IHt9OyAvLyAocHVibGljS2V5IC0+IGNlcnQpIGNhY2hlXG5cbmZ1bmN0aW9uIHZlcmlmeVB1YmxpY0tleVVybChwdWJsaWNLZXlVcmwpIHtcbiAgdHJ5IHtcbiAgICBjb25zdCByZWdleCA9IC9eaHR0cHM6XFwvXFwvKD86Wy1fQS1aYS16MC05XStcXC4pezAsfWFwcGxlXFwuY29tXFwvLipcXC5jZXIkLztcbiAgICByZXR1cm4gcmVnZXgudGVzdChwdWJsaWNLZXlVcmwpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuXG5mdW5jdGlvbiBjb252ZXJ0WDUwOUNlcnRUb1BFTShYNTA5Q2VydCkge1xuICBjb25zdCBwZW1QcmVGaXggPSAnLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tXFxuJztcbiAgY29uc3QgcGVtUG9zdEZpeCA9ICctLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tJztcblxuICBjb25zdCBiYXNlNjQgPSBYNTA5Q2VydDtcbiAgY29uc3QgY2VydEJvZHkgPSBiYXNlNjQubWF0Y2gobmV3IFJlZ0V4cCgnLnswLDY0fScsICdnJykpLmpvaW4oJ1xcbicpO1xuXG4gIHJldHVybiBwZW1QcmVGaXggKyBjZXJ0Qm9keSArIHBlbVBvc3RGaXg7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGdldEFwcGxlQ2VydGlmaWNhdGUocHVibGljS2V5VXJsKSB7XG4gIGlmICghdmVyaWZ5UHVibGljS2V5VXJsKHB1YmxpY0tleVVybCkpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgYEFwcGxlIEdhbWUgQ2VudGVyIC0gaW52YWxpZCBwdWJsaWNLZXlVcmw6ICR7cHVibGljS2V5VXJsfWBcbiAgICApO1xuICB9XG4gIGlmIChjYWNoZVtwdWJsaWNLZXlVcmxdKSB7XG4gICAgcmV0dXJuIGNhY2hlW3B1YmxpY0tleVVybF07XG4gIH1cbiAgY29uc3QgdXJsID0gbmV3IFVSTChwdWJsaWNLZXlVcmwpO1xuICBjb25zdCBoZWFkT3B0aW9ucyA9IHtcbiAgICBob3N0bmFtZTogdXJsLmhvc3RuYW1lLFxuICAgIHBhdGg6IHVybC5wYXRobmFtZSxcbiAgICBtZXRob2Q6ICdIRUFEJyxcbiAgfTtcbiAgY29uc3QgY2VydF9oZWFkZXJzID0gYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT5cbiAgICBodHRwcy5nZXQoaGVhZE9wdGlvbnMsIHJlcyA9PiByZXNvbHZlKHJlcy5oZWFkZXJzKSkub24oJ2Vycm9yJywgcmVqZWN0KVxuICApO1xuICBjb25zdCB2YWxpZENvbnRlbnRUeXBlcyA9IFsnYXBwbGljYXRpb24veC14NTA5LWNhLWNlcnQnLCAnYXBwbGljYXRpb24vcGtpeC1jZXJ0J107XG4gIGlmIChcbiAgICAhdmFsaWRDb250ZW50VHlwZXMuaW5jbHVkZXMoY2VydF9oZWFkZXJzWydjb250ZW50LXR5cGUnXSkgfHxcbiAgICBjZXJ0X2hlYWRlcnNbJ2NvbnRlbnQtbGVuZ3RoJ10gPT0gbnVsbCB8fFxuICAgIGNlcnRfaGVhZGVyc1snY29udGVudC1sZW5ndGgnXSA+IDEwMDAwXG4gICkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsXG4gICAgICBgQXBwbGUgR2FtZSBDZW50ZXIgLSBpbnZhbGlkIHB1YmxpY0tleVVybDogJHtwdWJsaWNLZXlVcmx9YFxuICAgICk7XG4gIH1cbiAgY29uc3QgeyBjZXJ0aWZpY2F0ZSwgaGVhZGVycyB9ID0gYXdhaXQgZ2V0Q2VydGlmaWNhdGUocHVibGljS2V5VXJsKTtcbiAgaWYgKGhlYWRlcnNbJ2NhY2hlLWNvbnRyb2wnXSkge1xuICAgIGNvbnN0IGV4cGlyZSA9IGhlYWRlcnNbJ2NhY2hlLWNvbnRyb2wnXS5tYXRjaCgvbWF4LWFnZT0oWzAtOV0rKS8pO1xuICAgIGlmIChleHBpcmUpIHtcbiAgICAgIGNhY2hlW3B1YmxpY0tleVVybF0gPSBjZXJ0aWZpY2F0ZTtcbiAgICAgIC8vIHdlJ2xsIGV4cGlyZSB0aGUgY2FjaGUgZW50cnkgbGF0ZXIsIGFzIHBlciBtYXgtYWdlXG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgZGVsZXRlIGNhY2hlW3B1YmxpY0tleVVybF07XG4gICAgICB9LCBwYXJzZUludChleHBpcmVbMV0sIDEwKSAqIDEwMDApO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdmVyaWZ5UHVibGljS2V5SXNzdWVyKGNlcnRpZmljYXRlLCBwdWJsaWNLZXlVcmwpO1xufVxuXG5mdW5jdGlvbiBnZXRDZXJ0aWZpY2F0ZSh1cmwsIGJ1ZmZlcikge1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGh0dHBzXG4gICAgICAuZ2V0KHVybCwgcmVzID0+IHtcbiAgICAgICAgY29uc3QgZGF0YSA9IFtdO1xuICAgICAgICByZXMub24oJ2RhdGEnLCBjaHVuayA9PiB7XG4gICAgICAgICAgZGF0YS5wdXNoKGNodW5rKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJlcy5vbignZW5kJywgKCkgPT4ge1xuICAgICAgICAgIGlmIChidWZmZXIpIHtcbiAgICAgICAgICAgIHJlc29sdmUoeyBjZXJ0aWZpY2F0ZTogQnVmZmVyLmNvbmNhdChkYXRhKSwgaGVhZGVyczogcmVzLmhlYWRlcnMgfSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICAgIGxldCBjZXJ0ID0gJyc7XG4gICAgICAgICAgZm9yIChjb25zdCBjaHVuayBvZiBkYXRhKSB7XG4gICAgICAgICAgICBjZXJ0ICs9IGNodW5rLnRvU3RyaW5nKCdiYXNlNjQnKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc3QgY2VydGlmaWNhdGUgPSBjb252ZXJ0WDUwOUNlcnRUb1BFTShjZXJ0KTtcbiAgICAgICAgICByZXNvbHZlKHsgY2VydGlmaWNhdGUsIGhlYWRlcnM6IHJlcy5oZWFkZXJzIH0pO1xuICAgICAgICB9KTtcbiAgICAgIH0pXG4gICAgICAub24oJ2Vycm9yJywgcmVqZWN0KTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnRUaW1lc3RhbXBUb0JpZ0VuZGlhbih0aW1lc3RhbXApIHtcbiAgY29uc3QgYnVmZmVyID0gQnVmZmVyLmFsbG9jKDgpO1xuXG4gIGNvbnN0IGhpZ2ggPSB+fih0aW1lc3RhbXAgLyAweGZmZmZmZmZmKTtcbiAgY29uc3QgbG93ID0gdGltZXN0YW1wICUgKDB4ZmZmZmZmZmYgKyAweDEpO1xuXG4gIGJ1ZmZlci53cml0ZVVJbnQzMkJFKHBhcnNlSW50KGhpZ2gsIDEwKSwgMCk7XG4gIGJ1ZmZlci53cml0ZVVJbnQzMkJFKHBhcnNlSW50KGxvdywgMTApLCA0KTtcblxuICByZXR1cm4gYnVmZmVyO1xufVxuXG5mdW5jdGlvbiB2ZXJpZnlTaWduYXR1cmUocHVibGljS2V5LCBhdXRoRGF0YSkge1xuICBjb25zdCB2ZXJpZmllciA9IGNyeXB0by5jcmVhdGVWZXJpZnkoJ3NoYTI1NicpO1xuICB2ZXJpZmllci51cGRhdGUoYXV0aERhdGEucGxheWVySWQsICd1dGY4Jyk7XG4gIHZlcmlmaWVyLnVwZGF0ZShhdXRoRGF0YS5idW5kbGVJZCwgJ3V0ZjgnKTtcbiAgdmVyaWZpZXIudXBkYXRlKGNvbnZlcnRUaW1lc3RhbXBUb0JpZ0VuZGlhbihhdXRoRGF0YS50aW1lc3RhbXApKTtcbiAgdmVyaWZpZXIudXBkYXRlKGF1dGhEYXRhLnNhbHQsICdiYXNlNjQnKTtcblxuICBpZiAoIXZlcmlmaWVyLnZlcmlmeShwdWJsaWNLZXksIGF1dGhEYXRhLnNpZ25hdHVyZSwgJ2Jhc2U2NCcpKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdBcHBsZSBHYW1lIENlbnRlciAtIGludmFsaWQgc2lnbmF0dXJlJyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gdmVyaWZ5UHVibGljS2V5SXNzdWVyKGNlcnQsIHB1YmxpY0tleVVybCkge1xuICBjb25zdCBwdWJsaWNLZXlDZXJ0ID0gcGtpLmNlcnRpZmljYXRlRnJvbVBlbShjZXJ0KTtcbiAgaWYgKCFjYS5jZXJ0KSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCxcbiAgICAgICdBcHBsZSBHYW1lIENlbnRlciBhdXRoIGFkYXB0ZXIgcGFyYW1ldGVyIGByb290Q2VydGlmaWNhdGVVUkxgIGlzIGludmFsaWQuJ1xuICAgICk7XG4gIH1cbiAgdHJ5IHtcbiAgICBpZiAoIWNhLmNlcnQudmVyaWZ5KHB1YmxpY0tleUNlcnQpKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsXG4gICAgICAgIGBBcHBsZSBHYW1lIENlbnRlciAtIGludmFsaWQgcHVibGljS2V5VXJsOiAke3B1YmxpY0tleVVybH1gXG4gICAgICApO1xuICAgIH1cbiAgfSBjYXRjaCAoZSkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsXG4gICAgICBgQXBwbGUgR2FtZSBDZW50ZXIgLSBpbnZhbGlkIHB1YmxpY0tleVVybDogJHtwdWJsaWNLZXlVcmx9YFxuICAgICk7XG4gIH1cbiAgcmV0dXJuIGNlcnQ7XG59XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWYgdGhpcyB1c2VyIGlkIGlzIHZhbGlkLlxuYXN5bmMgZnVuY3Rpb24gdmFsaWRhdGVBdXRoRGF0YShhdXRoRGF0YSkge1xuICBpZiAoIWF1dGhEYXRhLmlkKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdBcHBsZSBHYW1lIENlbnRlciAtIGF1dGhEYXRhIGlkIG1pc3NpbmcnKTtcbiAgfVxuICBhdXRoRGF0YS5wbGF5ZXJJZCA9IGF1dGhEYXRhLmlkO1xuICBjb25zdCBwdWJsaWNLZXkgPSBhd2FpdCBnZXRBcHBsZUNlcnRpZmljYXRlKGF1dGhEYXRhLnB1YmxpY0tleVVybCk7XG4gIHJldHVybiB2ZXJpZnlTaWduYXR1cmUocHVibGljS2V5LCBhdXRoRGF0YSk7XG59XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWYgdGhpcyBhcHAgaWQgaXMgdmFsaWQuXG5hc3luYyBmdW5jdGlvbiB2YWxpZGF0ZUFwcElkKGFwcElkcywgYXV0aERhdGEsIG9wdGlvbnMgPSB7fSkge1xuICBpZiAoIW9wdGlvbnMucm9vdENlcnRpZmljYXRlVXJsKSB7XG4gICAgb3B0aW9ucy5yb290Q2VydGlmaWNhdGVVcmwgPVxuICAgICAgJ2h0dHBzOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkRzRDb2RlU2lnbmluZ1JTQTQwOTZTSEEzODQyMDIxQ0ExLmNydC5wZW0nO1xuICB9XG4gIGlmIChjYS51cmwgPT09IG9wdGlvbnMucm9vdENlcnRpZmljYXRlVXJsKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGNvbnN0IHsgY2VydGlmaWNhdGUsIGhlYWRlcnMgfSA9IGF3YWl0IGdldENlcnRpZmljYXRlKG9wdGlvbnMucm9vdENlcnRpZmljYXRlVXJsLCB0cnVlKTtcbiAgaWYgKFxuICAgIGhlYWRlcnNbJ2NvbnRlbnQtdHlwZSddICE9PSAnYXBwbGljYXRpb24veC1wZW0tZmlsZScgfHxcbiAgICBoZWFkZXJzWydjb250ZW50LWxlbmd0aCddID09IG51bGwgfHxcbiAgICBoZWFkZXJzWydjb250ZW50LWxlbmd0aCddID4gMTAwMDBcbiAgKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCxcbiAgICAgICdBcHBsZSBHYW1lIENlbnRlciBhdXRoIGFkYXB0ZXIgcGFyYW1ldGVyIGByb290Q2VydGlmaWNhdGVVUkxgIGlzIGludmFsaWQuJ1xuICAgICk7XG4gIH1cbiAgY2EuY2VydCA9IHBraS5jZXJ0aWZpY2F0ZUZyb21QZW0oY2VydGlmaWNhdGUpO1xuICBjYS51cmwgPSBvcHRpb25zLnJvb3RDZXJ0aWZpY2F0ZVVybDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHZhbGlkYXRlQXBwSWQsXG4gIHZhbGlkYXRlQXV0aERhdGEsXG4gIGNhY2hlLFxufTtcbiJdLCJtYXBwaW5ncyI6Ijs7QUFBQTtBQUNBO0FB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Q0FBQ1osUUFBUSxFQUFFO0VBQ3hDLElBQUksQ0FBQ0EsUUFBUSxDQUFDYSxFQUFFLEVBQUU7SUFDaEIsTUFBTSxJQUFJNUUsS0FBSyxDQUFDd0IsS0FBSyxDQUFDeEIsS0FBSyxDQUFDd0IsS0FBSyxDQUFDQyxnQkFBZ0IsRUFBRSx5Q0FBeUMsQ0FBQztFQUNoRztFQUNBc0MsUUFBUSxDQUFDSSxRQUFRLEdBQUdKLFFBQVEsQ0FBQ2EsRUFBRTtFQUMvQixNQUFNZCxTQUFTLEdBQUcsTUFBTXZDLG1CQUFtQixDQUFDd0MsUUFBUSxDQUFDckQsWUFBWSxDQUFDO0VBQ2xFLE9BQU9tRCxlQUFlLENBQUNDLFNBQVMsRUFBRUMsUUFBUSxDQUFDO0FBQzdDOztBQUVBO0FBQ0EsZUFBZWMsYUFBYUEsQ0FBQ0MsTUFBTSxFQUFFZixRQUFRLEVBQUVnQixPQUFPLEdBQUcsQ0FBQyxDQUFDLEVBQUU7RUFDM0QsSUFBSSxDQUFDQSxPQUFPLENBQUNDLGtCQUFrQixFQUFFO0lBQy9CRCxPQUFPLENBQUNDLGtCQUFrQixHQUN4Qix1RkFBdUY7RUFDM0Y7RUFDQSxJQUFJM0UsRUFBRSxDQUFDRSxHQUFHLEtBQUt3RSxPQUFPLENBQUNDLGtCQUFrQixFQUFFO0lBQ3pDO0VBQ0Y7RUFDQSxNQUFNO0lBQUV0QyxXQUFXO0lBQUVKO0VBQVEsQ0FBQyxHQUFHLE1BQU1LLGNBQWMsQ0FBQ29DLE9BQU8sQ0FBQ0Msa0JBQWtCLEVBQUUsSUFBSSxDQUFDO0VBQ3ZGLElBQ0UxQyxPQUFPLENBQUMsY0FBYyxDQUFDLEtBQUssd0JBQXdCLElBQ3BEQSxPQUFPLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxJQUFJLElBQ2pDQSxPQUFPLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxLQUFLLEVBQ2pDO0lBQ0EsTUFBTSxJQUFJdEMsS0FBSyxDQUFDd0IsS0FBSyxDQUNuQnhCLEtBQUssQ0FBQ3dCLEtBQUssQ0FBQ0MsZ0JBQWdCLEVBQzVCLDJFQUNGLENBQUM7RUFDSDtFQUNBcEIsRUFBRSxDQUFDQyxJQUFJLEdBQUdGLEdBQUcsQ0FBQ3FFLGtCQUFrQixDQUFDL0IsV0FBVyxDQUFDO0VBQzdDckMsRUFBRSxDQUFDRSxHQUFHLEdBQUd3RSxPQUFPLENBQUNDLGtCQUFrQjtBQUNyQztBQUVBQyxNQUFNLENBQUNDLE9BQU8sR0FBRztFQUNmTCxhQUFhO0VBQ2JGLGdCQUFnQjtFQUNoQm5FO0FBQ0YsQ0FBQyIsImlnbm9yZUxpc3QiOltdfQ==
216
+ var _default = exports.default = new GameCenterAuth();
217
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfY3J5cHRvIiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsInJlcXVpcmUiLCJfbm9kZUZvcmdlIiwiX0F1dGhBZGFwdGVyIiwiZSIsIl9fZXNNb2R1bGUiLCJkZWZhdWx0IiwiR2FtZUNlbnRlckF1dGgiLCJBdXRoQWRhcHRlciIsImNvbnN0cnVjdG9yIiwiY2EiLCJjZXJ0IiwidXJsIiwiY2FjaGUiLCJidW5kbGVJZCIsInZhbGlkYXRlT3B0aW9ucyIsIm9wdGlvbnMiLCJFcnJvciIsImxvYWRpbmdQcm9taXNlIiwibG9hZENlcnRpZmljYXRlIiwiZW5hYmxlSW5zZWN1cmVBdXRoIiwicm9vdENlcnRpZmljYXRlVXJsIiwiY2VydGlmaWNhdGUiLCJoZWFkZXJzIiwiZmV0Y2hDZXJ0aWZpY2F0ZSIsImdldCIsInBhcnNlSW50IiwiUGFyc2UiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwicGtpIiwiY2VydGlmaWNhdGVGcm9tUGVtIiwidmVyaWZ5UHVibGljS2V5VXJsIiwicHVibGljS2V5VXJsIiwicmVnZXgiLCJ0ZXN0IiwicmVzcG9uc2UiLCJmZXRjaCIsIm9rIiwiY29udGVudFR5cGUiLCJpc1BlbSIsImluY2x1ZGVzIiwidGV4dCIsImRhdGEiLCJhcnJheUJ1ZmZlciIsImJpbmFyeURhdGEiLCJCdWZmZXIiLCJmcm9tIiwiYXNuMUNlcnQiLCJhc24xIiwiZnJvbURlciIsInRvU3RyaW5nIiwiZm9yZ2VDZXJ0IiwiY2VydGlmaWNhdGVGcm9tQXNuMSIsImNlcnRpZmljYXRlVG9QZW0iLCJnZXRBcHBsZUNlcnRpZmljYXRlIiwiY2FjaGVDb250cm9sIiwiZXhwaXJlIiwibWF0Y2giLCJ2ZXJpZnlQdWJsaWNLZXlJc3N1ZXIiLCJzZXRUaW1lb3V0IiwicHVibGljS2V5Q2VydCIsInZlcmlmeSIsInZlcmlmeVNpZ25hdHVyZSIsInB1YmxpY0tleSIsImF1dGhEYXRhIiwidmVyaWZpZXIiLCJjcnlwdG8iLCJjcmVhdGVWZXJpZnkiLCJ1cGRhdGUiLCJpZCIsImNvbnZlcnRUaW1lc3RhbXBUb0JpZ0VuZGlhbiIsInRpbWVzdGFtcCIsInNhbHQiLCJzaWduYXR1cmUiLCJ2YWxpZGF0ZUF1dGhEYXRhIiwicmVxdWlyZWRLZXlzIiwicHVzaCIsImtleSIsImJ1ZmZlciIsImFsbG9jIiwid3JpdGVCaWdVSW50NjRCRSIsIkJpZ0ludCIsIl9kZWZhdWx0IiwiZXhwb3J0cyJdLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2djZW50ZXIuanMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBQYXJzZSBTZXJ2ZXIgYXV0aGVudGljYXRpb24gYWRhcHRlciBmb3IgQXBwbGUgR2FtZSBDZW50ZXIuXG4gKlxuICogQGNsYXNzIEFwcGxlR2FtZUNlbnRlckFkYXB0ZXJcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIC0gQ29uZmlndXJhdGlvbiBvcHRpb25zIGZvciB0aGUgYWRhcHRlci5cbiAqIEBwYXJhbSB7c3RyaW5nfSBvcHRpb25zLmJ1bmRsZUlkIC0gWW91ciBBcHBsZSBHYW1lIENlbnRlciBidW5kbGUgSUQuIFJlcXVpcmVkIGZvciBzZWN1cmUgYXV0aGVudGljYXRpb24uXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLmVuYWJsZUluc2VjdXJlQXV0aD1mYWxzZV0gLSAqKltERVBSRUNBVEVEXSoqIEVuYWJsZSBpbnNlY3VyZSBhdXRoZW50aWNhdGlvbiAobm90IHJlY29tbWVuZGVkKS5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gYXV0aERhdGEgLSBUaGUgYXV0aGVudGljYXRpb24gZGF0YSBwcm92aWRlZCBieSB0aGUgY2xpZW50LlxuICogQHBhcmFtIHtzdHJpbmd9IGF1dGhEYXRhLmlkIC0gVGhlIHVzZXIgSUQgb2J0YWluZWQgZnJvbSBBcHBsZSBHYW1lIENlbnRlci5cbiAqIEBwYXJhbSB7c3RyaW5nfSBhdXRoRGF0YS5wdWJsaWNLZXlVcmwgLSBUaGUgcHVibGljIGtleSBVUkwgb2J0YWluZWQgZnJvbSBBcHBsZSBHYW1lIENlbnRlci5cbiAqIEBwYXJhbSB7c3RyaW5nfSBhdXRoRGF0YS50aW1lc3RhbXAgLSBUaGUgdGltZXN0YW1wIG9idGFpbmVkIGZyb20gQXBwbGUgR2FtZSBDZW50ZXIuXG4gKiBAcGFyYW0ge3N0cmluZ30gYXV0aERhdGEuc2lnbmF0dXJlIC0gVGhlIHNpZ25hdHVyZSBvYnRhaW5lZCBmcm9tIEFwcGxlIEdhbWUgQ2VudGVyLlxuICogQHBhcmFtIHtzdHJpbmd9IGF1dGhEYXRhLnNhbHQgLSBUaGUgc2FsdCBvYnRhaW5lZCBmcm9tIEFwcGxlIEdhbWUgQ2VudGVyLlxuICogQHBhcmFtIHtzdHJpbmd9IFthdXRoRGF0YS5idW5kbGVJZF0gLSAqKltERVBSRUNBVEVEXSoqIFRoZSBidW5kbGUgSUQgb2J0YWluZWQgZnJvbSBBcHBsZSBHYW1lIENlbnRlciAocmVxdWlyZWQgZm9yIGluc2VjdXJlIGF1dGhlbnRpY2F0aW9uKS5cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqICMjIFBhcnNlIFNlcnZlciBDb25maWd1cmF0aW9uXG4gKiBUaGUgZm9sbG93aW5nIGBhdXRoRGF0YWAgZmllbGRzIGFyZSByZXF1aXJlZDpcbiAqIGBpZGAsIGBwdWJsaWNLZXlVcmxgLCBgdGltZXN0YW1wYCwgYHNpZ25hdHVyZWAsIGFuZCBgc2FsdGAuIFRoZXNlIGZpZWxkcyBhcmUgdmFsaWRhdGVkIGFnYWluc3QgdGhlIGNvbmZpZ3VyZWQgYGJ1bmRsZUlkYCBmb3IgYWRkaXRpb25hbCBzZWN1cml0eS5cbiAqXG4gKiBUbyBjb25maWd1cmUgUGFyc2UgU2VydmVyIGZvciBBcHBsZSBHYW1lIENlbnRlciBhdXRoZW50aWNhdGlvbiwgdXNlIHRoZSBmb2xsb3dpbmcgc3RydWN0dXJlOlxuICogYGBganNvblxuICoge1xuICogIFwiYXV0aFwiOiB7XG4gKiAgICBcImdjZW50ZXJcIjoge1xuICogICAgIFwiYnVuZGxlSWRcIjogXCJjb20udmFsaWQuYXBwXCJcbiAqICB9XG4gKiB9XG4gKiBgYGBcbiAqXG4gKiAjIyBJbnNlY3VyZSBBdXRoZW50aWNhdGlvbiAoTm90IFJlY29tbWVuZGVkKVxuICogVGhlIGZvbGxvd2luZyBgYXV0aERhdGFgIGZpZWxkcyBhcmUgcmVxdWlyZWQgZm9yIGluc2VjdXJlIGF1dGhlbnRpY2F0aW9uOlxuICogYGlkYCwgYHB1YmxpY0tleVVybGAsIGB0aW1lc3RhbXBgLCBgc2lnbmF0dXJlYCwgYHNhbHRgLCBhbmQgYGJ1bmRsZUlkYCAoKipbREVQUkVDQVRFRF0qKikuIFRoaXMgZmxvdyBpcyBpbnNlY3VyZSBhbmQgcG9zZXMgcG90ZW50aWFsIHNlY3VyaXR5IHJpc2tzLlxuICpcbiAqIFRvIGNvbmZpZ3VyZSBQYXJzZSBTZXJ2ZXIgZm9yIGluc2VjdXJlIGF1dGhlbnRpY2F0aW9uLCB1c2UgdGhlIGZvbGxvd2luZyBzdHJ1Y3R1cmU6XG4gKiBgYGBqc29uXG4gKiB7XG4gKiAgIFwiYXV0aFwiOiB7XG4gKiAgICBcImdjZW50ZXJcIjoge1xuICogICAgICBcImVuYWJsZUluc2VjdXJlQXV0aFwiOiB0cnVlXG4gKiAgIH1cbiAqIH1cbiAqIGBgYFxuICpcbiAqICMjIyBEZXByZWNhdGlvbiBOb3RpY2VcbiAqIFRoZSBgZW5hYmxlSW5zZWN1cmVBdXRoYCBvcHRpb24gYW5kIGBhdXRoRGF0YS5idW5kbGVJZGAgcGFyYW1ldGVyIGFyZSBkZXByZWNhdGVkIGFuZCBtYXkgYmUgcmVtb3ZlZCBpbiBmdXR1cmUgcmVsZWFzZXMuIFVzZSBzZWN1cmUgYXV0aGVudGljYXRpb24gd2l0aCB0aGUgYGJ1bmRsZUlkYCBjb25maWd1cmVkIGluIHRoZSBgb3B0aW9uc2Agb2JqZWN0IGluc3RlYWQuXG4gKlxuICpcbiAqIEBleGFtcGxlIDxjYXB0aW9uPlNlY3VyZSBBdXRoZW50aWNhdGlvbiBFeGFtcGxlPC9jYXB0aW9uPlxuICogLy8gRXhhbXBsZSBhdXRoRGF0YSBmb3Igc2VjdXJlIGF1dGhlbnRpY2F0aW9uOlxuICogY29uc3QgYXV0aERhdGEgPSB7XG4gKiAgIGdjZW50ZXI6IHtcbiAqICAgICBpZDogXCIxMjM0NTY3XCIsXG4gKiAgICAgcHVibGljS2V5VXJsOiBcImh0dHBzOi8vdmFsaWQuYXBwbGUuY29tL3B1YmxpYy90aW1lb3V0LmNlclwiLFxuICogICAgIHRpbWVzdGFtcDogMTQ2MDk4MTQyMTMwMyxcbiAqICAgICBzYWx0OiBcInNhbHRTVD09XCIsXG4gKiAgICAgc2lnbmF0dXJlOiBcIlBvRHdmMzlEQ040NjRCNDlqSkNVMGQ5WTBKXCJcbiAqICAgfVxuICogfTtcbiAqXG4gKiBAZXhhbXBsZSA8Y2FwdGlvbj5JbnNlY3VyZSBBdXRoZW50aWNhdGlvbiBFeGFtcGxlIChOb3QgUmVjb21tZW5kZWQpPC9jYXB0aW9uPlxuICogLy8gRXhhbXBsZSBhdXRoRGF0YSBmb3IgaW5zZWN1cmUgYXV0aGVudGljYXRpb246XG4gKiBjb25zdCBhdXRoRGF0YSA9IHtcbiAqICAgZ2NlbnRlcjoge1xuICogICAgIGlkOiBcIjEyMzQ1NjdcIixcbiAqICAgICBwdWJsaWNLZXlVcmw6IFwiaHR0cHM6Ly92YWxpZC5hcHBsZS5jb20vcHVibGljL3RpbWVvdXQuY2VyXCIsXG4gKiAgICAgdGltZXN0YW1wOiAxNDYwOTgxNDIxMzAzLFxuICogICAgIHNhbHQ6IFwic2FsdFNUPT1cIixcbiAqICAgICBzaWduYXR1cmU6IFwiUG9Ed2YzOURDTjQ2NEI0OWpKQ1UwZDlZMEpcIixcbiAqICAgICBidW5kbGVJZDogXCJjb20udmFsaWQuYXBwXCIgLy8gRGVwcmVjYXRlZC5cbiAqICAgfVxuICogfTtcbiAqXG4gKiBAc2VlIHtAbGluayBodHRwczovL2RldmVsb3Blci5hcHBsZS5jb20vZG9jdW1lbnRhdGlvbi9nYW1la2l0L2drbG9jYWxwbGF5ZXIvMzUxNjI4My1mZXRjaGl0ZW1zIEFwcGxlIEdhbWUgQ2VudGVyIERvY3VtZW50YXRpb259XG4gKi9cbi8qIGdsb2JhbCBCaWdJbnQgKi9cblxuaW1wb3J0IGNyeXB0byBmcm9tICdjcnlwdG8nO1xuaW1wb3J0IHsgYXNuMSwgcGtpIH0gZnJvbSAnbm9kZS1mb3JnZSc7XG5pbXBvcnQgQXV0aEFkYXB0ZXIgZnJvbSAnLi9BdXRoQWRhcHRlcic7XG5jbGFzcyBHYW1lQ2VudGVyQXV0aCBleHRlbmRzIEF1dGhBZGFwdGVyIHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoKTtcbiAgICB0aGlzLmNhID0geyBjZXJ0OiBudWxsLCB1cmw6IG51bGwgfTtcbiAgICB0aGlzLmNhY2hlID0ge307XG4gICAgdGhpcy5idW5kbGVJZCA9ICcnO1xuICB9XG5cbiAgdmFsaWRhdGVPcHRpb25zKG9wdGlvbnMpIHtcbiAgICBpZiAoIW9wdGlvbnMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignR2FtZSBjZW50ZXIgYXV0aCBvcHRpb25zIGFyZSByZXF1aXJlZC4nKTtcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMubG9hZGluZ1Byb21pc2UpIHtcbiAgICAgIHRoaXMubG9hZGluZ1Byb21pc2UgPSB0aGlzLmxvYWRDZXJ0aWZpY2F0ZShvcHRpb25zKTtcbiAgICB9XG5cbiAgICB0aGlzLmVuYWJsZUluc2VjdXJlQXV0aCA9IG9wdGlvbnMuZW5hYmxlSW5zZWN1cmVBdXRoO1xuICAgIHRoaXMuYnVuZGxlSWQgPSBvcHRpb25zLmJ1bmRsZUlkO1xuXG4gICAgaWYgKCF0aGlzLmVuYWJsZUluc2VjdXJlQXV0aCAmJiAhdGhpcy5idW5kbGVJZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdidW5kbGVJZCBpcyByZXF1aXJlZCBmb3Igc2VjdXJlIGF1dGguJyk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgbG9hZENlcnRpZmljYXRlKG9wdGlvbnMpIHtcbiAgICBjb25zdCByb290Q2VydGlmaWNhdGVVcmwgPVxuICAgICAgb3B0aW9ucy5yb290Q2VydGlmaWNhdGVVcmwgfHxcbiAgICAgICdodHRwczovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZEc0Q29kZVNpZ25pbmdSU0E0MDk2U0hBMzg0MjAyMUNBMS5jcnQucGVtJztcblxuICAgIGlmICh0aGlzLmNhLnVybCA9PT0gcm9vdENlcnRpZmljYXRlVXJsKSB7XG4gICAgICByZXR1cm4gcm9vdENlcnRpZmljYXRlVXJsO1xuICAgIH1cblxuICAgIGNvbnN0IHsgY2VydGlmaWNhdGUsIGhlYWRlcnMgfSA9IGF3YWl0IHRoaXMuZmV0Y2hDZXJ0aWZpY2F0ZShyb290Q2VydGlmaWNhdGVVcmwpO1xuXG4gICAgaWYgKFxuICAgICAgaGVhZGVycy5nZXQoJ2NvbnRlbnQtdHlwZScpICE9PSAnYXBwbGljYXRpb24veC1wZW0tZmlsZScgfHxcbiAgICAgICFoZWFkZXJzLmdldCgnY29udGVudC1sZW5ndGgnKSB8fFxuICAgICAgcGFyc2VJbnQoaGVhZGVycy5nZXQoJ2NvbnRlbnQtbGVuZ3RoJyksIDEwKSA+IDEwMDAwXG4gICAgKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ0ludmFsaWQgcm9vdENlcnRpZmljYXRlVVJMLicpO1xuICAgIH1cblxuICAgIHRoaXMuY2EuY2VydCA9IHBraS5jZXJ0aWZpY2F0ZUZyb21QZW0oY2VydGlmaWNhdGUpO1xuICAgIHRoaXMuY2EudXJsID0gcm9vdENlcnRpZmljYXRlVXJsO1xuXG4gICAgcmV0dXJuIHJvb3RDZXJ0aWZpY2F0ZVVybDtcbiAgfVxuXG4gIHZlcmlmeVB1YmxpY0tleVVybChwdWJsaWNLZXlVcmwpIHtcbiAgICBjb25zdCByZWdleCA9IC9eaHR0cHM6XFwvXFwvKD86Wy1fQS1aYS16MC05XStcXC4pezAsfWFwcGxlXFwuY29tXFwvLipcXC5jZXIkLztcbiAgICByZXR1cm4gcmVnZXgudGVzdChwdWJsaWNLZXlVcmwpO1xuICB9XG5cbiAgYXN5bmMgZmV0Y2hDZXJ0aWZpY2F0ZSh1cmwpIHtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKHVybCk7XG4gICAgaWYgKCFyZXNwb25zZS5vaykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gZmV0Y2ggY2VydGlmaWNhdGU6ICR7dXJsfWApO1xuICAgIH1cblxuICAgIGNvbnN0IGNvbnRlbnRUeXBlID0gcmVzcG9uc2UuaGVhZGVycy5nZXQoJ2NvbnRlbnQtdHlwZScpO1xuICAgIGNvbnN0IGlzUGVtID0gY29udGVudFR5cGU/LmluY2x1ZGVzKCdhcHBsaWNhdGlvbi94LXBlbS1maWxlJyk7XG5cbiAgICBpZiAoaXNQZW0pIHtcbiAgICAgIGNvbnN0IGNlcnRpZmljYXRlID0gYXdhaXQgcmVzcG9uc2UudGV4dCgpO1xuICAgICAgcmV0dXJuIHsgY2VydGlmaWNhdGUsIGhlYWRlcnM6IHJlc3BvbnNlLmhlYWRlcnMgfTtcbiAgICB9XG5cbiAgICBjb25zdCBkYXRhID0gYXdhaXQgcmVzcG9uc2UuYXJyYXlCdWZmZXIoKTtcbiAgICBjb25zdCBiaW5hcnlEYXRhID0gQnVmZmVyLmZyb20oZGF0YSk7XG5cbiAgICBjb25zdCBhc24xQ2VydCA9IGFzbjEuZnJvbURlcihiaW5hcnlEYXRhLnRvU3RyaW5nKCdiaW5hcnknKSk7XG4gICAgY29uc3QgZm9yZ2VDZXJ0ID0gcGtpLmNlcnRpZmljYXRlRnJvbUFzbjEoYXNuMUNlcnQpO1xuICAgIGNvbnN0IGNlcnRpZmljYXRlID0gcGtpLmNlcnRpZmljYXRlVG9QZW0oZm9yZ2VDZXJ0KTtcblxuICAgIHJldHVybiB7IGNlcnRpZmljYXRlLCBoZWFkZXJzOiByZXNwb25zZS5oZWFkZXJzIH07XG4gIH1cblxuICBhc3luYyBnZXRBcHBsZUNlcnRpZmljYXRlKHB1YmxpY0tleVVybCkge1xuICAgIGlmICghdGhpcy52ZXJpZnlQdWJsaWNLZXlVcmwocHVibGljS2V5VXJsKSkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsIGBJbnZhbGlkIHB1YmxpY0tleVVybDogJHtwdWJsaWNLZXlVcmx9YCk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuY2FjaGVbcHVibGljS2V5VXJsXSkge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGVbcHVibGljS2V5VXJsXTtcbiAgICB9XG5cbiAgICBjb25zdCB7IGNlcnRpZmljYXRlLCBoZWFkZXJzIH0gPSBhd2FpdCB0aGlzLmZldGNoQ2VydGlmaWNhdGUocHVibGljS2V5VXJsKTtcbiAgICBjb25zdCBjYWNoZUNvbnRyb2wgPSBoZWFkZXJzLmdldCgnY2FjaGUtY29udHJvbCcpO1xuICAgIGNvbnN0IGV4cGlyZSA9IGNhY2hlQ29udHJvbD8ubWF0Y2goL21heC1hZ2U9KFswLTldKykvKTtcblxuICAgIHRoaXMudmVyaWZ5UHVibGljS2V5SXNzdWVyKGNlcnRpZmljYXRlLCBwdWJsaWNLZXlVcmwpO1xuXG4gICAgaWYgKGV4cGlyZSkge1xuICAgICAgdGhpcy5jYWNoZVtwdWJsaWNLZXlVcmxdID0gY2VydGlmaWNhdGU7XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IGRlbGV0ZSB0aGlzLmNhY2hlW3B1YmxpY0tleVVybF0sIHBhcnNlSW50KGV4cGlyZVsxXSwgMTApICogMTAwMCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNlcnRpZmljYXRlO1xuICB9XG5cbiAgdmVyaWZ5UHVibGljS2V5SXNzdWVyKGNlcnQsIHB1YmxpY0tleVVybCkge1xuICAgIGNvbnN0IHB1YmxpY0tleUNlcnQgPSBwa2kuY2VydGlmaWNhdGVGcm9tUGVtKGNlcnQpO1xuXG4gICAgaWYgKCF0aGlzLmNhLmNlcnQpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCxcbiAgICAgICAgJ1Jvb3QgY2VydGlmaWNhdGUgaXMgaW52YWxpZCBvciBtaXNzaW5nLidcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLmNhLmNlcnQudmVyaWZ5KHB1YmxpY0tleUNlcnQpKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgYEludmFsaWQgcHVibGljS2V5VXJsOiAke3B1YmxpY0tleVVybH1gKTtcbiAgICB9XG4gIH1cblxuICB2ZXJpZnlTaWduYXR1cmUocHVibGljS2V5LCBhdXRoRGF0YSkge1xuICAgIGNvbnN0IGJ1bmRsZUlkID0gdGhpcy5idW5kbGVJZCB8fCAodGhpcy5lbmFibGVJbnNlY3VyZUF1dGggJiYgYXV0aERhdGEuYnVuZGxlSWQpO1xuXG4gICAgY29uc3QgdmVyaWZpZXIgPSBjcnlwdG8uY3JlYXRlVmVyaWZ5KCdzaGEyNTYnKTtcbiAgICB2ZXJpZmllci51cGRhdGUoQnVmZmVyLmZyb20oYXV0aERhdGEuaWQsICd1dGY4JykpO1xuICAgIHZlcmlmaWVyLnVwZGF0ZShCdWZmZXIuZnJvbShidW5kbGVJZCwgJ3V0ZjgnKSk7XG4gICAgdmVyaWZpZXIudXBkYXRlKHRoaXMuY29udmVydFRpbWVzdGFtcFRvQmlnRW5kaWFuKGF1dGhEYXRhLnRpbWVzdGFtcCkpO1xuICAgIHZlcmlmaWVyLnVwZGF0ZShCdWZmZXIuZnJvbShhdXRoRGF0YS5zYWx0LCAnYmFzZTY0JykpO1xuXG4gICAgaWYgKCF2ZXJpZmllci52ZXJpZnkocHVibGljS2V5LCBhdXRoRGF0YS5zaWduYXR1cmUsICdiYXNlNjQnKSkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdJbnZhbGlkIHNpZ25hdHVyZS4nKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyB2YWxpZGF0ZUF1dGhEYXRhKGF1dGhEYXRhKSB7XG5cbiAgICBjb25zdCByZXF1aXJlZEtleXMgPSBbJ2lkJywgJ3B1YmxpY0tleVVybCcsICd0aW1lc3RhbXAnLCAnc2lnbmF0dXJlJywgJ3NhbHQnXTtcbiAgICBpZiAodGhpcy5lbmFibGVJbnNlY3VyZUF1dGgpIHtcbiAgICAgIHJlcXVpcmVkS2V5cy5wdXNoKCdidW5kbGVJZCcpO1xuICAgIH1cblxuICAgIGZvciAoY29uc3Qga2V5IG9mIHJlcXVpcmVkS2V5cykge1xuICAgICAgaWYgKCFhdXRoRGF0YVtrZXldKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCBgQXV0aERhdGEgJHtrZXl9IGlzIG1pc3NpbmcuYCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgYXdhaXQgdGhpcy5sb2FkaW5nUHJvbWlzZTtcblxuICAgIGNvbnN0IHB1YmxpY0tleSA9IGF3YWl0IHRoaXMuZ2V0QXBwbGVDZXJ0aWZpY2F0ZShhdXRoRGF0YS5wdWJsaWNLZXlVcmwpO1xuICAgIHRoaXMudmVyaWZ5U2lnbmF0dXJlKHB1YmxpY0tleSwgYXV0aERhdGEpO1xuICB9XG5cbiAgY29udmVydFRpbWVzdGFtcFRvQmlnRW5kaWFuKHRpbWVzdGFtcCkge1xuICAgIGNvbnN0IGJ1ZmZlciA9IEJ1ZmZlci5hbGxvYyg4KTtcbiAgICBidWZmZXIud3JpdGVCaWdVSW50NjRCRShCaWdJbnQodGltZXN0YW1wKSk7XG4gICAgcmV0dXJuIGJ1ZmZlcjtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBuZXcgR2FtZUNlbnRlckF1dGgoKTtcbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBOEVBLElBQUFBLE9BQUEsR0FBQUMsc0JBQUEsQ0FBQUMsT0FBQTtBQUNBLElBQUFDLFVBQUEsR0FBQUQsT0FBQTtBQUNBLElBQUFFLFlBQUEsR0FBQUgsc0JBQUEsQ0FBQUMsT0FBQTtBQUF3QyxTQUFBRCx1QkFBQUksQ0FBQSxXQUFBQSxDQUFBLElBQUFBLENBQUEsQ0FBQUMsVUFBQSxHQUFBRCxDQUFBLEtBQUFFLE9BQUEsRUFBQUYsQ0FBQTtBQWhGeEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7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
@@ -1,37 +1,125 @@
1
1
  "use strict";
2
2
 
3
- // Helper functions for accessing the github API.
4
- var Parse = require('parse/node').Parse;
5
- const httpsRequest = require('./httpsRequest');
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _BaseCodeAuthAdapter = _interopRequireDefault(require("./BaseCodeAuthAdapter"));
8
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
9
+ /**
10
+ * Parse Server authentication adapter for GitHub.
11
+ * @class GitHubAdapter
12
+ * @param {Object} options - The adapter configuration options.
13
+ * @param {string} options.clientId - The GitHub App Client ID. Required for secure authentication.
14
+ * @param {string} options.clientSecret - The GitHub App Client Secret. Required for secure authentication.
15
+ * @param {boolean} [options.enableInsecureAuth=false] - **[DEPRECATED]** Enable insecure authentication (not recommended).
16
+ *
17
+ * @param {Object} authData - The authentication data provided by the client.
18
+ * @param {string} authData.code - The authorization code from GitHub. Required for secure authentication.
19
+ * @param {string} [authData.id] - **[DEPRECATED]** The GitHub user ID (required for insecure authentication).
20
+ * @param {string} [authData.access_token] - **[DEPRECATED]** The GitHub access token (required for insecure authentication).
21
+ *
22
+ * @description
23
+ * ## Parse Server Configuration
24
+ * * To configure Parse Server for GitHub authentication, use the following structure:
25
+ * ```json
26
+ * {
27
+ * "auth": {
28
+ * "github": {
29
+ * "clientId": "12345",
30
+ * "clientSecret": "abcde"
31
+ * }
32
+ * }
33
+ * ```
34
+ *
35
+ * The GitHub adapter exchanges the `authData.code` provided by the client for an access token using GitHub's OAuth API. The following `authData` field is required:
36
+ * - `code`
37
+ *
38
+ * ## Insecure Authentication (Not Recommended)
39
+ * Insecure authentication uses the `authData.id` and `authData.access_token` provided by the client. This flow is insecure, deprecated, and poses potential security risks. The following `authData` fields are required:
40
+ * - `id` (**[DEPRECATED]**): The GitHub user ID.
41
+ * - `access_token` (**[DEPRECATED]**): The GitHub access token.
42
+ * To configure Parse Server for insecure authentication, use the following structure:
43
+ * ```json
44
+ * {
45
+ * "auth": {
46
+ * "github": {
47
+ * "enableInsecureAuth": true
48
+ * }
49
+ * }
50
+ * ```
51
+ *
52
+ * ### Deprecation Notice
53
+ * The `enableInsecureAuth` option and insecure `authData` fields (`id`, `access_token`) are deprecated and will be removed in future versions. Use secure authentication with `clientId` and `clientSecret`.
54
+ *
55
+ * @example <caption>Secure Authentication Example</caption>
56
+ * // Example authData for secure authentication:
57
+ * const authData = {
58
+ * github: {
59
+ * code: "abc123def456ghi789"
60
+ * }
61
+ * };
62
+ *
63
+ * @example <caption>Insecure Authentication Example (Not Recommended)</caption>
64
+ * // Example authData for insecure authentication:
65
+ * const authData = {
66
+ * github: {
67
+ * id: "1234567",
68
+ * access_token: "abc123def456ghi789" // Deprecated.
69
+ * }
70
+ * };
71
+ *
72
+ * @note `enableInsecureAuth` will be removed in future versions. Use secure authentication with `clientId` and `clientSecret`.
73
+ * @note Secure authentication exchanges the `code` provided by the client for an access token using GitHub's OAuth API.
74
+ *
75
+ * @see {@link https://docs.github.com/en/developers/apps/authorizing-oauth-apps GitHub OAuth Documentation}
76
+ */
6
77
 
7
- // Returns a promise that fulfills iff this user id is valid.
8
- function validateAuthData(authData) {
9
- return request('user', authData.access_token).then(data => {
10
- if (data && data.id == authData.id) {
11
- return;
78
+ class GitHubAdapter extends _BaseCodeAuthAdapter.default {
79
+ constructor() {
80
+ super('GitHub');
81
+ }
82
+ async getAccessTokenFromCode(authData) {
83
+ const tokenUrl = 'https://github.com/login/oauth/access_token';
84
+ const response = await fetch(tokenUrl, {
85
+ method: 'POST',
86
+ headers: {
87
+ 'Content-Type': 'application/json',
88
+ Accept: 'application/json'
89
+ },
90
+ body: JSON.stringify({
91
+ client_id: this.clientId,
92
+ client_secret: this.clientSecret,
93
+ code: authData.code
94
+ })
95
+ });
96
+ if (!response.ok) {
97
+ throw new Parse.Error(Parse.Error.VALIDATION_ERROR, `Failed to exchange code for token: ${response.statusText}`);
12
98
  }
13
- throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Github auth is invalid for this user.');
14
- });
15
- }
16
-
17
- // Returns a promise that fulfills iff this app id is valid.
18
- function validateAppId() {
19
- return Promise.resolve();
20
- }
21
-
22
- // A promisey wrapper for api requests
23
- function request(path, access_token) {
24
- return httpsRequest.get({
25
- host: 'api.github.com',
26
- path: '/' + path,
27
- headers: {
28
- Authorization: 'bearer ' + access_token,
29
- 'User-Agent': 'parse-server'
99
+ const data = await response.json();
100
+ if (data.error) {
101
+ throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, data.error_description || data.error);
102
+ }
103
+ return data.access_token;
104
+ }
105
+ async getUserFromAccessToken(accessToken) {
106
+ const userApiUrl = 'https://api.github.com/user';
107
+ const response = await fetch(userApiUrl, {
108
+ method: 'GET',
109
+ headers: {
110
+ Authorization: `Bearer ${accessToken}`,
111
+ Accept: 'application/json'
112
+ }
113
+ });
114
+ if (!response.ok) {
115
+ throw new Parse.Error(Parse.Error.VALIDATION_ERROR, `Failed to fetch GitHub user: ${response.statusText}`);
116
+ }
117
+ const userData = await response.json();
118
+ if (!userData.id || !userData.login) {
119
+ throw new Parse.Error(Parse.Error.VALIDATION_ERROR, 'Invalid GitHub user data received.');
30
120
  }
31
- });
121
+ return userData;
122
+ }
32
123
  }
33
- module.exports = {
34
- validateAppId: validateAppId,
35
- validateAuthData: validateAuthData
36
- };
37
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJQYXJzZSIsInJlcXVpcmUiLCJodHRwc1JlcXVlc3QiLCJ2YWxpZGF0ZUF1dGhEYXRhIiwiYXV0aERhdGEiLCJyZXF1ZXN0IiwiYWNjZXNzX3Rva2VuIiwidGhlbiIsImRhdGEiLCJpZCIsIkVycm9yIiwiT0JKRUNUX05PVF9GT1VORCIsInZhbGlkYXRlQXBwSWQiLCJQcm9taXNlIiwicmVzb2x2ZSIsInBhdGgiLCJnZXQiLCJob3N0IiwiaGVhZGVycyIsIkF1dGhvcml6YXRpb24iLCJtb2R1bGUiLCJleHBvcnRzIl0sInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL0FkYXB0ZXJzL0F1dGgvZ2l0aHViLmpzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIEhlbHBlciBmdW5jdGlvbnMgZm9yIGFjY2Vzc2luZyB0aGUgZ2l0aHViIEFQSS5cbnZhciBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKS5QYXJzZTtcbmNvbnN0IGh0dHBzUmVxdWVzdCA9IHJlcXVpcmUoJy4vaHR0cHNSZXF1ZXN0Jyk7XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWZmIHRoaXMgdXNlciBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXV0aERhdGEoYXV0aERhdGEpIHtcbiAgcmV0dXJuIHJlcXVlc3QoJ3VzZXInLCBhdXRoRGF0YS5hY2Nlc3NfdG9rZW4pLnRoZW4oZGF0YSA9PiB7XG4gICAgaWYgKGRhdGEgJiYgZGF0YS5pZCA9PSBhdXRoRGF0YS5pZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ0dpdGh1YiBhdXRoIGlzIGludmFsaWQgZm9yIHRoaXMgdXNlci4nKTtcbiAgfSk7XG59XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWZmIHRoaXMgYXBwIGlkIGlzIHZhbGlkLlxuZnVuY3Rpb24gdmFsaWRhdGVBcHBJZCgpIHtcbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xufVxuXG4vLyBBIHByb21pc2V5IHdyYXBwZXIgZm9yIGFwaSByZXF1ZXN0c1xuZnVuY3Rpb24gcmVxdWVzdChwYXRoLCBhY2Nlc3NfdG9rZW4pIHtcbiAgcmV0dXJuIGh0dHBzUmVxdWVzdC5nZXQoe1xuICAgIGhvc3Q6ICdhcGkuZ2l0aHViLmNvbScsXG4gICAgcGF0aDogJy8nICsgcGF0aCxcbiAgICBoZWFkZXJzOiB7XG4gICAgICBBdXRob3JpemF0aW9uOiAnYmVhcmVyICcgKyBhY2Nlc3NfdG9rZW4sXG4gICAgICAnVXNlci1BZ2VudCc6ICdwYXJzZS1zZXJ2ZXInLFxuICAgIH0sXG4gIH0pO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgdmFsaWRhdGVBcHBJZDogdmFsaWRhdGVBcHBJZCxcbiAgdmFsaWRhdGVBdXRoRGF0YTogdmFsaWRhdGVBdXRoRGF0YSxcbn07XG4iXSwibWFwcGluZ3MiOiI7O0FBQUE7QUFDQSxJQUFJQSxLQUFLLEdBQUdDLE9BQU8sQ0FBQyxZQUFZLENBQUMsQ0FBQ0QsS0FBSztBQUN2QyxNQUFNRSxZQUFZLEdBQUdELE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQzs7QUFFOUM7QUFDQSxTQUFTRSxnQkFBZ0JBLENBQUNDLFFBQVEsRUFBRTtFQUNsQyxPQUFPQyxPQUFPLENBQUMsTUFBTSxFQUFFRCxRQUFRLENBQUNFLFlBQVksQ0FBQyxDQUFDQyxJQUFJLENBQUNDLElBQUksSUFBSTtJQUN6RCxJQUFJQSxJQUFJLElBQUlBLElBQUksQ0FBQ0MsRUFBRSxJQUFJTCxRQUFRLENBQUNLLEVBQUUsRUFBRTtNQUNsQztJQUNGO0lBQ0EsTUFBTSxJQUFJVCxLQUFLLENBQUNVLEtBQUssQ0FBQ1YsS0FBSyxDQUFDVSxLQUFLLENBQUNDLGdCQUFnQixFQUFFLHVDQUF1QyxDQUFDO0VBQzlGLENBQUMsQ0FBQztBQUNKOztBQUVBO0FBQ0EsU0FBU0MsYUFBYUEsQ0FBQSxFQUFHO0VBQ3ZCLE9BQU9DLE9BQU8sQ0FBQ0MsT0FBTyxDQUFDLENBQUM7QUFDMUI7O0FBRUE7QUFDQSxTQUFTVCxPQUFPQSxDQUFDVSxJQUFJLEVBQUVULFlBQVksRUFBRTtFQUNuQyxPQUFPSixZQUFZLENBQUNjLEdBQUcsQ0FBQztJQUN0QkMsSUFBSSxFQUFFLGdCQUFnQjtJQUN0QkYsSUFBSSxFQUFFLEdBQUcsR0FBR0EsSUFBSTtJQUNoQkcsT0FBTyxFQUFFO01BQ1BDLGFBQWEsRUFBRSxTQUFTLEdBQUdiLFlBQVk7TUFDdkMsWUFBWSxFQUFFO0lBQ2hCO0VBQ0YsQ0FBQyxDQUFDO0FBQ0o7QUFFQWMsTUFBTSxDQUFDQyxPQUFPLEdBQUc7RUFDZlQsYUFBYSxFQUFFQSxhQUFhO0VBQzVCVCxnQkFBZ0IsRUFBRUE7QUFDcEIsQ0FBQyIsImlnbm9yZUxpc3QiOltdfQ==
124
+ var _default = exports.default = new GitHubAdapter();
125
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfQmFzZUNvZGVBdXRoQWRhcHRlciIsIl9pbnRlcm9wUmVxdWlyZURlZmF1bHQiLCJyZXF1aXJlIiwiZSIsIl9fZXNNb2R1bGUiLCJkZWZhdWx0IiwiR2l0SHViQWRhcHRlciIsIkJhc2VDb2RlQXV0aEFkYXB0ZXIiLCJjb25zdHJ1Y3RvciIsImdldEFjY2Vzc1Rva2VuRnJvbUNvZGUiLCJhdXRoRGF0YSIsInRva2VuVXJsIiwicmVzcG9uc2UiLCJmZXRjaCIsIm1ldGhvZCIsImhlYWRlcnMiLCJBY2NlcHQiLCJib2R5IiwiSlNPTiIsInN0cmluZ2lmeSIsImNsaWVudF9pZCIsImNsaWVudElkIiwiY2xpZW50X3NlY3JldCIsImNsaWVudFNlY3JldCIsImNvZGUiLCJvayIsIlBhcnNlIiwiRXJyb3IiLCJWQUxJREFUSU9OX0VSUk9SIiwic3RhdHVzVGV4dCIsImRhdGEiLCJqc29uIiwiZXJyb3IiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwiZXJyb3JfZGVzY3JpcHRpb24iLCJhY2Nlc3NfdG9rZW4iLCJnZXRVc2VyRnJvbUFjY2Vzc1Rva2VuIiwiYWNjZXNzVG9rZW4iLCJ1c2VyQXBpVXJsIiwiQXV0aG9yaXphdGlvbiIsInVzZXJEYXRhIiwiaWQiLCJsb2dpbiIsIl9kZWZhdWx0IiwiZXhwb3J0cyJdLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2dpdGh1Yi5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFBhcnNlIFNlcnZlciBhdXRoZW50aWNhdGlvbiBhZGFwdGVyIGZvciBHaXRIdWIuXG4gKiBAY2xhc3MgR2l0SHViQWRhcHRlclxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgLSBUaGUgYWRhcHRlciBjb25maWd1cmF0aW9uIG9wdGlvbnMuXG4gKiBAcGFyYW0ge3N0cmluZ30gb3B0aW9ucy5jbGllbnRJZCAtIFRoZSBHaXRIdWIgQXBwIENsaWVudCBJRC4gUmVxdWlyZWQgZm9yIHNlY3VyZSBhdXRoZW50aWNhdGlvbi5cbiAqIEBwYXJhbSB7c3RyaW5nfSBvcHRpb25zLmNsaWVudFNlY3JldCAtIFRoZSBHaXRIdWIgQXBwIENsaWVudCBTZWNyZXQuIFJlcXVpcmVkIGZvciBzZWN1cmUgYXV0aGVudGljYXRpb24uXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLmVuYWJsZUluc2VjdXJlQXV0aD1mYWxzZV0gLSAqKltERVBSRUNBVEVEXSoqIEVuYWJsZSBpbnNlY3VyZSBhdXRoZW50aWNhdGlvbiAobm90IHJlY29tbWVuZGVkKS5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gYXV0aERhdGEgLSBUaGUgYXV0aGVudGljYXRpb24gZGF0YSBwcm92aWRlZCBieSB0aGUgY2xpZW50LlxuICogQHBhcmFtIHtzdHJpbmd9IGF1dGhEYXRhLmNvZGUgLSBUaGUgYXV0aG9yaXphdGlvbiBjb2RlIGZyb20gR2l0SHViLiBSZXF1aXJlZCBmb3Igc2VjdXJlIGF1dGhlbnRpY2F0aW9uLlxuICogQHBhcmFtIHtzdHJpbmd9IFthdXRoRGF0YS5pZF0gLSAqKltERVBSRUNBVEVEXSoqIFRoZSBHaXRIdWIgdXNlciBJRCAocmVxdWlyZWQgZm9yIGluc2VjdXJlIGF1dGhlbnRpY2F0aW9uKS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBbYXV0aERhdGEuYWNjZXNzX3Rva2VuXSAtICoqW0RFUFJFQ0FURURdKiogVGhlIEdpdEh1YiBhY2Nlc3MgdG9rZW4gKHJlcXVpcmVkIGZvciBpbnNlY3VyZSBhdXRoZW50aWNhdGlvbikuXG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiAjIyBQYXJzZSBTZXJ2ZXIgQ29uZmlndXJhdGlvblxuICogKiBUbyBjb25maWd1cmUgUGFyc2UgU2VydmVyIGZvciBHaXRIdWIgYXV0aGVudGljYXRpb24sIHVzZSB0aGUgZm9sbG93aW5nIHN0cnVjdHVyZTpcbiAqIGBgYGpzb25cbiAqIHtcbiAqICBcImF1dGhcIjoge1xuICogICBcImdpdGh1YlwiOiB7XG4gKiAgICAgXCJjbGllbnRJZFwiOiBcIjEyMzQ1XCIsXG4gKiAgICAgXCJjbGllbnRTZWNyZXRcIjogXCJhYmNkZVwiXG4gKiAgIH1cbiAqIH1cbiAqIGBgYFxuICpcbiAqIFRoZSBHaXRIdWIgYWRhcHRlciBleGNoYW5nZXMgdGhlIGBhdXRoRGF0YS5jb2RlYCBwcm92aWRlZCBieSB0aGUgY2xpZW50IGZvciBhbiBhY2Nlc3MgdG9rZW4gdXNpbmcgR2l0SHViJ3MgT0F1dGggQVBJLiBUaGUgZm9sbG93aW5nIGBhdXRoRGF0YWAgZmllbGQgaXMgcmVxdWlyZWQ6XG4gKiAtIGBjb2RlYFxuICpcbiAqICMjIEluc2VjdXJlIEF1dGhlbnRpY2F0aW9uIChOb3QgUmVjb21tZW5kZWQpXG4gKiBJbnNlY3VyZSBhdXRoZW50aWNhdGlvbiB1c2VzIHRoZSBgYXV0aERhdGEuaWRgIGFuZCBgYXV0aERhdGEuYWNjZXNzX3Rva2VuYCBwcm92aWRlZCBieSB0aGUgY2xpZW50LiBUaGlzIGZsb3cgaXMgaW5zZWN1cmUsIGRlcHJlY2F0ZWQsIGFuZCBwb3NlcyBwb3RlbnRpYWwgc2VjdXJpdHkgcmlza3MuIFRoZSBmb2xsb3dpbmcgYGF1dGhEYXRhYCBmaWVsZHMgYXJlIHJlcXVpcmVkOlxuICogLSBgaWRgICgqKltERVBSRUNBVEVEXSoqKTogVGhlIEdpdEh1YiB1c2VyIElELlxuICogLSBgYWNjZXNzX3Rva2VuYCAoKipbREVQUkVDQVRFRF0qKik6IFRoZSBHaXRIdWIgYWNjZXNzIHRva2VuLlxuICogVG8gY29uZmlndXJlIFBhcnNlIFNlcnZlciBmb3IgaW5zZWN1cmUgYXV0aGVudGljYXRpb24sIHVzZSB0aGUgZm9sbG93aW5nIHN0cnVjdHVyZTpcbiAqIGBgYGpzb25cbiAqIHtcbiAqICBcImF1dGhcIjoge1xuICogICAgXCJnaXRodWJcIjoge1xuICogICAgXCJlbmFibGVJbnNlY3VyZUF1dGhcIjogdHJ1ZVxuICogIH1cbiAqIH1cbiAqIGBgYFxuICpcbiAqICMjIyBEZXByZWNhdGlvbiBOb3RpY2VcbiAqIFRoZSBgZW5hYmxlSW5zZWN1cmVBdXRoYCBvcHRpb24gYW5kIGluc2VjdXJlIGBhdXRoRGF0YWAgZmllbGRzIChgaWRgLCBgYWNjZXNzX3Rva2VuYCkgYXJlIGRlcHJlY2F0ZWQgYW5kIHdpbGwgYmUgcmVtb3ZlZCBpbiBmdXR1cmUgdmVyc2lvbnMuIFVzZSBzZWN1cmUgYXV0aGVudGljYXRpb24gd2l0aCBgY2xpZW50SWRgIGFuZCBgY2xpZW50U2VjcmV0YC5cbiAqXG4gKiBAZXhhbXBsZSA8Y2FwdGlvbj5TZWN1cmUgQXV0aGVudGljYXRpb24gRXhhbXBsZTwvY2FwdGlvbj5cbiAqIC8vIEV4YW1wbGUgYXV0aERhdGEgZm9yIHNlY3VyZSBhdXRoZW50aWNhdGlvbjpcbiAqIGNvbnN0IGF1dGhEYXRhID0ge1xuICogICBnaXRodWI6IHtcbiAqICAgICBjb2RlOiBcImFiYzEyM2RlZjQ1NmdoaTc4OVwiXG4gKiAgIH1cbiAqIH07XG4gKlxuICogQGV4YW1wbGUgPGNhcHRpb24+SW5zZWN1cmUgQXV0aGVudGljYXRpb24gRXhhbXBsZSAoTm90IFJlY29tbWVuZGVkKTwvY2FwdGlvbj5cbiAqIC8vIEV4YW1wbGUgYXV0aERhdGEgZm9yIGluc2VjdXJlIGF1dGhlbnRpY2F0aW9uOlxuICogY29uc3QgYXV0aERhdGEgPSB7XG4gKiAgIGdpdGh1Yjoge1xuICogICAgIGlkOiBcIjEyMzQ1NjdcIixcbiAqICAgICBhY2Nlc3NfdG9rZW46IFwiYWJjMTIzZGVmNDU2Z2hpNzg5XCIgLy8gRGVwcmVjYXRlZC5cbiAqICAgfVxuICogfTtcbiAqXG4gKiBAbm90ZSBgZW5hYmxlSW5zZWN1cmVBdXRoYCB3aWxsIGJlIHJlbW92ZWQgaW4gZnV0dXJlIHZlcnNpb25zLiBVc2Ugc2VjdXJlIGF1dGhlbnRpY2F0aW9uIHdpdGggYGNsaWVudElkYCBhbmQgYGNsaWVudFNlY3JldGAuXG4gKiBAbm90ZSBTZWN1cmUgYXV0aGVudGljYXRpb24gZXhjaGFuZ2VzIHRoZSBgY29kZWAgcHJvdmlkZWQgYnkgdGhlIGNsaWVudCBmb3IgYW4gYWNjZXNzIHRva2VuIHVzaW5nIEdpdEh1YidzIE9BdXRoIEFQSS5cbiAqXG4gKiBAc2VlIHtAbGluayBodHRwczovL2RvY3MuZ2l0aHViLmNvbS9lbi9kZXZlbG9wZXJzL2FwcHMvYXV0aG9yaXppbmctb2F1dGgtYXBwcyBHaXRIdWIgT0F1dGggRG9jdW1lbnRhdGlvbn1cbiAqL1xuXG5pbXBvcnQgQmFzZUNvZGVBdXRoQWRhcHRlciBmcm9tICcuL0Jhc2VDb2RlQXV0aEFkYXB0ZXInO1xuY2xhc3MgR2l0SHViQWRhcHRlciBleHRlbmRzIEJhc2VDb2RlQXV0aEFkYXB0ZXIge1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcignR2l0SHViJyk7XG4gIH1cbiAgYXN5bmMgZ2V0QWNjZXNzVG9rZW5Gcm9tQ29kZShhdXRoRGF0YSkge1xuICAgIGNvbnN0IHRva2VuVXJsID0gJ2h0dHBzOi8vZ2l0aHViLmNvbS9sb2dpbi9vYXV0aC9hY2Nlc3NfdG9rZW4nO1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2godG9rZW5VcmwsIHtcbiAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgaGVhZGVyczoge1xuICAgICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgICAgICBBY2NlcHQ6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgIH0sXG4gICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgIGNsaWVudF9pZDogdGhpcy5jbGllbnRJZCxcbiAgICAgICAgY2xpZW50X3NlY3JldDogdGhpcy5jbGllbnRTZWNyZXQsXG4gICAgICAgIGNvZGU6IGF1dGhEYXRhLmNvZGUsXG4gICAgICB9KSxcbiAgICB9KTtcblxuICAgIGlmICghcmVzcG9uc2Uub2spIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5WQUxJREFUSU9OX0VSUk9SLCBgRmFpbGVkIHRvIGV4Y2hhbmdlIGNvZGUgZm9yIHRva2VuOiAke3Jlc3BvbnNlLnN0YXR1c1RleHR9YCk7XG4gICAgfVxuXG4gICAgY29uc3QgZGF0YSA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcbiAgICBpZiAoZGF0YS5lcnJvcikge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsIGRhdGEuZXJyb3JfZGVzY3JpcHRpb24gfHwgZGF0YS5lcnJvcik7XG4gICAgfVxuXG4gICAgcmV0dXJuIGRhdGEuYWNjZXNzX3Rva2VuO1xuICB9XG5cbiAgYXN5bmMgZ2V0VXNlckZyb21BY2Nlc3NUb2tlbihhY2Nlc3NUb2tlbikge1xuICAgIGNvbnN0IHVzZXJBcGlVcmwgPSAnaHR0cHM6Ly9hcGkuZ2l0aHViLmNvbS91c2VyJztcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKHVzZXJBcGlVcmwsIHtcbiAgICAgIG1ldGhvZDogJ0dFVCcsXG4gICAgICBoZWFkZXJzOiB7XG4gICAgICAgIEF1dGhvcml6YXRpb246IGBCZWFyZXIgJHthY2Nlc3NUb2tlbn1gLFxuICAgICAgICBBY2NlcHQ6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBpZiAoIXJlc3BvbnNlLm9rKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuVkFMSURBVElPTl9FUlJPUiwgYEZhaWxlZCB0byBmZXRjaCBHaXRIdWIgdXNlcjogJHtyZXNwb25zZS5zdGF0dXNUZXh0fWApO1xuICAgIH1cblxuICAgIGNvbnN0IHVzZXJEYXRhID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuICAgIGlmICghdXNlckRhdGEuaWQgfHwgIXVzZXJEYXRhLmxvZ2luKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuVkFMSURBVElPTl9FUlJPUiwgJ0ludmFsaWQgR2l0SHViIHVzZXIgZGF0YSByZWNlaXZlZC4nKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdXNlckRhdGE7XG4gIH1cblxufVxuXG5leHBvcnQgZGVmYXVsdCBuZXcgR2l0SHViQWRhcHRlcigpO1xuXG4iXSwibWFwcGluZ3MiOiI7Ozs7OztBQXFFQSxJQUFBQSxvQkFBQSxHQUFBQyxzQkFBQSxDQUFBQyxPQUFBO0FBQXdELFNBQUFELHVCQUFBRSxDQUFBLFdBQUFBLENBQUEsSUFBQUEsQ0FBQSxDQUFBQyxVQUFBLEdBQUFELENBQUEsS0FBQUUsT0FBQSxFQUFBRixDQUFBO0FBckV4RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUdBLE1BQU1HLGFBQWEsU0FBU0MsNEJBQW1CLENBQUM7RUFDOUNDLFdBQVdBLENBQUEsRUFBRztJQUNaLEtBQUssQ0FBQyxRQUFRLENBQUM7RUFDakI7RUFDQSxNQUFNQyxzQkFBc0JBLENBQUNDLFFBQVEsRUFBRTtJQUNyQyxNQUFNQyxRQUFRLEdBQUcsNkNBQTZDO0lBQzlELE1BQU1DLFFBQVEsR0FBRyxNQUFNQyxLQUFLLENBQUNGLFFBQVEsRUFBRTtNQUNyQ0csTUFBTSxFQUFFLE1BQU07TUFDZEMsT0FBTyxFQUFFO1FBQ1AsY0FBYyxFQUFFLGtCQUFrQjtRQUNsQ0MsTUFBTSxFQUFFO01BQ1YsQ0FBQztNQUNEQyxJQUFJLEVBQUVDLElBQUksQ0FBQ0MsU0FBUyxDQUFDO1FBQ25CQyxTQUFTLEVBQUUsSUFBSSxDQUFDQyxRQUFRO1FBQ3hCQyxhQUFhLEVBQUUsSUFBSSxDQUFDQyxZQUFZO1FBQ2hDQyxJQUFJLEVBQUVkLFFBQVEsQ0FBQ2M7TUFDakIsQ0FBQztJQUNILENBQUMsQ0FBQztJQUVGLElBQUksQ0FBQ1osUUFBUSxDQUFDYSxFQUFFLEVBQUU7TUFDaEIsTUFBTSxJQUFJQyxLQUFLLENBQUNDLEtBQUssQ0FBQ0QsS0FBSyxDQUFDQyxLQUFLLENBQUNDLGdCQUFnQixFQUFFLHNDQUFzQ2hCLFFBQVEsQ0FBQ2lCLFVBQVUsRUFBRSxDQUFDO0lBQ2xIO0lBRUEsTUFBTUMsSUFBSSxHQUFHLE1BQU1sQixRQUFRLENBQUNtQixJQUFJLENBQUMsQ0FBQztJQUNsQyxJQUFJRCxJQUFJLENBQUNFLEtBQUssRUFBRTtNQUNkLE1BQU0sSUFBSU4sS0FBSyxDQUFDQyxLQUFLLENBQUNELEtBQUssQ0FBQ0MsS0FBSyxDQUFDTSxnQkFBZ0IsRUFBRUgsSUFBSSxDQUFDSSxpQkFBaUIsSUFBSUosSUFBSSxDQUFDRSxLQUFLLENBQUM7SUFDM0Y7SUFFQSxPQUFPRixJQUFJLENBQUNLLFlBQVk7RUFDMUI7RUFFQSxNQUFNQyxzQkFBc0JBLENBQUNDLFdBQVcsRUFBRTtJQUN4QyxNQUFNQyxVQUFVLEdBQUcsNkJBQTZCO0lBQ2hELE1BQU0xQixRQUFRLEdBQUcsTUFBTUMsS0FBSyxDQUFDeUIsVUFBVSxFQUFFO01BQ3ZDeEIsTUFBTSxFQUFFLEtBQUs7TUFDYkMsT0FBTyxFQUFFO1FBQ1B3QixhQUFhLEVBQUUsVUFBVUYsV0FBVyxFQUFFO1FBQ3RDckIsTUFBTSxFQUFFO01BQ1Y7SUFDRixDQUFDLENBQUM7SUFFRixJQUFJLENBQUNKLFFBQVEsQ0FBQ2EsRUFBRSxFQUFFO01BQ2hCLE1BQU0sSUFBSUMsS0FBSyxDQUFDQyxLQUFLLENBQUNELEtBQUssQ0FBQ0MsS0FBSyxDQUFDQyxnQkFBZ0IsRUFBRSxnQ0FBZ0NoQixRQUFRLENBQUNpQixVQUFVLEVBQUUsQ0FBQztJQUM1RztJQUVBLE1BQU1XLFFBQVEsR0FBRyxNQUFNNUIsUUFBUSxDQUFDbUIsSUFBSSxDQUFDLENBQUM7SUFDdEMsSUFBSSxDQUFDUyxRQUFRLENBQUNDLEVBQUUsSUFBSSxDQUFDRCxRQUFRLENBQUNFLEtBQUssRUFBRTtNQUNuQyxNQUFNLElBQUloQixLQUFLLENBQUNDLEtBQUssQ0FBQ0QsS0FBSyxDQUFDQyxLQUFLLENBQUNDLGdCQUFnQixFQUFFLG9DQUFvQyxDQUFDO0lBQzNGO0lBRUEsT0FBT1ksUUFBUTtFQUNqQjtBQUVGO0FBQUMsSUFBQUcsUUFBQSxHQUFBQyxPQUFBLENBQUF2QyxPQUFBLEdBRWMsSUFBSUMsYUFBYSxDQUFDLENBQUMiLCJpZ25vcmVMaXN0IjpbXX0=