parse-server 8.0.1 → 8.0.2-alpha.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.
Files changed (37) 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 +11 -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 +96 -109
  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 +20 -13
  26. package/lib/Adapters/Auth/wechat.js +105 -25
  27. package/lib/Adapters/Auth/weibo.js +135 -37
  28. package/lib/Auth.js +26 -17
  29. package/lib/Config.js +14 -1
  30. package/lib/Deprecator/Deprecations.js +5 -2
  31. package/lib/Options/Definitions.js +7 -1
  32. package/lib/Options/docs.js +2 -1
  33. package/lib/Options/index.js +1 -1
  34. package/lib/RestWrite.js +4 -5
  35. package/lib/Security/CheckGroups/CheckGroupServerConfig.js +10 -1
  36. package/lib/cli/parse-server.js +1 -1
  37. package/package.json +6 -6
@@ -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?.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?.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+SW5zZWN1cmUgQXV0aGVudGljYXRpb24gRXhhbXBsZSAoTm90IFJlY29tbWVuZGVkKTwvY2FwdGlvbj5cbiAqIC8vIEV4YW1wbGUgYXV0aERhdGEgZm9yIGluc2VjdXJlIGF1dGhlbnRpY2F0aW9uOlxuICogY29uc3QgYXV0aERhdGEgPSB7XG4gKiAgIGdpdGh1Yjoge1xuICogICAgIGlkOiBcIjEyMzQ1NjdcIixcbiAqICAgICBhY2Nlc3NfdG9rZW46IFwiYWJjMTIzZGVmNDU2Z2hpNzg5XCIgLy8gRGVwcmVjYXRlZC5cbiAqICAgfVxuICogfTtcbiAqXG4gKiBAbm90ZSBgZW5hYmxlSW5zZWN1cmVBdXRoYCB3aWxsIGJlIHJlbW92ZWQgaW4gZnV0dXJlIHZlcnNpb25zLiBVc2Ugc2VjdXJlIGF1dGhlbnRpY2F0aW9uIHdpdGggYGNsaWVudElkYCBhbmQgYGNsaWVudFNlY3JldGAuXG4gKiBAbm90ZSBTZWN1cmUgYXV0aGVudGljYXRpb24gZXhjaGFuZ2VzIHRoZSBgY29kZWAgcHJvdmlkZWQgYnkgdGhlIGNsaWVudCBmb3IgYW4gYWNjZXNzIHRva2VuIHVzaW5nIEdpdEh1YidzIE9BdXRoIEFQSS5cbiAqXG4gKiBAc2VlIHtAbGluayBodHRwczovL2RvY3MuZ2l0aHViLmNvbS9lbi9kZXZlbG9wZXJzL2FwcHMvYXV0aG9yaXppbmctb2F1dGgtYXBwcyBHaXRIdWIgT0F1dGggRG9jdW1lbnRhdGlvbn1cbiAqL1xuXG5pbXBvcnQgQmFzZUNvZGVBdXRoQWRhcHRlciBmcm9tICcuL0Jhc2VDb2RlQXV0aEFkYXB0ZXInO1xuY2xhc3MgR2l0SHViQWRhcHRlciBleHRlbmRzIEJhc2VDb2RlQXV0aEFkYXB0ZXIge1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcignR2l0SHViJyk7XG4gIH1cbiAgYXN5bmMgZ2V0QWNjZXNzVG9rZW5Gcm9tQ29kZShhdXRoRGF0YSkge1xuICAgIGNvbnN0IHRva2VuVXJsID0gJ2h0dHBzOi8vZ2l0aHViLmNvbS9sb2dpbi9vYXV0aC9hY2Nlc3NfdG9rZW4nO1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2godG9rZW5VcmwsIHtcbiAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgaGVhZGVyczoge1xuICAgICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgICAgICBBY2NlcHQ6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgIH0sXG4gICAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgIGNsaWVudF9pZDogdGhpcy5jbGllbnRJZCxcbiAgICAgICAgY2xpZW50X3NlY3JldDogdGhpcy5jbGllbnRTZWNyZXQsXG4gICAgICAgIGNvZGU6IGF1dGhEYXRhLmNvZGUsXG4gICAgICB9KSxcbiAgICB9KTtcblxuICAgIGlmICghcmVzcG9uc2Uub2spIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5WQUxJREFUSU9OX0VSUk9SLCBgRmFpbGVkIHRvIGV4Y2hhbmdlIGNvZGUgZm9yIHRva2VuOiAke3Jlc3BvbnNlLnN0YXR1c1RleHR9YCk7XG4gICAgfVxuXG4gICAgY29uc3QgZGF0YSA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcbiAgICBpZiAoZGF0YS5lcnJvcikge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsIGRhdGEuZXJyb3JfZGVzY3JpcHRpb24gfHwgZGF0YS5lcnJvcik7XG4gICAgfVxuXG4gICAgcmV0dXJuIGRhdGEuYWNjZXNzX3Rva2VuO1xuICB9XG5cbiAgYXN5bmMgZ2V0VXNlckZyb21BY2Nlc3NUb2tlbihhY2Nlc3NUb2tlbikge1xuICAgIGNvbnN0IHVzZXJBcGlVcmwgPSAnaHR0cHM6Ly9hcGkuZ2l0aHViLmNvbS91c2VyJztcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKHVzZXJBcGlVcmwsIHtcbiAgICAgIG1ldGhvZDogJ0dFVCcsXG4gICAgICBoZWFkZXJzOiB7XG4gICAgICAgIEF1dGhvcml6YXRpb246IGBCZWFyZXIgJHthY2Nlc3NUb2tlbn1gLFxuICAgICAgICBBY2NlcHQ6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBpZiAoIXJlc3BvbnNlLm9rKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuVkFMSURBVElPTl9FUlJPUiwgYEZhaWxlZCB0byBmZXRjaCBHaXRIdWIgdXNlcjogJHtyZXNwb25zZS5zdGF0dXNUZXh0fWApO1xuICAgIH1cblxuICAgIGNvbnN0IHVzZXJEYXRhID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuICAgIGlmICghdXNlckRhdGEuaWQgfHwgIXVzZXJEYXRhLmxvZ2luKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuVkFMSURBVElPTl9FUlJPUiwgJ0ludmFsaWQgR2l0SHViIHVzZXIgZGF0YSByZWNlaXZlZC4nKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdXNlckRhdGE7XG4gIH1cblxufVxuXG5leHBvcnQgZGVmYXVsdCBuZXcgR2l0SHVi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