parse-server 8.0.1-alpha.2 → 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 +7 -7
@@ -1,42 +1,113 @@
1
1
  "use strict";
2
2
 
3
- // Helper functions for accessing the qq Graph API.
4
- const httpsRequest = require('./httpsRequest');
5
- var Parse = require('parse/node').Parse;
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 QQ.
11
+ *
12
+ * @class QqAdapter
13
+ * @param {Object} options - The adapter configuration options.
14
+ * @param {string} options.clientId - Your QQ App ID. Required for secure authentication.
15
+ * @param {string} options.clientSecret - Your QQ App Secret. Required for secure authentication.
16
+ * @param {boolean} [options.enableInsecureAuth=false] - **[DEPRECATED]** Enable insecure authentication (not recommended).
17
+ *
18
+ * @description
19
+ * ## Parse Server Configuration
20
+ * To configure Parse Server for QQ authentication, use the following structure:
21
+ * ### Secure Configuration
22
+ * ```json
23
+ * {
24
+ * "auth": {
25
+ * "qq": {
26
+ * "clientId": "your-app-id",
27
+ * "clientSecret": "your-app-secret"
28
+ * }
29
+ * }
30
+ * }
31
+ * ```
32
+ * ### Insecure Configuration (Not Recommended)
33
+ * ```json
34
+ * {
35
+ * "auth": {
36
+ * "qq": {
37
+ * "enableInsecureAuth": true
38
+ * }
39
+ * }
40
+ * }
41
+ * ```
42
+ *
43
+ * The adapter requires the following `authData` fields:
44
+ * - **Secure Authentication**: `code`, `redirect_uri`.
45
+ * - **Insecure Authentication (Not Recommended)**: `id`, `access_token`.
46
+ *
47
+ * ## Auth Payloads
48
+ * ### Secure Authentication Payload
49
+ * ```json
50
+ * {
51
+ * "qq": {
52
+ * "code": "abcd1234",
53
+ * "redirect_uri": "https://your-redirect-uri.com/callback"
54
+ * }
55
+ * }
56
+ * ```
57
+ * ### Insecure Authentication Payload (Not Recommended)
58
+ * ```json
59
+ * {
60
+ * "qq": {
61
+ * "id": "1234567",
62
+ * "access_token": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
63
+ * }
64
+ * }
65
+ * ```
66
+ *
67
+ * ## Notes
68
+ * - Secure authentication exchanges the `code` and `redirect_uri` provided by the client for an access token using QQ's OAuth API.
69
+ * - **Insecure authentication** validates the `id` and `access_token` directly, bypassing OAuth flows. This approach is not recommended and may be deprecated in future versions.
70
+ *
71
+ * @see {@link https://wiki.connect.qq.com/ QQ Authentication Documentation}
72
+ */
6
73
 
7
- // Returns a promise that fulfills iff this user id is valid.
8
- function validateAuthData(authData) {
9
- return graphRequest('me?access_token=' + authData.access_token).then(function (data) {
10
- if (data && data.openid == authData.id) {
11
- return;
74
+ class QqAdapter extends _BaseCodeAuthAdapter.default {
75
+ constructor() {
76
+ super('qq');
77
+ }
78
+ async getUserFromAccessToken(access_token) {
79
+ const response = await fetch('https://graph.qq.com/oauth2.0/me', {
80
+ headers: {
81
+ Authorization: `Bearer ${access_token}`
82
+ }
83
+ });
84
+ if (!response.ok) {
85
+ throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'qq API request failed.');
12
86
  }
13
- throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'qq auth is invalid for this user.');
14
- });
15
- }
16
-
17
- // Returns a promise that fulfills if this app id is valid.
18
- function validateAppId() {
19
- return Promise.resolve();
20
- }
21
-
22
- // A promisey wrapper for qq graph requests.
23
- function graphRequest(path) {
24
- return httpsRequest.get('https://graph.qq.com/oauth2.0/' + path, true).then(data => {
25
- return parseResponseData(data);
26
- });
27
- }
28
- function parseResponseData(data) {
29
- const starPos = data.indexOf('(');
30
- const endPos = data.indexOf(')');
31
- if (starPos == -1 || endPos == -1) {
32
- throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'qq auth is invalid for this user.');
87
+ const data = await response.text();
88
+ return this.parseResponseData(data);
89
+ }
90
+ async getAccessTokenFromCode(authData) {
91
+ const response = await fetch('https://graph.qq.com/oauth2.0/token', {
92
+ method: 'GET',
93
+ headers: {
94
+ 'Content-Type': 'application/x-www-form-urlencoded'
95
+ },
96
+ body: new URLSearchParams({
97
+ grant_type: 'authorization_code',
98
+ client_id: this.clientId,
99
+ client_secret: this.clientSecret,
100
+ redirect_uri: authData.redirect_uri,
101
+ code: authData.code
102
+ }).toString()
103
+ });
104
+ if (!response.ok) {
105
+ throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'qq API request failed.');
106
+ }
107
+ const text = await response.text();
108
+ const data = this.parseResponseData(text);
109
+ return data.access_token;
33
110
  }
34
- data = data.substring(starPos + 1, endPos - 1);
35
- return JSON.parse(data);
36
111
  }
37
- module.exports = {
38
- validateAppId,
39
- validateAuthData,
40
- parseResponseData
41
- };
42
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJodHRwc1JlcXVlc3QiLCJyZXF1aXJlIiwiUGFyc2UiLCJ2YWxpZGF0ZUF1dGhEYXRhIiwiYXV0aERhdGEiLCJncmFwaFJlcXVlc3QiLCJhY2Nlc3NfdG9rZW4iLCJ0aGVuIiwiZGF0YSIsIm9wZW5pZCIsImlkIiwiRXJyb3IiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwidmFsaWRhdGVBcHBJZCIsIlByb21pc2UiLCJyZXNvbHZlIiwicGF0aCIsImdldCIsInBhcnNlUmVzcG9uc2VEYXRhIiwic3RhclBvcyIsImluZGV4T2YiLCJlbmRQb3MiLCJzdWJzdHJpbmciLCJKU09OIiwicGFyc2UiLCJtb2R1bGUiLCJleHBvcnRzIl0sInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL0FkYXB0ZXJzL0F1dGgvcXEuanMiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gSGVscGVyIGZ1bmN0aW9ucyBmb3IgYWNjZXNzaW5nIHRoZSBxcSBHcmFwaCBBUEkuXG5jb25zdCBodHRwc1JlcXVlc3QgPSByZXF1aXJlKCcuL2h0dHBzUmVxdWVzdCcpO1xudmFyIFBhcnNlID0gcmVxdWlyZSgncGFyc2Uvbm9kZScpLlBhcnNlO1xuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmZiB0aGlzIHVzZXIgaWQgaXMgdmFsaWQuXG5mdW5jdGlvbiB2YWxpZGF0ZUF1dGhEYXRhKGF1dGhEYXRhKSB7XG4gIHJldHVybiBncmFwaFJlcXVlc3QoJ21lP2FjY2Vzc190b2tlbj0nICsgYXV0aERhdGEuYWNjZXNzX3Rva2VuKS50aGVuKGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgaWYgKGRhdGEgJiYgZGF0YS5vcGVuaWQgPT0gYXV0aERhdGEuaWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdxcSBhdXRoIGlzIGludmFsaWQgZm9yIHRoaXMgdXNlci4nKTtcbiAgfSk7XG59XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWYgdGhpcyBhcHAgaWQgaXMgdmFsaWQuXG5mdW5jdGlvbiB2YWxpZGF0ZUFwcElkKCkge1xuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG59XG5cbi8vIEEgcHJvbWlzZXkgd3JhcHBlciBmb3IgcXEgZ3JhcGggcmVxdWVzdHMuXG5mdW5jdGlvbiBncmFwaFJlcXVlc3QocGF0aCkge1xuICByZXR1cm4gaHR0cHNSZXF1ZXN0LmdldCgnaHR0cHM6Ly9ncmFwaC5xcS5jb20vb2F1dGgyLjAvJyArIHBhdGgsIHRydWUpLnRoZW4oZGF0YSA9PiB7XG4gICAgcmV0dXJuIHBhcnNlUmVzcG9uc2VEYXRhKGRhdGEpO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gcGFyc2VSZXNwb25zZURhdGEoZGF0YSkge1xuICBjb25zdCBzdGFyUG9zID0gZGF0YS5pbmRleE9mKCcoJyk7XG4gIGNvbnN0IGVuZFBvcyA9IGRhdGEuaW5kZXhPZignKScpO1xuICBpZiAoc3RhclBvcyA9PSAtMSB8fCBlbmRQb3MgPT0gLTEpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ3FxIGF1dGggaXMgaW52YWxpZCBmb3IgdGhpcyB1c2VyLicpO1xuICB9XG4gIGRhdGEgPSBkYXRhLnN1YnN0cmluZyhzdGFyUG9zICsgMSwgZW5kUG9zIC0gMSk7XG4gIHJldHVybiBKU09OLnBhcnNlKGRhdGEpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgdmFsaWRhdGVBcHBJZCxcbiAgdmFsaWRhdGVBdXRoRGF0YSxcbiAgcGFyc2VSZXNwb25zZURhdGEsXG59O1xuIl0sIm1hcHBpbmdzIjoiOztBQUFBO0FBQ0EsTUFBTUEsWUFBWSxHQUFHQyxPQUFPLENBQUMsZ0JBQWdCLENBQUM7QUFDOUMsSUFBSUMsS0FBSyxHQUFHRCxPQUFPLENBQUMsWUFBWSxDQUFDLENBQUNDLEtBQUs7O0FBRXZDO0FBQ0EsU0FBU0MsZ0JBQWdCQSxDQUFDQyxRQUFRLEVBQUU7RUFDbEMsT0FBT0MsWUFBWSxDQUFDLGtCQUFrQixHQUFHRCxRQUFRLENBQUNFLFlBQVksQ0FBQyxDQUFDQyxJQUFJLENBQUMsVUFBVUMsSUFBSSxFQUFFO0lBQ25GLElBQUlBLElBQUksSUFBSUEsSUFBSSxDQUFDQyxNQUFNLElBQUlMLFFBQVEsQ0FBQ00sRUFBRSxFQUFFO01BQ3RDO0lBQ0Y7SUFDQSxNQUFNLElBQUlSLEtBQUssQ0FBQ1MsS0FBSyxDQUFDVCxLQUFLLENBQUNTLEtBQUssQ0FBQ0MsZ0JBQWdCLEVBQUUsbUNBQW1DLENBQUM7RUFDMUYsQ0FBQyxDQUFDO0FBQ0o7O0FBRUE7QUFDQSxTQUFTQyxhQUFhQSxDQUFBLEVBQUc7RUFDdkIsT0FBT0MsT0FBTyxDQUFDQyxPQUFPLENBQUMsQ0FBQztBQUMxQjs7QUFFQTtBQUNBLFNBQVNWLFlBQVlBLENBQUNXLElBQUksRUFBRTtFQUMxQixPQUFPaEIsWUFBWSxDQUFDaUIsR0FBRyxDQUFDLGdDQUFnQyxHQUFHRCxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUNULElBQUksQ0FBQ0MsSUFBSSxJQUFJO0lBQ2xGLE9BQU9VLGlCQUFpQixDQUFDVixJQUFJLENBQUM7RUFDaEMsQ0FBQyxDQUFDO0FBQ0o7QUFFQSxTQUFTVSxpQkFBaUJBLENBQUNWLElBQUksRUFBRTtFQUMvQixNQUFNVyxPQUFPLEdBQUdYLElBQUksQ0FBQ1ksT0FBTyxDQUFDLEdBQUcsQ0FBQztFQUNqQyxNQUFNQyxNQUFNLEdBQUdiLElBQUksQ0FBQ1ksT0FBTyxDQUFDLEdBQUcsQ0FBQztFQUNoQyxJQUFJRCxPQUFPLElBQUksQ0FBQyxDQUFDLElBQUlFLE1BQU0sSUFBSSxDQUFDLENBQUMsRUFBRTtJQUNqQyxNQUFNLElBQUluQixLQUFLLENBQUNTLEtBQUssQ0FBQ1QsS0FBSyxDQUFDUyxLQUFLLENBQUNDLGdCQUFnQixFQUFFLG1DQUFtQyxDQUFDO0VBQzFGO0VBQ0FKLElBQUksR0FBR0EsSUFBSSxDQUFDYyxTQUFTLENBQUNILE9BQU8sR0FBRyxDQUFDLEVBQUVFLE1BQU0sR0FBRyxDQUFDLENBQUM7RUFDOUMsT0FBT0UsSUFBSSxDQUFDQyxLQUFLLENBQUNoQixJQUFJLENBQUM7QUFDekI7QUFFQWlCLE1BQU0sQ0FBQ0MsT0FBTyxHQUFHO0VBQ2ZiLGFBQWE7RUFDYlYsZ0JBQWdCO0VBQ2hCZTtBQUNGLENBQUMiLCJpZ25vcmVMaXN0IjpbXX0=
112
+ var _default = exports.default = new QqAdapter();
113
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfQmFzZUNvZGVBdXRoQWRhcHRlciIsIl9pbnRlcm9wUmVxdWlyZURlZmF1bHQiLCJyZXF1aXJlIiwiZSIsIl9fZXNNb2R1bGUiLCJkZWZhdWx0IiwiUXFBZGFwdGVyIiwiQmFzZUF1dGhDb2RlQWRhcHRlciIsImNvbnN0cnVjdG9yIiwiZ2V0VXNlckZyb21BY2Nlc3NUb2tlbiIsImFjY2Vzc190b2tlbiIsInJlc3BvbnNlIiwiZmV0Y2giLCJoZWFkZXJzIiwiQXV0aG9yaXphdGlvbiIsIm9rIiwiUGFyc2UiLCJFcnJvciIsIk9CSkVDVF9OT1RfRk9VTkQiLCJkYXRhIiwidGV4dCIsInBhcnNlUmVzcG9uc2VEYXRhIiwiZ2V0QWNjZXNzVG9rZW5Gcm9tQ29kZSIsImF1dGhEYXRhIiwibWV0aG9kIiwiYm9keSIsIlVSTFNlYXJjaFBhcmFtcyIsImdyYW50X3R5cGUiLCJjbGllbnRfaWQiLCJjbGllbnRJZCIsImNsaWVudF9zZWNyZXQiLCJjbGllbnRTZWNyZXQiLCJyZWRpcmVjdF91cmkiLCJjb2RlIiwidG9TdHJpbmciLCJfZGVmYXVsdCIsImV4cG9ydHMiXSwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvQWRhcHRlcnMvQXV0aC9xcS5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFBhcnNlIFNlcnZlciBhdXRoZW50aWNhdGlvbiBhZGFwdGVyIGZvciBRUS5cbiAqXG4gKiBAY2xhc3MgUXFBZGFwdGVyXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyAtIFRoZSBhZGFwdGVyIGNvbmZpZ3VyYXRpb24gb3B0aW9ucy5cbiAqIEBwYXJhbSB7c3RyaW5nfSBvcHRpb25zLmNsaWVudElkIC0gWW91ciBRUSBBcHAgSUQuIFJlcXVpcmVkIGZvciBzZWN1cmUgYXV0aGVudGljYXRpb24uXG4gKiBAcGFyYW0ge3N0cmluZ30gb3B0aW9ucy5jbGllbnRTZWNyZXQgLSBZb3VyIFFRIEFwcCBTZWNyZXQuIFJlcXVpcmVkIGZvciBzZWN1cmUgYXV0aGVudGljYXRpb24uXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLmVuYWJsZUluc2VjdXJlQXV0aD1mYWxzZV0gLSAqKltERVBSRUNBVEVEXSoqIEVuYWJsZSBpbnNlY3VyZSBhdXRoZW50aWNhdGlvbiAobm90IHJlY29tbWVuZGVkKS5cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqICMjIFBhcnNlIFNlcnZlciBDb25maWd1cmF0aW9uXG4gKiBUbyBjb25maWd1cmUgUGFyc2UgU2VydmVyIGZvciBRUSBhdXRoZW50aWNhdGlvbiwgdXNlIHRoZSBmb2xsb3dpbmcgc3RydWN0dXJlOlxuICogIyMjIFNlY3VyZSBDb25maWd1cmF0aW9uXG4gKiBgYGBqc29uXG4gKiB7XG4gKiAgIFwiYXV0aFwiOiB7XG4gKiAgICAgXCJxcVwiOiB7XG4gKiAgICAgICBcImNsaWVudElkXCI6IFwieW91ci1hcHAtaWRcIixcbiAqICAgICAgIFwiY2xpZW50U2VjcmV0XCI6IFwieW91ci1hcHAtc2VjcmV0XCJcbiAqICAgICB9XG4gKiAgIH1cbiAqIH1cbiAqIGBgYFxuICogIyMjIEluc2VjdXJlIENvbmZpZ3VyYXRpb24gKE5vdCBSZWNvbW1lbmRlZClcbiAqIGBgYGpzb25cbiAqIHtcbiAqICAgXCJhdXRoXCI6IHtcbiAqICAgICBcInFxXCI6IHtcbiAqICAgICAgIFwiZW5hYmxlSW5zZWN1cmVBdXRoXCI6IHRydWVcbiAqICAgICB9XG4gKiAgIH1cbiAqIH1cbiAqIGBgYFxuICpcbiAqIFRoZSBhZGFwdGVyIHJlcXVpcmVzIHRoZSBmb2xsb3dpbmcgYGF1dGhEYXRhYCBmaWVsZHM6XG4gKiAtICoqU2VjdXJlIEF1dGhlbnRpY2F0aW9uKio6IGBjb2RlYCwgYHJlZGlyZWN0X3VyaWAuXG4gKiAtICoqSW5zZWN1cmUgQXV0aGVudGljYXRpb24gKE5vdCBSZWNvbW1lbmRlZCkqKjogYGlkYCwgYGFjY2Vzc190b2tlbmAuXG4gKlxuICogIyMgQXV0aCBQYXlsb2Fkc1xuICogIyMjIFNlY3VyZSBBdXRoZW50aWNhdGlvbiBQYXlsb2FkXG4gKiBgYGBqc29uXG4gKiB7XG4gKiAgIFwicXFcIjoge1xuICogICAgIFwiY29kZVwiOiBcImFiY2QxMjM0XCIsXG4gKiAgICAgXCJyZWRpcmVjdF91cmlcIjogXCJodHRwczovL3lvdXItcmVkaXJlY3QtdXJpLmNvbS9jYWxsYmFja1wiXG4gKiAgIH1cbiAqIH1cbiAqIGBgYFxuICogIyMjIEluc2VjdXJlIEF1dGhlbnRpY2F0aW9uIFBheWxvYWQgKE5vdCBSZWNvbW1lbmRlZClcbiAqIGBgYGpzb25cbiAqIHtcbiAqICAgXCJxcVwiOiB7XG4gKiAgICAgXCJpZFwiOiBcIjEyMzQ1NjdcIixcbiAqICAgICBcImFjY2Vzc190b2tlblwiOiBcInh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4XCJcbiAqICAgfVxuICogfVxuICogYGBgXG4gKlxuICogIyMgTm90ZXNcbiAqIC0gU2VjdXJlIGF1dGhlbnRpY2F0aW9uIGV4Y2hhbmdlcyB0aGUgYGNvZGVgIGFuZCBgcmVkaXJlY3RfdXJpYCBwcm92aWRlZCBieSB0aGUgY2xpZW50IGZvciBhbiBhY2Nlc3MgdG9rZW4gdXNpbmcgUVEncyBPQXV0aCBBUEkuXG4gKiAtICoqSW5zZWN1cmUgYXV0aGVudGljYXRpb24qKiB2YWxpZGF0ZXMgdGhlIGBpZGAgYW5kIGBhY2Nlc3NfdG9rZW5gIGRpcmVjdGx5LCBieXBhc3NpbmcgT0F1dGggZmxvd3MuIFRoaXMgYXBwcm9hY2ggaXMgbm90IHJlY29tbWVuZGVkIGFuZCBtYXkgYmUgZGVwcmVjYXRlZCBpbiBmdXR1cmUgdmVyc2lvbnMuXG4gKlxuICogQHNlZSB7QGxpbmsgaHR0cHM6Ly93aWtpLmNvbm5lY3QucXEuY29tLyBRUSBBdXRoZW50aWNhdGlvbiBEb2N1bWVudGF0aW9ufVxuICovXG5cbmltcG9ydCBCYXNlQXV0aENvZGVBZGFwdGVyIGZyb20gJy4vQmFzZUNvZGVBdXRoQWRhcHRlcic7XG5jbGFzcyBRcUFkYXB0ZXIgZXh0ZW5kcyBCYXNlQXV0aENvZGVBZGFwdGVyIHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoJ3FxJyk7XG4gIH1cblxuICBhc3luYyBnZXRVc2VyRnJvbUFjY2Vzc1Rva2VuKGFjY2Vzc190b2tlbikge1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goJ2h0dHBzOi8vZ3JhcGgucXEuY29tL29hdXRoMi4wL21lJywge1xuICAgICAgaGVhZGVyczoge1xuICAgICAgICBBdXRob3JpemF0aW9uOiBgQmVhcmVyICR7YWNjZXNzX3Rva2VufWAsXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgaWYgKCFyZXNwb25zZS5vaykge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdxcSBBUEkgcmVxdWVzdCBmYWlsZWQuJyk7XG4gICAgfVxuXG4gICAgY29uc3QgZGF0YSA9IGF3YWl0IHJlc3BvbnNlLnRleHQoKTtcbiAgICByZXR1cm4gdGhpcy5wYXJzZVJlc3BvbnNlRGF0YShkYXRhKTtcbiAgfVxuXG4gIGFzeW5jIGdldEFjY2Vzc1Rva2VuRnJvbUNvZGUoYXV0aERhdGEpIHtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKCdodHRwczovL2dyYXBoLnFxLmNvbS9vYXV0aDIuMC90b2tlbicsIHtcbiAgICAgIG1ldGhvZDogJ0dFVCcsXG4gICAgICBoZWFkZXJzOiB7XG4gICAgICAgICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJyxcbiAgICAgIH0sXG4gICAgICBib2R5OiBuZXcgVVJMU2VhcmNoUGFyYW1zKHtcbiAgICAgICAgZ3JhbnRfdHlwZTogJ2F1dGhvcml6YXRpb25fY29kZScsXG4gICAgICAgIGNsaWVudF9pZDogdGhpcy5jbGllbnRJZCxcbiAgICAgICAgY2xpZW50X3NlY3JldDogdGhpcy5jbGllbnRTZWNyZXQsXG4gICAgICAgIHJlZGlyZWN0X3VyaTogYXV0aERhdGEucmVkaXJlY3RfdXJpLFxuICAgICAgICBjb2RlOiBhdXRoRGF0YS5jb2RlLFxuICAgICAgfSkudG9TdHJpbmcoKSxcbiAgICB9KTtcblxuICAgIGlmICghcmVzcG9uc2Uub2spIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAncXEgQVBJIHJlcXVlc3QgZmFpbGVkLicpO1xuICAgIH1cblxuICAgIGNvbnN0IHRleHQgPSBhd2FpdCByZXNwb25zZS50ZXh0KCk7XG4gICAgY29uc3QgZGF0YSA9IHRoaXMucGFyc2VSZXNwb25zZURhdGEodGV4dCk7XG4gICAgcmV0dXJuIGRhdGEuYWNjZXNzX3Rva2VuO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IG5ldyBRcUFkYXB0ZXIoKTtcbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBaUVBLElBQUFBLG9CQUFBLEdBQUFDLHNCQUFBLENBQUFDLE9BQUE7QUFBd0QsU0FBQUQsdUJBQUFFLENBQUEsV0FBQUEsQ0FBQSxJQUFBQSxDQUFBLENBQUFDLFVBQUEsR0FBQUQsQ0FBQSxLQUFBRSxPQUFBLEVBQUFGLENBQUE7QUFqRXhEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUdBLE1BQU1HLFNBQVMsU0FBU0MsNEJBQW1CLENBQUM7RUFDMUNDLFdBQVdBLENBQUEsRUFBRztJQUNaLEtBQUssQ0FBQyxJQUFJLENBQUM7RUFDYjtFQUVBLE1BQU1DLHNCQUFzQkEsQ0FBQ0MsWUFBWSxFQUFFO0lBQ3pDLE1BQU1DLFFBQVEsR0FBRyxNQUFNQyxLQUFLLENBQUMsa0NBQWtDLEVBQUU7TUFDL0RDLE9BQU8sRUFBRTtRQUNQQyxhQUFhLEVBQUUsVUFBVUosWUFBWTtNQUN2QztJQUNGLENBQUMsQ0FBQztJQUVGLElBQUksQ0FBQ0MsUUFBUSxDQUFDSSxFQUFFLEVBQUU7TUFDaEIsTUFBTSxJQUFJQyxLQUFLLENBQUNDLEtBQUssQ0FBQ0QsS0FBSyxDQUFDQyxLQUFLLENBQUNDLGdCQUFnQixFQUFFLHdCQUF3QixDQUFDO0lBQy9FO0lBRUEsTUFBTUMsSUFBSSxHQUFHLE1BQU1SLFFBQVEsQ0FBQ1MsSUFBSSxDQUFDLENBQUM7SUFDbEMsT0FBTyxJQUFJLENBQUNDLGlCQUFpQixDQUFDRixJQUFJLENBQUM7RUFDckM7RUFFQSxNQUFNRyxzQkFBc0JBLENBQUNDLFFBQVEsRUFBRTtJQUNyQyxNQUFNWixRQUFRLEdBQUcsTUFBTUMsS0FBSyxDQUFDLHFDQUFxQyxFQUFFO01BQ2xFWSxNQUFNLEVBQUUsS0FBSztNQUNiWCxPQUFPLEVBQUU7UUFDUCxjQUFjLEVBQUU7TUFDbEIsQ0FBQztNQUNEWSxJQUFJLEVBQUUsSUFBSUMsZUFBZSxDQUFDO1FBQ3hCQyxVQUFVLEVBQUUsb0JBQW9CO1FBQ2hDQyxTQUFTLEVBQUUsSUFBSSxDQUFDQyxRQUFRO1FBQ3hCQyxhQUFhLEVBQUUsSUFBSSxDQUFDQyxZQUFZO1FBQ2hDQyxZQUFZLEVBQUVULFFBQVEsQ0FBQ1MsWUFBWTtRQUNuQ0MsSUFBSSxFQUFFVixRQUFRLENBQUNVO01BQ2pCLENBQUMsQ0FBQyxDQUFDQyxRQUFRLENBQUM7SUFDZCxDQUFDLENBQUM7SUFFRixJQUFJLENBQUN2QixRQUFRLENBQUNJLEVBQUUsRUFBRTtNQUNoQixNQUFNLElBQUlDLEtBQUssQ0FBQ0MsS0FBSyxDQUFDRCxLQUFLLENBQUNDLEtBQUssQ0FBQ0MsZ0JBQWdCLEVBQUUsd0JBQXdCLENBQUM7SUFDL0U7SUFFQSxNQUFNRSxJQUFJLEdBQUcsTUFBTVQsUUFBUSxDQUFDUyxJQUFJLENBQUMsQ0FBQztJQUNsQyxNQUFNRCxJQUFJLEdBQUcsSUFBSSxDQUFDRSxpQkFBaUIsQ0FBQ0QsSUFBSSxDQUFDO0lBQ3pDLE9BQU9ELElBQUksQ0FBQ1QsWUFBWTtFQUMxQjtBQUNGO0FBQUMsSUFBQXlCLFFBQUEsR0FBQUMsT0FBQSxDQUFBL0IsT0FBQSxHQUVjLElBQUlDLFNBQVMsQ0FBQyxDQUFDIiwiaWdub3JlTGlzdCI6W119
@@ -1,46 +1,115 @@
1
1
  "use strict";
2
2
 
3
- // Helper functions for accessing the Spotify API.
4
- const httpsRequest = require('./httpsRequest');
5
- var Parse = require('parse/node').Parse;
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 Spotify.
11
+ *
12
+ * @class SpotifyAdapter
13
+ * @param {Object} options - The adapter configuration options.
14
+ * @param {string} options.clientId - Your Spotify application's Client ID. Required for secure authentication.
15
+ * @param {boolean} [options.enableInsecureAuth=false] - **[DEPRECATED]** Enable insecure authentication (not recommended).
16
+ *
17
+ * @description
18
+ * ## Parse Server Configuration
19
+ * To configure Parse Server for Spotify authentication, use the following structure:
20
+ * ### Secure Configuration
21
+ * ```json
22
+ * {
23
+ * "auth": {
24
+ * "spotify": {
25
+ * "clientId": "your-client-id"
26
+ * }
27
+ * }
28
+ * }
29
+ * ```
30
+ * ### Insecure Configuration (Not Recommended)
31
+ * ```json
32
+ * {
33
+ * "auth": {
34
+ * "spotify": {
35
+ * "enableInsecureAuth": true
36
+ * }
37
+ * }
38
+ * }
39
+ * ```
40
+ *
41
+ * The adapter requires the following `authData` fields:
42
+ * - **Secure Authentication**: `code`, `redirect_uri`, and `code_verifier`.
43
+ * - **Insecure Authentication (Not Recommended)**: `id`, `access_token`.
44
+ *
45
+ * ## Auth Payloads
46
+ * ### Secure Authentication Payload
47
+ * ```json
48
+ * {
49
+ * "spotify": {
50
+ * "code": "abc123def456ghi789",
51
+ * "redirect_uri": "https://example.com/callback",
52
+ * "code_verifier": "secure-code-verifier"
53
+ * }
54
+ * }
55
+ * ```
56
+ * ### Insecure Authentication Payload (Not Recommended)
57
+ * ```json
58
+ * {
59
+ * "spotify": {
60
+ * "id": "1234567",
61
+ * "access_token": "abc123def456ghi789"
62
+ * }
63
+ * }
64
+ * ```
65
+ *
66
+ * ## Notes
67
+ * - `enableInsecureAuth` is **not recommended** and bypasses secure flows by validating the user ID and access token directly. This method is not suitable for production environments and may be removed in future versions.
68
+ * - Secure authentication exchanges the `code` provided by the client for an access token using Spotify's OAuth API. This method ensures greater security and is the recommended approach.
69
+ *
70
+ * @see {@link https://developer.spotify.com/documentation/web-api/tutorials/getting-started Spotify OAuth Documentation}
71
+ */
6
72
 
7
- // Returns a promise that fulfills iff this user id is valid.
8
- function validateAuthData(authData) {
9
- return request('me', authData.access_token).then(data => {
10
- if (data && data.id == authData.id) {
11
- return;
12
- }
13
- throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Spotify auth is invalid for this user.');
14
- });
15
- }
16
-
17
- // Returns a promise that fulfills if this app id is valid.
18
- async function validateAppId(appIds, authData) {
19
- const access_token = authData.access_token;
20
- if (!Array.isArray(appIds)) {
21
- throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'appIds must be an array.');
73
+ class SpotifyAdapter extends _BaseCodeAuthAdapter.default {
74
+ constructor() {
75
+ super('spotify');
22
76
  }
23
- if (!appIds.length) {
24
- throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Spotify auth is not configured.');
25
- }
26
- const data = await request('me', access_token);
27
- if (!data || !appIds.includes(data.id)) {
28
- throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Spotify auth is invalid for this user.');
77
+ async getUserFromAccessToken(access_token) {
78
+ const response = await fetch('https://api.spotify.com/v1/me', {
79
+ headers: {
80
+ Authorization: 'Bearer ' + access_token
81
+ }
82
+ });
83
+ if (!response.ok) {
84
+ throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Spotify API request failed.');
85
+ }
86
+ const user = await response.json();
87
+ return {
88
+ id: user.id
89
+ };
29
90
  }
30
- }
31
-
32
- // A promisey wrapper for Spotify API requests.
33
- function request(path, access_token) {
34
- return httpsRequest.get({
35
- host: 'api.spotify.com',
36
- path: '/v1/' + path,
37
- headers: {
38
- Authorization: 'Bearer ' + access_token
91
+ async getAccessTokenFromCode(authData) {
92
+ if (!authData.code || !authData.redirect_uri || !authData.code_verifier) {
93
+ throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Spotify auth configuration authData.code and/or authData.redirect_uri and/or authData.code_verifier.');
39
94
  }
40
- });
95
+ const response = await fetch('https://accounts.spotify.com/api/token', {
96
+ method: 'POST',
97
+ headers: {
98
+ 'Content-Type': 'application/x-www-form-urlencoded'
99
+ },
100
+ body: new URLSearchParams({
101
+ grant_type: 'authorization_code',
102
+ code: authData.code,
103
+ redirect_uri: authData.redirect_uri,
104
+ code_verifier: authData.code_verifier,
105
+ client_id: this.clientId
106
+ })
107
+ });
108
+ if (!response.ok) {
109
+ throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Spotify API request failed.');
110
+ }
111
+ return response.json();
112
+ }
41
113
  }
42
- module.exports = {
43
- validateAppId: validateAppId,
44
- validateAuthData: validateAuthData
45
- };
46
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJodHRwc1JlcXVlc3QiLCJyZXF1aXJlIiwiUGFyc2UiLCJ2YWxpZGF0ZUF1dGhEYXRhIiwiYXV0aERhdGEiLCJyZXF1ZXN0IiwiYWNjZXNzX3Rva2VuIiwidGhlbiIsImRhdGEiLCJpZCIsIkVycm9yIiwiT0JKRUNUX05PVF9GT1VORCIsInZhbGlkYXRlQXBwSWQiLCJhcHBJZHMiLCJBcnJheSIsImlzQXJyYXkiLCJsZW5ndGgiLCJpbmNsdWRlcyIsInBhdGgiLCJnZXQiLCJob3N0IiwiaGVhZGVycyIsIkF1dGhvcml6YXRpb24iLCJtb2R1bGUiLCJleHBvcnRzIl0sInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL0FkYXB0ZXJzL0F1dGgvc3BvdGlmeS5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBIZWxwZXIgZnVuY3Rpb25zIGZvciBhY2Nlc3NpbmcgdGhlIFNwb3RpZnkgQVBJLlxuY29uc3QgaHR0cHNSZXF1ZXN0ID0gcmVxdWlyZSgnLi9odHRwc1JlcXVlc3QnKTtcbnZhciBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKS5QYXJzZTtcblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBmdWxmaWxscyBpZmYgdGhpcyB1c2VyIGlkIGlzIHZhbGlkLlxuZnVuY3Rpb24gdmFsaWRhdGVBdXRoRGF0YShhdXRoRGF0YSkge1xuICByZXR1cm4gcmVxdWVzdCgnbWUnLCBhdXRoRGF0YS5hY2Nlc3NfdG9rZW4pLnRoZW4oZGF0YSA9PiB7XG4gICAgaWYgKGRhdGEgJiYgZGF0YS5pZCA9PSBhdXRoRGF0YS5pZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ1Nwb3RpZnkgYXV0aCBpcyBpbnZhbGlkIGZvciB0aGlzIHVzZXIuJyk7XG4gIH0pO1xufVxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmIHRoaXMgYXBwIGlkIGlzIHZhbGlkLlxuYXN5bmMgZnVuY3Rpb24gdmFsaWRhdGVBcHBJZChhcHBJZHMsIGF1dGhEYXRhKSB7XG4gIGNvbnN0IGFjY2Vzc190b2tlbiA9IGF1dGhEYXRhLmFjY2Vzc190b2tlbjtcbiAgaWYgKCFBcnJheS5pc0FycmF5KGFwcElkcykpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ2FwcElkcyBtdXN0IGJlIGFuIGFycmF5LicpO1xuICB9XG4gIGlmICghYXBwSWRzLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAnU3BvdGlmeSBhdXRoIGlzIG5vdCBjb25maWd1cmVkLicpO1xuICB9XG4gIGNvbnN0IGRhdGEgPSBhd2FpdCByZXF1ZXN0KCdtZScsIGFjY2Vzc190b2tlbik7XG4gIGlmICghZGF0YSB8fCAhYXBwSWRzLmluY2x1ZGVzKGRhdGEuaWQpKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdTcG90aWZ5IGF1dGggaXMgaW52YWxpZCBmb3IgdGhpcyB1c2VyLicpO1xuICB9XG59XG5cbi8vIEEgcHJvbWlzZXkgd3JhcHBlciBmb3IgU3BvdGlmeSBBUEkgcmVxdWVzdHMuXG5mdW5jdGlvbiByZXF1ZXN0KHBhdGgsIGFjY2Vzc190b2tlbikge1xuICByZXR1cm4gaHR0cHNSZXF1ZXN0LmdldCh7XG4gICAgaG9zdDogJ2FwaS5zcG90aWZ5LmNvbScsXG4gICAgcGF0aDogJy92MS8nICsgcGF0aCxcbiAgICBoZWFkZXJzOiB7XG4gICAgICBBdXRob3JpemF0aW9uOiAnQmVhcmVyICcgKyBhY2Nlc3NfdG9rZW4sXG4gICAgfSxcbiAgfSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICB2YWxpZGF0ZUFwcElkOiB2YWxpZGF0ZUFwcElkLFxuICB2YWxpZGF0ZUF1dGhEYXRhOiB2YWxpZGF0ZUF1dGhEYXRhLFxufTtcbiJdLCJtYXBwaW5ncyI6Ijs7QUFBQTtBQUNBLE1BQU1BLFlBQVksR0FBR0MsT0FBTyxDQUFDLGdCQUFnQixDQUFDO0FBQzlDLElBQUlDLEtBQUssR0FBR0QsT0FBTyxDQUFDLFlBQVksQ0FBQyxDQUFDQyxLQUFLOztBQUV2QztBQUNBLFNBQVNDLGdCQUFnQkEsQ0FBQ0MsUUFBUSxFQUFFO0VBQ2xDLE9BQU9DLE9BQU8sQ0FBQyxJQUFJLEVBQUVELFFBQVEsQ0FBQ0UsWUFBWSxDQUFDLENBQUNDLElBQUksQ0FBQ0MsSUFBSSxJQUFJO0lBQ3ZELElBQUlBLElBQUksSUFBSUEsSUFBSSxDQUFDQyxFQUFFLElBQUlMLFFBQVEsQ0FBQ0ssRUFBRSxFQUFFO01BQ2xDO0lBQ0Y7SUFDQSxNQUFNLElBQUlQLEtBQUssQ0FBQ1EsS0FBSyxDQUFDUixLQUFLLENBQUNRLEtBQUssQ0FBQ0MsZ0JBQWdCLEVBQUUsd0NBQXdDLENBQUM7RUFDL0YsQ0FBQyxDQUFDO0FBQ0o7O0FBRUE7QUFDQSxlQUFlQyxhQUFhQSxDQUFDQyxNQUFNLEVBQUVULFFBQVEsRUFBRTtFQUM3QyxNQUFNRSxZQUFZLEdBQUdGLFFBQVEsQ0FBQ0UsWUFBWTtFQUMxQyxJQUFJLENBQUNRLEtBQUssQ0FBQ0MsT0FBTyxDQUFDRixNQUFNLENBQUMsRUFBRTtJQUMxQixNQUFNLElBQUlYLEtBQUssQ0FBQ1EsS0FBSyxDQUFDUixLQUFLLENBQUNRLEtBQUssQ0FBQ0MsZ0JBQWdCLEVBQUUsMEJBQTBCLENBQUM7RUFDakY7RUFDQSxJQUFJLENBQUNFLE1BQU0sQ0FBQ0csTUFBTSxFQUFFO0lBQ2xCLE1BQU0sSUFBSWQsS0FBSyxDQUFDUSxLQUFLLENBQUNSLEtBQUssQ0FBQ1EsS0FBSyxDQUFDQyxnQkFBZ0IsRUFBRSxpQ0FBaUMsQ0FBQztFQUN4RjtFQUNBLE1BQU1ILElBQUksR0FBRyxNQUFNSCxPQUFPLENBQUMsSUFBSSxFQUFFQyxZQUFZLENBQUM7RUFDOUMsSUFBSSxDQUFDRSxJQUFJLElBQUksQ0FBQ0ssTUFBTSxDQUFDSSxRQUFRLENBQUNULElBQUksQ0FBQ0MsRUFBRSxDQUFDLEVBQUU7SUFDdEMsTUFBTSxJQUFJUCxLQUFLLENBQUNRLEtBQUssQ0FBQ1IsS0FBSyxDQUFDUSxLQUFLLENBQUNDLGdCQUFnQixFQUFFLHdDQUF3QyxDQUFDO0VBQy9GO0FBQ0Y7O0FBRUE7QUFDQSxTQUFTTixPQUFPQSxDQUFDYSxJQUFJLEVBQUVaLFlBQVksRUFBRTtFQUNuQyxPQUFPTixZQUFZLENBQUNtQixHQUFHLENBQUM7SUFDdEJDLElBQUksRUFBRSxpQkFBaUI7SUFDdkJGLElBQUksRUFBRSxNQUFNLEdBQUdBLElBQUk7SUFDbkJHLE9BQU8sRUFBRTtNQUNQQyxhQUFhLEVBQUUsU0FBUyxHQUFHaEI7SUFDN0I7RUFDRixDQUFDLENBQUM7QUFDSjtBQUVBaUIsTUFBTSxDQUFDQyxPQUFPLEdBQUc7RUFDZlosYUFBYSxFQUFFQSxhQUFhO0VBQzVCVCxnQkFBZ0IsRUFBRUE7QUFDcEIsQ0FBQyIsImlnbm9yZUxpc3QiOltdfQ==
114
+ var _default = exports.default = new SpotifyAdapter();
115
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfQmFzZUNvZGVBdXRoQWRhcHRlciIsIl9pbnRlcm9wUmVxdWlyZURlZmF1bHQiLCJyZXF1aXJlIiwiZSIsIl9fZXNNb2R1bGUiLCJkZWZhdWx0IiwiU3BvdGlmeUFkYXB0ZXIiLCJCYXNlQXV0aENvZGVBZGFwdGVyIiwiY29uc3RydWN0b3IiLCJnZXRVc2VyRnJvbUFjY2Vzc1Rva2VuIiwiYWNjZXNzX3Rva2VuIiwicmVzcG9uc2UiLCJmZXRjaCIsImhlYWRlcnMiLCJBdXRob3JpemF0aW9uIiwib2siLCJQYXJzZSIsIkVycm9yIiwiT0JKRUNUX05PVF9GT1VORCIsInVzZXIiLCJqc29uIiwiaWQiLCJnZXRBY2Nlc3NUb2tlbkZyb21Db2RlIiwiYXV0aERhdGEiLCJjb2RlIiwicmVkaXJlY3RfdXJpIiwiY29kZV92ZXJpZmllciIsIm1ldGhvZCIsImJvZHkiLCJVUkxTZWFyY2hQYXJhbXMiLCJncmFudF90eXBlIiwiY2xpZW50X2lkIiwiY2xpZW50SWQiLCJfZGVmYXVsdCIsImV4cG9ydHMiXSwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvQWRhcHRlcnMvQXV0aC9zcG90aWZ5LmpzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogUGFyc2UgU2VydmVyIGF1dGhlbnRpY2F0aW9uIGFkYXB0ZXIgZm9yIFNwb3RpZnkuXG4gKlxuICogQGNsYXNzIFNwb3RpZnlBZGFwdGVyXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyAtIFRoZSBhZGFwdGVyIGNvbmZpZ3VyYXRpb24gb3B0aW9ucy5cbiAqIEBwYXJhbSB7c3RyaW5nfSBvcHRpb25zLmNsaWVudElkIC0gWW91ciBTcG90aWZ5IGFwcGxpY2F0aW9uJ3MgQ2xpZW50IElELiBSZXF1aXJlZCBmb3Igc2VjdXJlIGF1dGhlbnRpY2F0aW9uLlxuICogQHBhcmFtIHtib29sZWFufSBbb3B0aW9ucy5lbmFibGVJbnNlY3VyZUF1dGg9ZmFsc2VdIC0gKipbREVQUkVDQVRFRF0qKiBFbmFibGUgaW5zZWN1cmUgYXV0aGVudGljYXRpb24gKG5vdCByZWNvbW1lbmRlZCkuXG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiAjIyBQYXJzZSBTZXJ2ZXIgQ29uZmlndXJhdGlvblxuICogVG8gY29uZmlndXJlIFBhcnNlIFNlcnZlciBmb3IgU3BvdGlmeSBhdXRoZW50aWNhdGlvbiwgdXNlIHRoZSBmb2xsb3dpbmcgc3RydWN0dXJlOlxuICogIyMjIFNlY3VyZSBDb25maWd1cmF0aW9uXG4gKiBgYGBqc29uXG4gKiB7XG4gKiAgIFwiYXV0aFwiOiB7XG4gKiAgICAgXCJzcG90aWZ5XCI6IHtcbiAqICAgICAgIFwiY2xpZW50SWRcIjogXCJ5b3VyLWNsaWVudC1pZFwiXG4gKiAgICAgfVxuICogICB9XG4gKiB9XG4gKiBgYGBcbiAqICMjIyBJbnNlY3VyZSBDb25maWd1cmF0aW9uIChOb3QgUmVjb21tZW5kZWQpXG4gKiBgYGBqc29uXG4gKiB7XG4gKiAgIFwiYXV0aFwiOiB7XG4gKiAgICAgXCJzcG90aWZ5XCI6IHtcbiAqICAgICAgIFwiZW5hYmxlSW5zZWN1cmVBdXRoXCI6IHRydWVcbiAqICAgICB9XG4gKiAgIH1cbiAqIH1cbiAqIGBgYFxuICpcbiAqIFRoZSBhZGFwdGVyIHJlcXVpcmVzIHRoZSBmb2xsb3dpbmcgYGF1dGhEYXRhYCBmaWVsZHM6XG4gKiAtICoqU2VjdXJlIEF1dGhlbnRpY2F0aW9uKio6IGBjb2RlYCwgYHJlZGlyZWN0X3VyaWAsIGFuZCBgY29kZV92ZXJpZmllcmAuXG4gKiAtICoqSW5zZWN1cmUgQXV0aGVudGljYXRpb24gKE5vdCBSZWNvbW1lbmRlZCkqKjogYGlkYCwgYGFjY2Vzc190b2tlbmAuXG4gKlxuICogIyMgQXV0aCBQYXlsb2Fkc1xuICogIyMjIFNlY3VyZSBBdXRoZW50aWNhdGlvbiBQYXlsb2FkXG4gKiBgYGBqc29uXG4gKiB7XG4gKiAgIFwic3BvdGlmeVwiOiB7XG4gKiAgICAgXCJjb2RlXCI6IFwiYWJjMTIzZGVmNDU2Z2hpNzg5XCIsXG4gKiAgICAgXCJyZWRpcmVjdF91cmlcIjogXCJodHRwczovL2V4YW1wbGUuY29tL2NhbGxiYWNrXCIsXG4gKiAgICAgXCJjb2RlX3ZlcmlmaWVyXCI6IFwic2VjdXJlLWNvZGUtdmVyaWZpZXJcIlxuICogICB9XG4gKiB9XG4gKiBgYGBcbiAqICMjIyBJbnNlY3VyZSBBdXRoZW50aWNhdGlvbiBQYXlsb2FkIChOb3QgUmVjb21tZW5kZWQpXG4gKiBgYGBqc29uXG4gKiB7XG4gKiAgIFwic3BvdGlmeVwiOiB7XG4gKiAgICAgXCJpZFwiOiBcIjEyMzQ1NjdcIixcbiAqICAgICBcImFjY2Vzc190b2tlblwiOiBcImFiYzEyM2RlZjQ1NmdoaTc4OVwiXG4gKiAgIH1cbiAqIH1cbiAqIGBgYFxuICpcbiAqICMjIE5vdGVzXG4gKiAtIGBlbmFibGVJbnNlY3VyZUF1dGhgIGlzICoqbm90IHJlY29tbWVuZGVkKiogYW5kIGJ5cGFzc2VzIHNlY3VyZSBmbG93cyBieSB2YWxpZGF0aW5nIHRoZSB1c2VyIElEIGFuZCBhY2Nlc3MgdG9rZW4gZGlyZWN0bHkuIFRoaXMgbWV0aG9kIGlzIG5vdCBzdWl0YWJsZSBmb3IgcHJvZHVjdGlvbiBlbnZpcm9ubWVudHMgYW5kIG1heSBiZSByZW1vdmVkIGluIGZ1dHVyZSB2ZXJzaW9ucy5cbiAqIC0gU2VjdXJlIGF1dGhlbnRpY2F0aW9uIGV4Y2hhbmdlcyB0aGUgYGNvZGVgIHByb3ZpZGVkIGJ5IHRoZSBjbGllbnQgZm9yIGFuIGFjY2VzcyB0b2tlbiB1c2luZyBTcG90aWZ5J3MgT0F1dGggQVBJLiBUaGlzIG1ldGhvZCBlbnN1cmVzIGdyZWF0ZXIgc2VjdXJpdHkgYW5kIGlzIHRoZSByZWNvbW1lbmRlZCBhcHByb2FjaC5cbiAqXG4gKiBAc2VlIHtAbGluayBodHRwczovL2RldmVsb3Blci5zcG90aWZ5LmNvbS9kb2N1bWVudGF0aW9uL3dlYi1hcGkvdHV0b3JpYWxzL2dldHRpbmctc3RhcnRlZCBTcG90aWZ5IE9BdXRoIERvY3VtZW50YXRpb259XG4gKi9cblxuaW1wb3J0IEJhc2VBdXRoQ29kZUFkYXB0ZXIgZnJvbSAnLi9CYXNlQ29kZUF1dGhBZGFwdGVyJztcbmNsYXNzIFNwb3RpZnlBZGFwdGVyIGV4dGVuZHMgQmFzZUF1dGhDb2RlQWRhcHRlciB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCdzcG90aWZ5Jyk7XG4gIH1cblxuICBhc3luYyBnZXRVc2VyRnJvbUFjY2Vzc1Rva2VuKGFjY2Vzc190b2tlbikge1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goJ2h0dHBzOi8vYXBpLnNwb3RpZnkuY29tL3YxL21lJywge1xuICAgICAgaGVhZGVyczoge1xuICAgICAgICBBdXRob3JpemF0aW9uOiAnQmVhcmVyICcgKyBhY2Nlc3NfdG9rZW4sXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgaWYgKCFyZXNwb25zZS5vaykge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdTcG90aWZ5IEFQSSByZXF1ZXN0IGZhaWxlZC4nKTtcbiAgICB9XG5cbiAgICBjb25zdCB1c2VyID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuICAgIHJldHVybiB7XG4gICAgICBpZDogdXNlci5pZCxcbiAgICB9O1xuICB9XG5cbiAgYXN5bmMgZ2V0QWNjZXNzVG9rZW5Gcm9tQ29kZShhdXRoRGF0YSkge1xuICAgIGlmICghYXV0aERhdGEuY29kZSB8fCAhYXV0aERhdGEucmVkaXJlY3RfdXJpIHx8ICFhdXRoRGF0YS5jb2RlX3ZlcmlmaWVyKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsXG4gICAgICAgICdTcG90aWZ5IGF1dGggY29uZmlndXJhdGlvbiBhdXRoRGF0YS5jb2RlIGFuZC9vciBhdXRoRGF0YS5yZWRpcmVjdF91cmkgYW5kL29yIGF1dGhEYXRhLmNvZGVfdmVyaWZpZXIuJ1xuICAgICAgKTtcbiAgICB9XG5cbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKCdodHRwczovL2FjY291bnRzLnNwb3RpZnkuY29tL2FwaS90b2tlbicsIHtcbiAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgaGVhZGVyczoge1xuICAgICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCcsXG4gICAgICB9LFxuICAgICAgYm9keTogbmV3IFVSTFNlYXJjaFBhcmFtcyh7XG4gICAgICAgIGdyYW50X3R5cGU6ICdhdXRob3JpemF0aW9uX2NvZGUnLFxuICAgICAgICBjb2RlOiBhdXRoRGF0YS5jb2RlLFxuICAgICAgICByZWRpcmVjdF91cmk6IGF1dGhEYXRhLnJlZGlyZWN0X3VyaSxcbiAgICAgICAgY29kZV92ZXJpZmllcjogYXV0aERhdGEuY29kZV92ZXJpZmllcixcbiAgICAgICAgY2xpZW50X2lkOiB0aGlzLmNsaWVudElkLFxuICAgICAgfSksXG4gICAgfSk7XG5cbiAgICBpZiAoIXJlc3BvbnNlLm9rKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ1Nwb3RpZnkgQVBJIHJlcXVlc3QgZmFpbGVkLicpO1xuICAgIH1cblxuICAgIHJldHVybiByZXNwb25zZS5qc29uKCk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgbmV3IFNwb3RpZnlBZGFwdGVyKCk7XG4iXSwibWFwcGluZ3MiOiI7Ozs7OztBQWdFQSxJQUFBQSxvQkFBQSxHQUFBQyxzQkFBQSxDQUFBQyxPQUFBO0FBQXdELFNBQUFELHVCQUFBRSxDQUFBLFdBQUFBLENBQUEsSUFBQUEsQ0FBQSxDQUFBQyxVQUFBLEdBQUFELENBQUEsS0FBQUUsT0FBQSxFQUFBRixDQUFBO0FBaEV4RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBR0EsTUFBTUcsY0FBYyxTQUFTQyw0QkFBbUIsQ0FBQztFQUMvQ0MsV0FBV0EsQ0FBQSxFQUFHO0lBQ1osS0FBSyxDQUFDLFNBQVMsQ0FBQztFQUNsQjtFQUVBLE1BQU1DLHNCQUFzQkEsQ0FBQ0MsWUFBWSxFQUFFO0lBQ3pDLE1BQU1DLFFBQVEsR0FBRyxNQUFNQyxLQUFLLENBQUMsK0JBQStCLEVBQUU7TUFDNURDLE9BQU8sRUFBRTtRQUNQQyxhQUFhLEVBQUUsU0FBUyxHQUFHSjtNQUM3QjtJQUNGLENBQUMsQ0FBQztJQUVGLElBQUksQ0FBQ0MsUUFBUSxDQUFDSSxFQUFFLEVBQUU7TUFDaEIsTUFBTSxJQUFJQyxLQUFLLENBQUNDLEtBQUssQ0FBQ0QsS0FBSyxDQUFDQyxLQUFLLENBQUNDLGdCQUFnQixFQUFFLDZCQUE2QixDQUFDO0lBQ3BGO0lBRUEsTUFBTUMsSUFBSSxHQUFHLE1BQU1SLFFBQVEsQ0FBQ1MsSUFBSSxDQUFDLENBQUM7SUFDbEMsT0FBTztNQUNMQyxFQUFFLEVBQUVGLElBQUksQ0FBQ0U7SUFDWCxDQUFDO0VBQ0g7RUFFQSxNQUFNQyxzQkFBc0JBLENBQUNDLFFBQVEsRUFBRTtJQUNyQyxJQUFJLENBQUNBLFFBQVEsQ0FBQ0MsSUFBSSxJQUFJLENBQUNELFFBQVEsQ0FBQ0UsWUFBWSxJQUFJLENBQUNGLFFBQVEsQ0FBQ0csYUFBYSxFQUFFO01BQ3ZFLE1BQU0sSUFBSVYsS0FBSyxDQUFDQyxLQUFLLENBQ25CRCxLQUFLLENBQUNDLEtBQUssQ0FBQ0MsZ0JBQWdCLEVBQzVCLHNHQUNGLENBQUM7SUFDSDtJQUVBLE1BQU1QLFFBQVEsR0FBRyxNQUFNQyxLQUFLLENBQUMsd0NBQXdDLEVBQUU7TUFDckVlLE1BQU0sRUFBRSxNQUFNO01BQ2RkLE9BQU8sRUFBRTtRQUNQLGNBQWMsRUFBRTtNQUNsQixDQUFDO01BQ0RlLElBQUksRUFBRSxJQUFJQyxlQUFlLENBQUM7UUFDeEJDLFVBQVUsRUFBRSxvQkFBb0I7UUFDaENOLElBQUksRUFBRUQsUUFBUSxDQUFDQyxJQUFJO1FBQ25CQyxZQUFZLEVBQUVGLFFBQVEsQ0FBQ0UsWUFBWTtRQUNuQ0MsYUFBYSxFQUFFSCxRQUFRLENBQUNHLGFBQWE7UUFDckNLLFNBQVMsRUFBRSxJQUFJLENBQUNDO01BQ2xCLENBQUM7SUFDSCxDQUFDLENBQUM7SUFFRixJQUFJLENBQUNyQixRQUFRLENBQUNJLEVBQUUsRUFBRTtNQUNoQixNQUFNLElBQUlDLEtBQUssQ0FBQ0MsS0FBSyxDQUFDRCxLQUFLLENBQUNDLEtBQUssQ0FBQ0MsZ0JBQWdCLEVBQUUsNkJBQTZCLENBQUM7SUFDcEY7SUFFQSxPQUFPUCxRQUFRLENBQUNTLElBQUksQ0FBQyxDQUFDO0VBQ3hCO0FBQ0Y7QUFBQyxJQUFBYSxRQUFBLEdBQUFDLE9BQUEsQ0FBQTdCLE9BQUEsR0FFYyxJQUFJQyxjQUFjLENBQUMsQ0FBQyIsImlnbm9yZUxpc3QiOltdfQ==
@@ -1,50 +1,197 @@
1
1
  "use strict";
2
2
 
3
- // Helper functions for accessing the twitter API.
4
- var OAuth = require('./OAuth1Client');
5
- var Parse = require('parse/node').Parse;
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _Config = _interopRequireDefault(require("../../Config"));
8
+ var _querystring = _interopRequireDefault(require("querystring"));
9
+ var _AuthAdapter = _interopRequireDefault(require("./AuthAdapter"));
10
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
11
+ /**
12
+ * Parse Server authentication adapter for Twitter.
13
+ *
14
+ * @class TwitterAdapter
15
+ * @param {Object} options - The adapter configuration options.
16
+ * @param {string} options.consumerKey - The Twitter App Consumer Key. Required for secure authentication.
17
+ * @param {string} options.consumerSecret - The Twitter App Consumer Secret. Required for secure authentication.
18
+ * @param {boolean} [options.enableInsecureAuth=false] - **[DEPRECATED]** Enable insecure authentication (not recommended).
19
+ *
20
+ * @description
21
+ * ## Parse Server Configuration
22
+ * To configure Parse Server for Twitter authentication, use the following structure:
23
+ * ### Secure Configuration
24
+ * ```json
25
+ * {
26
+ * "auth": {
27
+ * "twitter": {
28
+ * "consumerKey": "your-consumer-key",
29
+ * "consumerSecret": "your-consumer-secret"
30
+ * }
31
+ * }
32
+ * }
33
+ * ```
34
+ * ### Insecure Configuration (Not Recommended)
35
+ * ```json
36
+ * {
37
+ * "auth": {
38
+ * "twitter": {
39
+ * "enableInsecureAuth": true
40
+ * }
41
+ * }
42
+ * }
43
+ * ```
44
+ *
45
+ * The adapter requires the following `authData` fields:
46
+ * - **Secure Authentication**: `oauth_token`, `oauth_verifier`.
47
+ * - **Insecure Authentication (Not Recommended)**: `id`, `oauth_token`, `oauth_token_secret`.
48
+ *
49
+ * ## Auth Payloads
50
+ * ### Secure Authentication Payload
51
+ * ```json
52
+ * {
53
+ * "twitter": {
54
+ * "oauth_token": "1234567890-abc123def456",
55
+ * "oauth_verifier": "abc123def456"
56
+ * }
57
+ * }
58
+ * ```
59
+ *
60
+ * ### Insecure Authentication Payload (Not Recommended)
61
+ * ```json
62
+ * {
63
+ * "twitter": {
64
+ * "id": "1234567890",
65
+ * "oauth_token": "1234567890-abc123def456",
66
+ * "oauth_token_secret": "1234567890-abc123def456"
67
+ * }
68
+ * }
69
+ * ```
70
+ *
71
+ * ## Notes
72
+ * - **Deprecation Notice**: `enableInsecureAuth` and insecure fields (`id`, `oauth_token_secret`) are **deprecated** and may be removed in future versions. Use secure authentication with `consumerKey` and `consumerSecret`.
73
+ * - Secure authentication exchanges the `oauth_token` and `oauth_verifier` provided by the client for an access token using Twitter's OAuth API.
74
+ *
75
+ * @see {@link https://developer.twitter.com/en/docs/authentication/oauth-1-0a Twitter OAuth Documentation}
76
+ */
6
77
 
7
- // Returns a promise that fulfills iff this user id is valid.
8
- function validateAuthData(authData, options) {
9
- if (!options) {
10
- throw new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'Twitter auth configuration missing');
11
- }
12
- options = handleMultipleConfigurations(authData, options);
13
- var client = new OAuth(options);
14
- client.host = 'api.twitter.com';
15
- client.auth_token = authData.auth_token;
16
- client.auth_token_secret = authData.auth_token_secret;
17
- return client.get('/1.1/account/verify_credentials.json').then(data => {
18
- if (data && data.id_str == '' + authData.id) {
78
+ class TwitterAuthAdapter extends _AuthAdapter.default {
79
+ validateOptions(options) {
80
+ if (!options) {
81
+ throw new Error('Twitter auth options are required.');
82
+ }
83
+ this.enableInsecureAuth = options.enableInsecureAuth;
84
+ if (!this.enableInsecureAuth && (!options.consumer_key || !options.consumer_secret)) {
85
+ throw new Error('Consumer key and secret are required for secure Twitter auth.');
86
+ }
87
+ }
88
+ async validateAuthData(authData, options) {
89
+ const config = _Config.default.get(Parse.applicationId);
90
+ const twitterConfig = config.auth.twitter;
91
+ if (this.enableInsecureAuth && twitterConfig && config.enableInsecureAuthAdapters) {
92
+ return this.validateInsecureAuth(authData, options);
93
+ }
94
+ if (!options.consumer_key || !options.consumer_secret) {
95
+ throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Twitter auth configuration missing consumer_key and/or consumer_secret.');
96
+ }
97
+ const accessTokenData = await this.exchangeAccessToken(authData);
98
+ if (accessTokenData?.oauth_token && accessTokenData?.user_id) {
99
+ authData.id = accessTokenData.user_id;
100
+ authData.auth_token = accessTokenData.oauth_token;
19
101
  return;
20
102
  }
21
103
  throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Twitter auth is invalid for this user.');
22
- });
23
- }
24
-
25
- // Returns a promise that fulfills iff this app id is valid.
26
- function validateAppId() {
27
- return Promise.resolve();
28
- }
29
- function handleMultipleConfigurations(authData, options) {
30
- if (Array.isArray(options)) {
31
- const consumer_key = authData.consumer_key;
32
- if (!consumer_key) {
33
- throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Twitter auth is invalid for this user.');
34
- }
35
- options = options.filter(option => {
36
- return option.consumer_key == consumer_key;
104
+ }
105
+ async validateInsecureAuth(authData, options) {
106
+ if (!authData.oauth_token || !authData.oauth_token_secret) {
107
+ throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Twitter insecure auth requires oauth_token and oauth_token_secret.');
108
+ }
109
+ options = this.handleMultipleConfigurations(authData, options);
110
+ const data = await this.request(authData, options);
111
+ const parsedData = await data.json();
112
+ if (parsedData?.id === authData.id) {
113
+ return;
114
+ }
115
+ throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Twitter auth is invalid for this user.');
116
+ }
117
+ async exchangeAccessToken(authData) {
118
+ const accessTokenRequestOptions = {
119
+ method: 'POST',
120
+ headers: {
121
+ 'Content-Type': 'application/x-www-form-urlencoded'
122
+ },
123
+ body: _querystring.default.stringify({
124
+ oauth_token: authData.oauth_token,
125
+ oauth_verifier: authData.oauth_verifier
126
+ })
127
+ };
128
+ const response = await fetch('https://api.twitter.com/oauth/access_token', accessTokenRequestOptions);
129
+ if (!response.ok) {
130
+ throw new Error('Failed to exchange access token.');
131
+ }
132
+ return response.json();
133
+ }
134
+ handleMultipleConfigurations(authData, options) {
135
+ if (Array.isArray(options)) {
136
+ const consumer_key = authData.consumer_key;
137
+ if (!consumer_key) {
138
+ throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Twitter auth is invalid for this user.');
139
+ }
140
+ options = options.filter(option => option.consumer_key === consumer_key);
141
+ if (options.length === 0) {
142
+ throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Twitter auth is invalid for this user.');
143
+ }
144
+ return options[0];
145
+ }
146
+ return options;
147
+ }
148
+ async request(authData, options) {
149
+ const {
150
+ consumer_key,
151
+ consumer_secret
152
+ } = options;
153
+ const oauth = {
154
+ consumer_key,
155
+ consumer_secret,
156
+ auth_token: authData.oauth_token,
157
+ auth_token_secret: authData.oauth_token_secret
158
+ };
159
+ const url = new URL('https://api.twitter.com/2/users/me');
160
+ const response = await fetch(url, {
161
+ headers: {
162
+ Authorization: 'Bearer ' + oauth.auth_token
163
+ },
164
+ body: JSON.stringify(oauth)
37
165
  });
38
- if (options.length == 0) {
39
- throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Twitter auth is invalid for this user.');
166
+ if (!response.ok) {
167
+ throw new Error('Failed to fetch user data.');
40
168
  }
41
- options = options[0];
169
+ return response;
170
+ }
171
+ async beforeFind(authData) {
172
+ if (this.enableInsecureAuth && !authData?.code) {
173
+ if (!authData?.access_token) {
174
+ throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Twitter auth is invalid for this user.');
175
+ }
176
+ const user = await this.getUserFromAccessToken(authData.access_token, authData);
177
+ if (user.id !== authData.id) {
178
+ throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Twitter auth is invalid for this user.');
179
+ }
180
+ return;
181
+ }
182
+ if (!authData?.code) {
183
+ throw new Parse.Error(Parse.Error.VALIDATION_ERROR, 'Twitter code is required.');
184
+ }
185
+ const access_token = await this.exchangeAccessToken(authData);
186
+ const user = await this.getUserFromAccessToken(access_token, authData);
187
+ authData.access_token = access_token;
188
+ authData.id = user.id;
189
+ delete authData.code;
190
+ delete authData.redirect_uri;
191
+ }
192
+ validateAppId() {
193
+ return Promise.resolve();
42
194
  }
43
- return options;
44
195
  }
45
- module.exports = {
46
- validateAppId,
47
- validateAuthData,
48
- handleMultipleConfigurations
49
- };
50
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJPQXV0aCIsInJlcXVpcmUiLCJQYXJzZSIsInZhbGlkYXRlQXV0aERhdGEiLCJhdXRoRGF0YSIsIm9wdGlvbnMiLCJFcnJvciIsIklOVEVSTkFMX1NFUlZFUl9FUlJPUiIsImhhbmRsZU11bHRpcGxlQ29uZmlndXJhdGlvbnMiLCJjbGllbnQiLCJob3N0IiwiYXV0aF90b2tlbiIsImF1dGhfdG9rZW5fc2VjcmV0IiwiZ2V0IiwidGhlbiIsImRhdGEiLCJpZF9zdHIiLCJpZCIsIk9CSkVDVF9OT1RfRk9VTkQiLCJ2YWxpZGF0ZUFwcElkIiwiUHJvbWlzZSIsInJlc29sdmUiLCJBcnJheSIsImlzQXJyYXkiLCJjb25zdW1lcl9rZXkiLCJmaWx0ZXIiLCJvcHRpb24iLCJsZW5ndGgiLCJtb2R1bGUiLCJleHBvcnRzIl0sInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL0FkYXB0ZXJzL0F1dGgvdHdpdHRlci5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBIZWxwZXIgZnVuY3Rpb25zIGZvciBhY2Nlc3NpbmcgdGhlIHR3aXR0ZXIgQVBJLlxudmFyIE9BdXRoID0gcmVxdWlyZSgnLi9PQXV0aDFDbGllbnQnKTtcbnZhciBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKS5QYXJzZTtcblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBmdWxmaWxscyBpZmYgdGhpcyB1c2VyIGlkIGlzIHZhbGlkLlxuZnVuY3Rpb24gdmFsaWRhdGVBdXRoRGF0YShhdXRoRGF0YSwgb3B0aW9ucykge1xuICBpZiAoIW9wdGlvbnMpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5URVJOQUxfU0VSVkVSX0VSUk9SLCAnVHdpdHRlciBhdXRoIGNvbmZpZ3VyYXRpb24gbWlzc2luZycpO1xuICB9XG4gIG9wdGlvbnMgPSBoYW5kbGVNdWx0aXBsZUNvbmZpZ3VyYXRpb25zKGF1dGhEYXRhLCBvcHRpb25zKTtcbiAgdmFyIGNsaWVudCA9IG5ldyBPQXV0aChvcHRpb25zKTtcbiAgY2xpZW50Lmhvc3QgPSAnYXBpLnR3aXR0ZXIuY29tJztcbiAgY2xpZW50LmF1dGhfdG9rZW4gPSBhdXRoRGF0YS5hdXRoX3Rva2VuO1xuICBjbGllbnQuYXV0aF90b2tlbl9zZWNyZXQgPSBhdXRoRGF0YS5hdXRoX3Rva2VuX3NlY3JldDtcblxuICByZXR1cm4gY2xpZW50LmdldCgnLzEuMS9hY2NvdW50L3ZlcmlmeV9jcmVkZW50aWFscy5qc29uJykudGhlbihkYXRhID0+IHtcbiAgICBpZiAoZGF0YSAmJiBkYXRhLmlkX3N0ciA9PSAnJyArIGF1dGhEYXRhLmlkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAnVHdpdHRlciBhdXRoIGlzIGludmFsaWQgZm9yIHRoaXMgdXNlci4nKTtcbiAgfSk7XG59XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWZmIHRoaXMgYXBwIGlkIGlzIHZhbGlkLlxuZnVuY3Rpb24gdmFsaWRhdGVBcHBJZCgpIHtcbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xufVxuXG5mdW5jdGlvbiBoYW5kbGVNdWx0aXBsZUNvbmZpZ3VyYXRpb25zKGF1dGhEYXRhLCBvcHRpb25zKSB7XG4gIGlmIChBcnJheS5pc0FycmF5KG9wdGlvbnMpKSB7XG4gICAgY29uc3QgY29uc3VtZXJfa2V5ID0gYXV0aERhdGEuY29uc3VtZXJfa2V5O1xuICAgIGlmICghY29uc3VtZXJfa2V5KSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ1R3aXR0ZXIgYXV0aCBpcyBpbnZhbGlkIGZvciB0aGlzIHVzZXIuJyk7XG4gICAgfVxuICAgIG9wdGlvbnMgPSBvcHRpb25zLmZpbHRlcihvcHRpb24gPT4ge1xuICAgICAgcmV0dXJuIG9wdGlvbi5jb25zdW1lcl9rZXkgPT0gY29uc3VtZXJfa2V5O1xuICAgIH0pO1xuXG4gICAgaWYgKG9wdGlvbnMubGVuZ3RoID09IDApIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAnVHdpdHRlciBhdXRoIGlzIGludmFsaWQgZm9yIHRoaXMgdXNlci4nKTtcbiAgICB9XG4gICAgb3B0aW9ucyA9IG9wdGlvbnNbMF07XG4gIH1cbiAgcmV0dXJuIG9wdGlvbnM7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICB2YWxpZGF0ZUFwcElkLFxuICB2YWxpZGF0ZUF1dGhEYXRhLFxuICBoYW5kbGVNdWx0aXBsZUNvbmZpZ3VyYXRpb25zLFxufTtcbiJdLCJtYXBwaW5ncyI6Ijs7QUFBQTtBQUNBLElBQUlBLEtBQUssR0FBR0MsT0FBTyxDQUFDLGdCQUFnQixDQUFDO0FBQ3JDLElBQUlDLEtBQUssR0FBR0QsT0FBTyxDQUFDLFlBQVksQ0FBQyxDQUFDQyxLQUFLOztBQUV2QztBQUNBLFNBQVNDLGdCQUFnQkEsQ0FBQ0MsUUFBUSxFQUFFQyxPQUFPLEVBQUU7RUFDM0MsSUFBSSxDQUFDQSxPQUFPLEVBQUU7SUFDWixNQUFNLElBQUlILEtBQUssQ0FBQ0ksS0FBSyxDQUFDSixLQUFLLENBQUNJLEtBQUssQ0FBQ0MscUJBQXFCLEVBQUUsb0NBQW9DLENBQUM7RUFDaEc7RUFDQUYsT0FBTyxHQUFHRyw0QkFBNEIsQ0FBQ0osUUFBUSxFQUFFQyxPQUFPLENBQUM7RUFDekQsSUFBSUksTUFBTSxHQUFHLElBQUlULEtBQUssQ0FBQ0ssT0FBTyxDQUFDO0VBQy9CSSxNQUFNLENBQUNDLElBQUksR0FBRyxpQkFBaUI7RUFDL0JELE1BQU0sQ0FBQ0UsVUFBVSxHQUFHUCxRQUFRLENBQUNPLFVBQVU7RUFDdkNGLE1BQU0sQ0FBQ0csaUJBQWlCLEdBQUdSLFFBQVEsQ0FBQ1EsaUJBQWlCO0VBRXJELE9BQU9ILE1BQU0sQ0FBQ0ksR0FBRyxDQUFDLHNDQUFzQyxDQUFDLENBQUNDLElBQUksQ0FBQ0MsSUFBSSxJQUFJO0lBQ3JFLElBQUlBLElBQUksSUFBSUEsSUFBSSxDQUFDQyxNQUFNLElBQUksRUFBRSxHQUFHWixRQUFRLENBQUNhLEVBQUUsRUFBRTtNQUMzQztJQUNGO0lBQ0EsTUFBTSxJQUFJZixLQUFLLENBQUNJLEtBQUssQ0FBQ0osS0FBSyxDQUFDSSxLQUFLLENBQUNZLGdCQUFnQixFQUFFLHdDQUF3QyxDQUFDO0VBQy9GLENBQUMsQ0FBQztBQUNKOztBQUVBO0FBQ0EsU0FBU0MsYUFBYUEsQ0FBQSxFQUFHO0VBQ3ZCLE9BQU9DLE9BQU8sQ0FBQ0MsT0FBTyxDQUFDLENBQUM7QUFDMUI7QUFFQSxTQUFTYiw0QkFBNEJBLENBQUNKLFFBQVEsRUFBRUMsT0FBTyxFQUFFO0VBQ3ZELElBQUlpQixLQUFLLENBQUNDLE9BQU8sQ0FBQ2xCLE9BQU8sQ0FBQyxFQUFFO0lBQzFCLE1BQU1tQixZQUFZLEdBQUdwQixRQUFRLENBQUNvQixZQUFZO0lBQzFDLElBQUksQ0FBQ0EsWUFBWSxFQUFFO01BQ2pCLE1BQU0sSUFBSXRCLEtBQUssQ0FBQ0ksS0FBSyxDQUFDSixLQUFLLENBQUNJLEtBQUssQ0FBQ1ksZ0JBQWdCLEVBQUUsd0NBQXdDLENBQUM7SUFDL0Y7SUFDQWIsT0FBTyxHQUFHQSxPQUFPLENBQUNvQixNQUFNLENBQUNDLE1BQU0sSUFBSTtNQUNqQyxPQUFPQSxNQUFNLENBQUNGLFlBQVksSUFBSUEsWUFBWTtJQUM1QyxDQUFDLENBQUM7SUFFRixJQUFJbkIsT0FBTyxDQUFDc0IsTUFBTSxJQUFJLENBQUMsRUFBRTtNQUN2QixNQUFNLElBQUl6QixLQUFLLENBQUNJLEtBQUssQ0FBQ0osS0FBSyxDQUFDSSxLQUFLLENBQUNZLGdCQUFnQixFQUFFLHdDQUF3QyxDQUFDO0lBQy9GO0lBQ0FiLE9BQU8sR0FBR0EsT0FBTyxDQUFDLENBQUMsQ0FBQztFQUN0QjtFQUNBLE9BQU9BLE9BQU87QUFDaEI7QUFFQXVCLE1BQU0sQ0FBQ0MsT0FBTyxHQUFHO0VBQ2ZWLGFBQWE7RUFDYmhCLGdCQUFnQjtFQUNoQks7QUFDRixDQUFDIiwiaWdub3JlTGlzdCI6W119
196
+ var _default = exports.default = new TwitterAuthAdapter();
197
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfQ29uZmlnIiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsInJlcXVpcmUiLCJfcXVlcnlzdHJpbmciLCJfQXV0aEFkYXB0ZXIiLCJlIiwiX19lc01vZHVsZSIsImRlZmF1bHQiLCJUd2l0dGVyQXV0aEFkYXB0ZXIiLCJBdXRoQWRhcHRlciIsInZhbGlkYXRlT3B0aW9ucyIsIm9wdGlvbnMiLCJFcnJvciIsImVuYWJsZUluc2VjdXJlQXV0aCIsImNvbnN1bWVyX2tleSIsImNvbnN1bWVyX3NlY3JldCIsInZhbGlkYXRlQXV0aERhdGEiLCJhdXRoRGF0YSIsImNvbmZpZyIsIkNvbmZpZyIsImdldCIsIlBhcnNlIiwiYXBwbGljYXRpb25JZCIsInR3aXR0ZXJDb25maWciLCJhdXRoIiwidHdpdHRlciIsImVuYWJsZUluc2VjdXJlQXV0aEFkYXB0ZXJzIiwidmFsaWRhdGVJbnNlY3VyZUF1dGgiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwiYWNjZXNzVG9rZW5EYXRhIiwiZXhjaGFuZ2VBY2Nlc3NUb2tlbiIsIm9hdXRoX3Rva2VuIiwidXNlcl9pZCIsImlkIiwiYXV0aF90b2tlbiIsIm9hdXRoX3Rva2VuX3NlY3JldCIsImhhbmRsZU11bHRpcGxlQ29uZmlndXJhdGlvbnMiLCJkYXRhIiwicmVxdWVzdCIsInBhcnNlZERhdGEiLCJqc29uIiwiYWNjZXNzVG9rZW5SZXF1ZXN0T3B0aW9ucyIsIm1ldGhvZCIsImhlYWRlcnMiLCJib2R5IiwicXVlcnlzdHJpbmciLCJzdHJpbmdpZnkiLCJvYXV0aF92ZXJpZmllciIsInJlc3BvbnNlIiwiZmV0Y2giLCJvayIsIkFycmF5IiwiaXNBcnJheSIsImZpbHRlciIsIm9wdGlvbiIsImxlbmd0aCIsIm9hdXRoIiwiYXV0aF90b2tlbl9zZWNyZXQiLCJ1cmwiLCJVUkwiLCJBdXRob3JpemF0aW9uIiwiSlNPTiIsImJlZm9yZUZpbmQiLCJjb2RlIiwiYWNjZXNzX3Rva2VuIiwidXNlciIsImdldFVzZXJGcm9tQWNjZXNzVG9rZW4iLCJWQUxJREFUSU9OX0VSUk9SIiwicmVkaXJlY3RfdXJpIiwidmFsaWRhdGVBcHBJZCIsIlByb21pc2UiLCJyZXNvbHZlIiwiX2RlZmF1bHQiLCJleHBvcnRzIl0sInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL0FkYXB0ZXJzL0F1dGgvdHdpdHRlci5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFBhcnNlIFNlcnZlciBhdXRoZW50aWNhdGlvbiBhZGFwdGVyIGZvciBUd2l0dGVyLlxuICpcbiAqIEBjbGFzcyBUd2l0dGVyQWRhcHRlclxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgLSBUaGUgYWRhcHRlciBjb25maWd1cmF0aW9uIG9wdGlvbnMuXG4gKiBAcGFyYW0ge3N0cmluZ30gb3B0aW9ucy5jb25zdW1lcktleSAtIFRoZSBUd2l0dGVyIEFwcCBDb25zdW1lciBLZXkuIFJlcXVpcmVkIGZvciBzZWN1cmUgYXV0aGVudGljYXRpb24uXG4gKiBAcGFyYW0ge3N0cmluZ30gb3B0aW9ucy5jb25zdW1lclNlY3JldCAtIFRoZSBUd2l0dGVyIEFwcCBDb25zdW1lciBTZWNyZXQuIFJlcXVpcmVkIGZvciBzZWN1cmUgYXV0aGVudGljYXRpb24uXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLmVuYWJsZUluc2VjdXJlQXV0aD1mYWxzZV0gLSAqKltERVBSRUNBVEVEXSoqIEVuYWJsZSBpbnNlY3VyZSBhdXRoZW50aWNhdGlvbiAobm90IHJlY29tbWVuZGVkKS5cbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqICMjIFBhcnNlIFNlcnZlciBDb25maWd1cmF0aW9uXG4gKiBUbyBjb25maWd1cmUgUGFyc2UgU2VydmVyIGZvciBUd2l0dGVyIGF1dGhlbnRpY2F0aW9uLCB1c2UgdGhlIGZvbGxvd2luZyBzdHJ1Y3R1cmU6XG4gKiAjIyMgU2VjdXJlIENvbmZpZ3VyYXRpb25cbiAqIGBgYGpzb25cbiAqIHtcbiAqICAgXCJhdXRoXCI6IHtcbiAqICAgICBcInR3aXR0ZXJcIjoge1xuICogICAgICAgXCJjb25zdW1lcktleVwiOiBcInlvdXItY29uc3VtZXIta2V5XCIsXG4gKiAgICAgICBcImNvbnN1bWVyU2VjcmV0XCI6IFwieW91ci1jb25zdW1lci1zZWNyZXRcIlxuICogICAgIH1cbiAqICAgfVxuICogfVxuICogYGBgXG4gKiAjIyMgSW5zZWN1cmUgQ29uZmlndXJhdGlvbiAoTm90IFJlY29tbWVuZGVkKVxuICogYGBganNvblxuICoge1xuICogICBcImF1dGhcIjoge1xuICogICAgIFwidHdpdHRlclwiOiB7XG4gKiAgICAgICBcImVuYWJsZUluc2VjdXJlQXV0aFwiOiB0cnVlXG4gKiAgICAgfVxuICogICB9XG4gKiB9XG4gKiBgYGBcbiAqXG4gKiBUaGUgYWRhcHRlciByZXF1aXJlcyB0aGUgZm9sbG93aW5nIGBhdXRoRGF0YWAgZmllbGRzOlxuICogLSAqKlNlY3VyZSBBdXRoZW50aWNhdGlvbioqOiBgb2F1dGhfdG9rZW5gLCBgb2F1dGhfdmVyaWZpZXJgLlxuICogLSAqKkluc2VjdXJlIEF1dGhlbnRpY2F0aW9uIChOb3QgUmVjb21tZW5kZWQpKio6IGBpZGAsIGBvYXV0aF90b2tlbmAsIGBvYXV0aF90b2tlbl9zZWNyZXRgLlxuICpcbiAqICMjIEF1dGggUGF5bG9hZHNcbiAqICMjIyBTZWN1cmUgQXV0aGVudGljYXRpb24gUGF5bG9hZFxuICogYGBganNvblxuICoge1xuICogICBcInR3aXR0ZXJcIjoge1xuICogICAgIFwib2F1dGhfdG9rZW5cIjogXCIxMjM0NTY3ODkwLWFiYzEyM2RlZjQ1NlwiLFxuICogICAgIFwib2F1dGhfdmVyaWZpZXJcIjogXCJhYmMxMjNkZWY0NTZcIlxuICogICB9XG4gKiB9XG4gKiBgYGBcbiAqXG4gKiAjIyMgSW5zZWN1cmUgQXV0aGVudGljYXRpb24gUGF5bG9hZCAoTm90IFJlY29tbWVuZGVkKVxuICogYGBganNvblxuICoge1xuICogICBcInR3aXR0ZXJcIjoge1xuICogICAgIFwiaWRcIjogXCIxMjM0NTY3ODkwXCIsXG4gKiAgICAgXCJvYXV0aF90b2tlblwiOiBcIjEyMzQ1Njc4OTAtYWJjMTIzZGVmNDU2XCIsXG4gKiAgICAgXCJvYXV0aF90b2tlbl9zZWNyZXRcIjogXCIxMjM0NTY3ODkwLWFiYzEyM2RlZjQ1NlwiXG4gKiAgIH1cbiAqIH1cbiAqIGBgYFxuICpcbiAqICMjIE5vdGVzXG4gKiAtICoqRGVwcmVjYXRpb24gTm90aWNlKio6IGBlbmFibGVJbnNlY3VyZUF1dGhgIGFuZCBpbnNlY3VyZSBmaWVsZHMgKGBpZGAsIGBvYXV0aF90b2tlbl9zZWNyZXRgKSBhcmUgKipkZXByZWNhdGVkKiogYW5kIG1heSBiZSByZW1vdmVkIGluIGZ1dHVyZSB2ZXJzaW9ucy4gVXNlIHNlY3VyZSBhdXRoZW50aWNhdGlvbiB3aXRoIGBjb25zdW1lcktleWAgYW5kIGBjb25zdW1lclNlY3JldGAuXG4gKiAtIFNlY3VyZSBhdXRoZW50aWNhdGlvbiBleGNoYW5nZXMgdGhlIGBvYXV0aF90b2tlbmAgYW5kIGBvYXV0aF92ZXJpZmllcmAgcHJvdmlkZWQgYnkgdGhlIGNsaWVudCBmb3IgYW4gYWNjZXNzIHRva2VuIHVzaW5nIFR3aXR0ZXIncyBPQXV0aCBBUEkuXG4gKlxuICogQHNlZSB7QGxpbmsgaHR0cHM6Ly9kZXZlbG9wZXIudHdpdHRlci5jb20vZW4vZG9jcy9hdXRoZW50aWNhdGlvbi9vYXV0aC0xLTBhIFR3aXR0ZXIgT0F1dGggRG9jdW1lbnRhdGlvbn1cbiAqL1xuXG5pbXBvcnQgQ29uZmlnIGZyb20gJy4uLy4uL0NvbmZpZyc7XG5pbXBvcnQgcXVlcnlzdHJpbmcgZnJvbSAncXVlcnlzdHJpbmcnO1xuaW1wb3J0IEF1dGhBZGFwdGVyIGZyb20gJy4vQXV0aEFkYXB0ZXInO1xuXG5jbGFzcyBUd2l0dGVyQXV0aEFkYXB0ZXIgZXh0ZW5kcyBBdXRoQWRhcHRlciB7XG4gIHZhbGlkYXRlT3B0aW9ucyhvcHRpb25zKSB7XG4gICAgaWYgKCFvcHRpb25zKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1R3aXR0ZXIgYXV0aCBvcHRpb25zIGFyZSByZXF1aXJlZC4nKTtcbiAgICB9XG5cbiAgICB0aGlzLmVuYWJsZUluc2VjdXJlQXV0aCA9IG9wdGlvbnMuZW5hYmxlSW5zZWN1cmVBdXRoO1xuXG4gICAgaWYgKCF0aGlzLmVuYWJsZUluc2VjdXJlQXV0aCAmJiAoIW9wdGlvbnMuY29uc3VtZXJfa2V5IHx8ICFvcHRpb25zLmNvbnN1bWVyX3NlY3JldCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQ29uc3VtZXIga2V5IGFuZCBzZWNyZXQgYXJlIHJlcXVpcmVkIGZvciBzZWN1cmUgVHdpdHRlciBhdXRoLicpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIHZhbGlkYXRlQXV0aERhdGEoYXV0aERhdGEsIG9wdGlvbnMpIHtcbiAgICBjb25zdCBjb25maWcgPSBDb25maWcuZ2V0KFBhcnNlLmFwcGxpY2F0aW9uSWQpO1xuICAgIGNvbnN0IHR3aXR0ZXJDb25maWcgPSBjb25maWcuYXV0aC50d2l0dGVyO1xuXG4gICAgaWYgKHRoaXMuZW5hYmxlSW5zZWN1cmVBdXRoICYmIHR3aXR0ZXJDb25maWcgJiYgY29uZmlnLmVuYWJsZUluc2VjdXJlQXV0aEFkYXB0ZXJzKSB7XG4gICAgICByZXR1cm4gdGhpcy52YWxpZGF0ZUluc2VjdXJlQXV0aChhdXRoRGF0YSwgb3B0aW9ucyk7XG4gICAgfVxuXG4gICAgaWYgKCFvcHRpb25zLmNvbnN1bWVyX2tleSB8fCAhb3B0aW9ucy5jb25zdW1lcl9zZWNyZXQpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCxcbiAgICAgICAgJ1R3aXR0ZXIgYXV0aCBjb25maWd1cmF0aW9uIG1pc3NpbmcgY29uc3VtZXJfa2V5IGFuZC9vciBjb25zdW1lcl9zZWNyZXQuJ1xuICAgICAgKTtcbiAgICB9XG5cbiAgICBjb25zdCBhY2Nlc3NUb2tlbkRhdGEgPSBhd2FpdCB0aGlzLmV4Y2hhbmdlQWNjZXNzVG9rZW4oYXV0aERhdGEpO1xuXG4gICAgaWYgKGFjY2Vzc1Rva2VuRGF0YT8ub2F1dGhfdG9rZW4gJiYgYWNjZXNzVG9rZW5EYXRhPy51c2VyX2lkKSB7XG4gICAgICBhdXRoRGF0YS5pZCA9IGFjY2Vzc1Rva2VuRGF0YS51c2VyX2lkO1xuICAgICAgYXV0aERhdGEuYXV0aF90b2tlbiA9IGFjY2Vzc1Rva2VuRGF0YS5vYXV0aF90b2tlbjtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgJ1R3aXR0ZXIgYXV0aCBpcyBpbnZhbGlkIGZvciB0aGlzIHVzZXIuJ1xuICAgICk7XG4gIH1cblxuICBhc3luYyB2YWxpZGF0ZUluc2VjdXJlQXV0aChhdXRoRGF0YSwgb3B0aW9ucykge1xuICAgIGlmICghYXV0aERhdGEub2F1dGhfdG9rZW4gfHwgIWF1dGhEYXRhLm9hdXRoX3Rva2VuX3NlY3JldCkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgICAnVHdpdHRlciBpbnNlY3VyZSBhdXRoIHJlcXVpcmVzIG9hdXRoX3Rva2VuIGFuZCBvYXV0aF90b2tlbl9zZWNyZXQuJ1xuICAgICAgKTtcbiAgICB9XG5cbiAgICBvcHRpb25zID0gdGhpcy5oYW5kbGVNdWx0aXBsZUNvbmZpZ3VyYXRpb25zKGF1dGhEYXRhLCBvcHRpb25zKTtcblxuICAgIGNvbnN0IGRhdGEgPSBhd2FpdCB0aGlzLnJlcXVlc3QoYXV0aERhdGEsIG9wdGlvbnMpO1xuICAgIGNvbnN0IHBhcnNlZERhdGEgPSBhd2FpdCBkYXRhLmpzb24oKTtcblxuICAgIGlmIChwYXJzZWREYXRhPy5pZCA9PT0gYXV0aERhdGEuaWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgJ1R3aXR0ZXIgYXV0aCBpcyBpbnZhbGlkIGZvciB0aGlzIHVzZXIuJ1xuICAgICk7XG4gIH1cblxuICBhc3luYyBleGNoYW5nZUFjY2Vzc1Rva2VuKGF1dGhEYXRhKSB7XG4gICAgY29uc3QgYWNjZXNzVG9rZW5SZXF1ZXN0T3B0aW9ucyA9IHtcbiAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgaGVhZGVyczoge1xuICAgICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCcsXG4gICAgICB9LFxuICAgICAgYm9keTogcXVlcnlzdHJpbmcuc3RyaW5naWZ5KHtcbiAgICAgICAgb2F1dGhfdG9rZW46IGF1dGhEYXRhLm9hdXRoX3Rva2VuLFxuICAgICAgICBvYXV0aF92ZXJpZmllcjogYXV0aERhdGEub2F1dGhfdmVyaWZpZXIsXG4gICAgICB9KSxcbiAgICB9O1xuXG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCgnaHR0cHM6Ly9hcGkudHdpdHRlci5jb20vb2F1dGgvYWNjZXNzX3Rva2VuJywgYWNjZXNzVG9rZW5SZXF1ZXN0T3B0aW9ucyk7XG4gICAgaWYgKCFyZXNwb25zZS5vaykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdGYWlsZWQgdG8gZXhjaGFuZ2UgYWNjZXNzIHRva2VuLicpO1xuICAgIH1cblxuICAgIHJldHVybiByZXNwb25zZS5qc29uKCk7XG4gIH1cblxuICBoYW5kbGVNdWx0aXBsZUNvbmZpZ3VyYXRpb25zKGF1dGhEYXRhLCBvcHRpb25zKSB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkob3B0aW9ucykpIHtcbiAgICAgIGNvbnN0IGNvbnN1bWVyX2tleSA9IGF1dGhEYXRhLmNvbnN1bWVyX2tleTtcblxuICAgICAgaWYgKCFjb25zdW1lcl9rZXkpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsXG4gICAgICAgICAgJ1R3aXR0ZXIgYXV0aCBpcyBpbnZhbGlkIGZvciB0aGlzIHVzZXIuJ1xuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBvcHRpb25zID0gb3B0aW9ucy5maWx0ZXIob3B0aW9uID0+IG9wdGlvbi5jb25zdW1lcl9rZXkgPT09IGNvbnN1bWVyX2tleSk7XG5cbiAgICAgIGlmIChvcHRpb25zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCxcbiAgICAgICAgICAnVHdpdHRlciBhdXRoIGlzIGludmFsaWQgZm9yIHRoaXMgdXNlci4nXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBvcHRpb25zWzBdO1xuICAgIH1cblxuICAgIHJldHVybiBvcHRpb25zO1xuICB9XG5cbiAgYXN5bmMgcmVxdWVzdChhdXRoRGF0YSwgb3B0aW9ucykge1xuICAgIGNvbnN0IHsgY29uc3VtZXJfa2V5LCBjb25zdW1lcl9zZWNyZXQgfSA9IG9wdGlvbnM7XG5cbiAgICBjb25zdCBvYXV0aCA9IHtcbiAgICAgIGNvbnN1bWVyX2tleSxcbiAgICAgIGNvbnN1bWVyX3NlY3JldCxcbiAgICAgIGF1dGhfdG9rZW46IGF1dGhEYXRhLm9hdXRoX3Rva2VuLFxuICAgICAgYXV0aF90b2tlbl9zZWNyZXQ6IGF1dGhEYXRhLm9hdXRoX3Rva2VuX3NlY3JldCxcbiAgICB9O1xuXG4gICAgY29uc3QgdXJsID0gbmV3IFVSTCgnaHR0cHM6Ly9hcGkudHdpdHRlci5jb20vMi91c2Vycy9tZScpO1xuXG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCh1cmwsIHtcbiAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgQXV0aG9yaXphdGlvbjogJ0JlYXJlciAnICsgb2F1dGguYXV0aF90b2tlbixcbiAgICAgIH0sXG4gICAgICBib2R5OiBKU09OLnN0cmluZ2lmeShvYXV0aCksXG4gICAgfSk7XG5cbiAgICBpZiAoIXJlc3BvbnNlLm9rKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZhaWxlZCB0byBmZXRjaCB1c2VyIGRhdGEuJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3BvbnNlO1xuICB9XG5cbiAgYXN5bmMgYmVmb3JlRmluZChhdXRoRGF0YSkge1xuICAgIGlmICh0aGlzLmVuYWJsZUluc2VjdXJlQXV0aCAmJiAhYXV0aERhdGE/LmNvZGUpIHtcbiAgICAgIGlmICghYXV0aERhdGE/LmFjY2Vzc190b2tlbikge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ1R3aXR0ZXIgYXV0aCBpcyBpbnZhbGlkIGZvciB0aGlzIHVzZXIuJyk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHVzZXIgPSBhd2FpdCB0aGlzLmdldFVzZXJGcm9tQWNjZXNzVG9rZW4oYXV0aERhdGEuYWNjZXNzX3Rva2VuLCBhdXRoRGF0YSk7XG5cbiAgICAgIGlmICh1c2VyLmlkICE9PSBhdXRoRGF0YS5pZCkge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ1R3aXR0ZXIgYXV0aCBpcyBpbnZhbGlkIGZvciB0aGlzIHVzZXIuJyk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoIWF1dGhEYXRhPy5jb2RlKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuVkFMSURBVElPTl9FUlJPUiwgJ1R3aXR0ZXIgY29kZSBpcyByZXF1aXJlZC4nKTtcbiAgICB9XG5cbiAgICBjb25zdCBhY2Nlc3NfdG9rZW4gPSBhd2FpdCB0aGlzLmV4Y2hhbmdlQWNjZXNzVG9rZW4oYXV0aERhdGEpO1xuICAgIGNvbnN0IHVzZXIgPSBhd2FpdCB0aGlzLmdldFVzZXJGcm9tQWNjZXNzVG9rZW4oYWNjZXNzX3Rva2VuLCBhdXRoRGF0YSk7XG5cblxuICAgIGF1dGhEYXRhLmFjY2Vzc190b2tlbiA9IGFjY2Vzc190b2tlbjtcbiAgICBhdXRoRGF0YS5pZCA9IHVzZXIuaWQ7XG5cbiAgICBkZWxldGUgYXV0aERhdGEuY29kZTtcbiAgICBkZWxldGUgYXV0aERhdGEucmVkaXJlY3RfdXJpO1xuICB9XG5cbiAgdmFsaWRhdGVBcHBJZCgpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgbmV3IFR3aXR0ZXJBdXRoQWRhcHRlcigpO1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFtRUEsSUFBQUEsT0FBQSxHQUFBQyxzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQUMsWUFBQSxHQUFBRixzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQUUsWUFBQSxHQUFBSCxzQkFBQSxDQUFBQyxPQUFBO0FBQXdDLFNBQUFELHVCQUFBSSxDQUFBLFdBQUFBLENBQUEsSUFBQUEsQ0FBQSxDQUFBQyxVQUFBLEdBQUFELENBQUEsS0FBQUUsT0FBQSxFQUFBRixDQUFBO0FBckV4QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBTUEsTUFBTUcsa0JBQWtCLFNBQVNDLG9CQUFXLENBQUM7RUFDM0NDLGVBQWVBLENBQUNDLE9BQU8sRUFBRTtJQUN2QixJQUFJLENBQUNBLE9BQU8sRUFB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