@dynamic-labs/utils 3.0.0-alpha.6 → 3.0.0-alpha.60

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 (60) hide show
  1. package/CHANGELOG.md +585 -0
  2. package/_virtual/_tslib.cjs +15 -0
  3. package/_virtual/_tslib.js +14 -1
  4. package/package.json +4 -4
  5. package/src/errors/MfaInvalidOtpError.cjs +1 -1
  6. package/src/errors/MfaInvalidOtpError.js +1 -1
  7. package/src/errors/MfaRateLimitedError.cjs +14 -0
  8. package/src/errors/MfaRateLimitedError.d.ts +4 -0
  9. package/src/errors/MfaRateLimitedError.js +10 -0
  10. package/src/errors/NoAccessError.cjs +3 -1
  11. package/src/errors/NoAccessError.d.ts +5 -1
  12. package/src/errors/NoAccessError.js +3 -1
  13. package/src/errors/SandboxMaximumThresholdReachedError.cjs +15 -0
  14. package/src/errors/SandboxMaximumThresholdReachedError.d.ts +5 -0
  15. package/src/errors/SandboxMaximumThresholdReachedError.js +11 -0
  16. package/src/errors/UserRejectedRequestError.cjs +14 -0
  17. package/src/errors/UserRejectedRequestError.d.ts +4 -0
  18. package/src/errors/UserRejectedRequestError.js +10 -0
  19. package/src/errors/WalletAddressMismatchError.cjs +17 -0
  20. package/src/errors/WalletAddressMismatchError.d.ts +11 -0
  21. package/src/errors/WalletAddressMismatchError.js +13 -0
  22. package/src/errors/index.d.ts +4 -0
  23. package/src/handleMobileWalletRedirect/handleMobileWalletRedirect.cjs +0 -6
  24. package/src/handleMobileWalletRedirect/handleMobileWalletRedirect.js +0 -6
  25. package/src/index.cjs +15 -0
  26. package/src/index.d.ts +2 -0
  27. package/src/index.js +8 -1
  28. package/src/isMobile.cjs +11 -0
  29. package/src/isMobile.d.ts +1 -0
  30. package/src/isMobile.js +11 -1
  31. package/src/nativeMobileOauthStateParam.cjs +13 -0
  32. package/src/nativeMobileOauthStateParam.d.ts +14 -0
  33. package/src/nativeMobileOauthStateParam.js +9 -0
  34. package/src/retryableFn.cjs +1 -5
  35. package/src/retryableFn.js +1 -5
  36. package/src/services/FetchService/FetchService.cjs +10 -5
  37. package/src/services/FetchService/FetchService.d.ts +2 -2
  38. package/src/services/FetchService/FetchService.js +10 -5
  39. package/src/services/Oauth2Service/Oauth2Service.cjs +38 -0
  40. package/src/services/Oauth2Service/Oauth2Service.d.ts +41 -0
  41. package/src/services/Oauth2Service/Oauth2Service.js +34 -0
  42. package/src/services/Oauth2Service/createWindowOauth2Service/createWindowOauth2Service.cjs +176 -0
  43. package/src/services/Oauth2Service/createWindowOauth2Service/createWindowOauth2Service.d.ts +2 -0
  44. package/src/services/Oauth2Service/createWindowOauth2Service/createWindowOauth2Service.js +172 -0
  45. package/src/services/Oauth2Service/createWindowOauth2Service/index.d.ts +1 -0
  46. package/src/services/Oauth2Service/index.d.ts +2 -0
  47. package/src/services/Oauth2Service/utils/connectWithAppleId/connectWithAppleId.cjs +26 -0
  48. package/src/services/Oauth2Service/utils/connectWithAppleId/connectWithAppleId.d.ts +7 -0
  49. package/src/services/Oauth2Service/utils/connectWithAppleId/connectWithAppleId.js +22 -0
  50. package/src/services/Oauth2Service/utils/connectWithAppleId/index.d.ts +1 -0
  51. package/src/services/Oauth2Service/utils/loadAppleId/index.d.ts +1 -0
  52. package/src/services/Oauth2Service/utils/loadAppleId/loadAppleId.cjs +34 -0
  53. package/src/services/Oauth2Service/utils/loadAppleId/loadAppleId.d.ts +1 -0
  54. package/src/services/Oauth2Service/utils/loadAppleId/loadAppleId.js +30 -0
  55. package/src/services/PlatformService/PlatformService.cjs +38 -13
  56. package/src/services/PlatformService/PlatformService.d.ts +25 -3
  57. package/src/services/PlatformService/PlatformService.js +40 -15
  58. package/src/services/PlatformService/createBrowserPlatformService/createBrowserPlatformService.cjs +1 -3
  59. package/src/services/PlatformService/createBrowserPlatformService/createBrowserPlatformService.js +1 -3
  60. package/src/services/PlatformService/types.d.ts +5 -4
@@ -1,20 +1,25 @@
1
1
  'use client'
2
+ import { __classPrivateFieldGet, __classPrivateFieldSet } from '../../../_virtual/_tslib.js';
3
+
4
+ var _a, _FetchService_implementation;
2
5
  /**
3
6
  * Class implementing the fetch service with a configurable fetch implementation.
4
7
  */
5
8
  class FetchService {
6
9
  static get implementation() {
7
- if (!FetchService._implementation) {
10
+ if (!__classPrivateFieldGet(_a, _a, "f", _FetchService_implementation)) {
8
11
  return { fetch: window.fetch.bind(window) };
9
12
  }
10
- return FetchService._implementation;
13
+ return __classPrivateFieldGet(_a, _a, "f", _FetchService_implementation);
11
14
  }
12
- static setImplementation(implementation) {
13
- FetchService._implementation = implementation;
15
+ static set implementation(implementation) {
16
+ __classPrivateFieldSet(_a, _a, implementation, "f", _FetchService_implementation);
14
17
  }
15
18
  static get fetch() {
16
- return FetchService.implementation.fetch;
19
+ return _a.implementation.fetch;
17
20
  }
18
21
  }
22
+ _a = FetchService;
23
+ _FetchService_implementation = { value: void 0 };
19
24
 
20
25
  export { FetchService };
@@ -0,0 +1,38 @@
1
+ 'use client'
2
+ 'use strict';
3
+
4
+ Object.defineProperty(exports, '__esModule', { value: true });
5
+
6
+ var _tslib = require('../../../_virtual/_tslib.cjs');
7
+ var types = require('@dynamic-labs/types');
8
+ var createWindowOauth2Service = require('./createWindowOauth2Service/createWindowOauth2Service.cjs');
9
+
10
+ var _a, _Oauth2Service_implementation;
11
+ /**
12
+ * Class implementing the fetch service with a configurable fetch implementation.
13
+ */
14
+ class Oauth2Service {
15
+ static get implementation() {
16
+ if (!_tslib.__classPrivateFieldGet(_a, _a, "f", _Oauth2Service_implementation)) {
17
+ return createWindowOauth2Service.createWindowOauth2Service();
18
+ }
19
+ return _tslib.__classPrivateFieldGet(_a, _a, "f", _Oauth2Service_implementation);
20
+ }
21
+ static set implementation(implementation) {
22
+ _tslib.__classPrivateFieldSet(_a, _a, implementation, "f", _Oauth2Service_implementation);
23
+ }
24
+ static get getOauthCode() {
25
+ return _a.implementation.getOauthCode;
26
+ }
27
+ }
28
+ _a = Oauth2Service;
29
+ _Oauth2Service_implementation = { value: void 0 };
30
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
31
+ Oauth2Service.isGetOauthCodeError = (error) => error === 'user-cancelled' ||
32
+ (typeof error === 'object' &&
33
+ 'code' in error &&
34
+ Object.values(types.SocialOAuthErrorCode).includes(error.code) &&
35
+ 'message' in error &&
36
+ typeof error.message === 'string');
37
+
38
+ exports.Oauth2Service = Oauth2Service;
@@ -0,0 +1,41 @@
1
+ import { OauthResultResponse, Provider, ProviderEnum } from '@dynamic-labs/sdk-api-core';
2
+ import { SocialOAuthErrorCode } from '@dynamic-labs/types';
3
+ export type GetOauthCodeProps = {
4
+ provider: ProviderEnum;
5
+ apiProvider: Provider | undefined;
6
+ setIsProcessing: (value: boolean) => void;
7
+ onSettled?: VoidFunction;
8
+ getOAuthResultFromApi: () => Promise<OauthResultResponse | undefined>;
9
+ initWebAuth: (options?: {
10
+ redirectUrl?: string;
11
+ }) => Promise<void>;
12
+ state: string;
13
+ oauthLoginUrl: URL;
14
+ /**
15
+ * The preferred strategy to use for the OAuth2 flow.
16
+ */
17
+ strategy: 'popup' | 'redirect';
18
+ sessionTimeout: number;
19
+ /**
20
+ * Overrides the default redirectUrl coming from the DynamicContextProvider
21
+ */
22
+ redirectUrl?: string;
23
+ isMobile?: boolean;
24
+ };
25
+ export type IOauth2Service = {
26
+ getOauthCode: (props: GetOauthCodeProps) => Promise<string>;
27
+ };
28
+ export type GetOauthCodeError = 'user-cancelled' | {
29
+ code: SocialOAuthErrorCode;
30
+ message: string;
31
+ };
32
+ /**
33
+ * Class implementing the fetch service with a configurable fetch implementation.
34
+ */
35
+ export declare class Oauth2Service {
36
+ #private;
37
+ static get implementation(): IOauth2Service;
38
+ static set implementation(implementation: IOauth2Service);
39
+ static get getOauthCode(): (props: GetOauthCodeProps) => Promise<string>;
40
+ static isGetOauthCodeError: (error: any) => error is GetOauthCodeError;
41
+ }
@@ -0,0 +1,34 @@
1
+ 'use client'
2
+ import { __classPrivateFieldGet, __classPrivateFieldSet } from '../../../_virtual/_tslib.js';
3
+ import { SocialOAuthErrorCode } from '@dynamic-labs/types';
4
+ import { createWindowOauth2Service } from './createWindowOauth2Service/createWindowOauth2Service.js';
5
+
6
+ var _a, _Oauth2Service_implementation;
7
+ /**
8
+ * Class implementing the fetch service with a configurable fetch implementation.
9
+ */
10
+ class Oauth2Service {
11
+ static get implementation() {
12
+ if (!__classPrivateFieldGet(_a, _a, "f", _Oauth2Service_implementation)) {
13
+ return createWindowOauth2Service();
14
+ }
15
+ return __classPrivateFieldGet(_a, _a, "f", _Oauth2Service_implementation);
16
+ }
17
+ static set implementation(implementation) {
18
+ __classPrivateFieldSet(_a, _a, implementation, "f", _Oauth2Service_implementation);
19
+ }
20
+ static get getOauthCode() {
21
+ return _a.implementation.getOauthCode;
22
+ }
23
+ }
24
+ _a = Oauth2Service;
25
+ _Oauth2Service_implementation = { value: void 0 };
26
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
27
+ Oauth2Service.isGetOauthCodeError = (error) => error === 'user-cancelled' ||
28
+ (typeof error === 'object' &&
29
+ 'code' in error &&
30
+ Object.values(SocialOAuthErrorCode).includes(error.code) &&
31
+ 'message' in error &&
32
+ typeof error.message === 'string');
33
+
34
+ export { Oauth2Service };
@@ -0,0 +1,176 @@
1
+ 'use client'
2
+ 'use strict';
3
+
4
+ Object.defineProperty(exports, '__esModule', { value: true });
5
+
6
+ var _tslib = require('../../../../_virtual/_tslib.cjs');
7
+ var types = require('@dynamic-labs/types');
8
+ var logger = require('../../../logger/logger.cjs');
9
+ var connectWithAppleId = require('../utils/connectWithAppleId/connectWithAppleId.cjs');
10
+ var isMobile = require('../../../isMobile.cjs');
11
+
12
+ let authWindowInterval;
13
+ const createWindowOauth2Service = () => ({
14
+ getOauthCode: ({ apiProvider, provider, redirectUrl, setIsProcessing, state, oauthLoginUrl, initWebAuth, strategy, }) => new Promise((resolve, _reject) => {
15
+ /**
16
+ * Use AppleID SDK for Apple provider on mobile
17
+ * It should use the strategy setting, but on ios or safari
18
+ * it should use the appleId always as it is the best experience
19
+ */
20
+ if (provider === types.ProviderEnum.Apple &&
21
+ (isMobile.isSafariBrowser() || isMobile.isIOS() || strategy === 'redirect')) {
22
+ initWebAuth({
23
+ redirectUrl: redirectUrl || window.location.href,
24
+ }).then(() => connectWithAppleId.connectWithAppleId({
25
+ clientId: apiProvider === null || apiProvider === void 0 ? void 0 : apiProvider.clientId,
26
+ oauthLoginUrl,
27
+ state,
28
+ }).catch(_reject));
29
+ return;
30
+ }
31
+ /**
32
+ * Use redirect flow on mobile for all providers except Telegram
33
+ */
34
+ if (strategy === 'redirect' && provider !== types.ProviderEnum.Telegram) {
35
+ initWebAuth({
36
+ redirectUrl: redirectUrl || window.location.href,
37
+ }).then(() => {
38
+ window.location.assign(oauthLoginUrl);
39
+ });
40
+ return;
41
+ }
42
+ // When we catch this error we assume it follows this type, so we must enforce it
43
+ // here to ensure the assumption is correct
44
+ const typedReject = (params) => _reject(params);
45
+ // Clear any potential pending timeouts and intervals
46
+ clearInterval(authWindowInterval);
47
+ const providersWaitingOauthMessage = {};
48
+ const authWindow = window.open('', '_blank', 'width=500,height=600');
49
+ const clearListeners = () => {
50
+ window.removeEventListener('message', handleWindowMessage);
51
+ providersWaitingOauthMessage[provider] = false;
52
+ };
53
+ const handleWindowMessage = (event) => _tslib.__awaiter(void 0, void 0, void 0, function* () {
54
+ const message = event.data;
55
+ const expectedOrigin = getExpectedOrigin(apiProvider);
56
+ if (!expectedOrigin) {
57
+ return;
58
+ }
59
+ if ((message === null || message === void 0 ? void 0 : message.type) === 'origin_check' && authWindow) {
60
+ logger.logger.debug('Origin check message received. Sending response now.', {
61
+ data: message,
62
+ expectedOrigin,
63
+ });
64
+ authWindow.postMessage('origin_check_response', expectedOrigin);
65
+ return;
66
+ }
67
+ const isTelegramCompletedMessage = (message === null || message === void 0 ? void 0 : message.type) === 'telegram_completed';
68
+ const isAuthorizationMessage = (message === null || message === void 0 ? void 0 : message.type) === 'authorization_response';
69
+ if (isAuthorizationMessage || isTelegramCompletedMessage) {
70
+ logger.logger.debug('Message received', { data: message });
71
+ }
72
+ const isExpectedOrigin = event.origin === expectedOrigin;
73
+ const isValidMessage = ((isAuthorizationMessage && (message === null || message === void 0 ? void 0 : message.provider) === provider) ||
74
+ isTelegramCompletedMessage) &&
75
+ isExpectedOrigin;
76
+ // don't process invalid messages for provider
77
+ if (!isValidMessage) {
78
+ return;
79
+ }
80
+ setIsProcessing(true);
81
+ if (!providersWaitingOauthMessage[provider]) {
82
+ typedReject({
83
+ code: types.SocialOAuthErrorCode.SESSION_TIMEOUT,
84
+ message: `Connecting ${provider} account session timeout.`,
85
+ });
86
+ return;
87
+ }
88
+ clearListeners();
89
+ if (isTelegramCompletedMessage) {
90
+ handleTelegramCompletionMessage(message, state);
91
+ return;
92
+ }
93
+ handleAuthorizationMessage(message, provider, state);
94
+ });
95
+ const getExpectedOrigin = (apiProvider) => {
96
+ if (!(apiProvider === null || apiProvider === void 0 ? void 0 : apiProvider.redirectUrl)) {
97
+ return;
98
+ }
99
+ try {
100
+ const redirectUri = new URL(apiProvider.redirectUrl);
101
+ return redirectUri.origin;
102
+ }
103
+ catch (e) {
104
+ logger.logger.error('Failed to parse social provider redirect url', {
105
+ error: e,
106
+ });
107
+ return;
108
+ }
109
+ };
110
+ const handleTelegramCompletionMessage = (message, state) => {
111
+ logger.logger.debug('Telegram completion message received', {
112
+ data: message,
113
+ });
114
+ const { code, state: authState } = message;
115
+ // check that the state we receive from message is the same state we calculated earlier
116
+ // this could be an attack
117
+ if (state !== authState) {
118
+ typedReject({
119
+ code: types.SocialOAuthErrorCode.OAUTH_ERROR,
120
+ message: 'Failed to connect telegram account: Invalid random state',
121
+ });
122
+ return;
123
+ }
124
+ resolve(code);
125
+ setIsProcessing(false);
126
+ };
127
+ const handleAuthorizationMessage = (message, provider, state) => {
128
+ const { code, error, state: authState } = message;
129
+ if (error && error !== 'undefined') {
130
+ typedReject({
131
+ code: types.SocialOAuthErrorCode.OAUTH_ERROR,
132
+ message: `Failed to connect ${provider} social account: ${error}`,
133
+ });
134
+ return;
135
+ }
136
+ // check that the state we receive from message is the same state we calculated earlier
137
+ // this could be an attack
138
+ // this state check is used only by providers with an open window opener reference (eg, not twitter)
139
+ if (state !== authState) {
140
+ typedReject({
141
+ code: types.SocialOAuthErrorCode.OAUTH_ERROR,
142
+ message: `Failed to connect ${provider} social account: Invalid random state`,
143
+ });
144
+ return;
145
+ }
146
+ if (!code) {
147
+ typedReject({
148
+ code: types.SocialOAuthErrorCode.NO_AUTH_CODE,
149
+ message: `Failed to connect ${provider} social account: no authorization code`,
150
+ });
151
+ return;
152
+ }
153
+ resolve(code);
154
+ setIsProcessing(false);
155
+ };
156
+ if (!providersWaitingOauthMessage[provider]) {
157
+ window.addEventListener('message', handleWindowMessage);
158
+ providersWaitingOauthMessage[provider] = true;
159
+ }
160
+ // First we store the state in backend
161
+ initWebAuth().then(() => {
162
+ authWindow === null || authWindow === void 0 ? void 0 : authWindow.location.assign(oauthLoginUrl);
163
+ authWindowInterval = setInterval(() => {
164
+ if (!(authWindow === null || authWindow === void 0 ? void 0 : authWindow.closed))
165
+ return;
166
+ clearInterval(authWindowInterval);
167
+ setIsProcessing(false);
168
+ // user didn't complete oauth
169
+ if (providersWaitingOauthMessage[provider])
170
+ typedReject('user-cancelled');
171
+ }, 2000);
172
+ });
173
+ }),
174
+ });
175
+
176
+ exports.createWindowOauth2Service = createWindowOauth2Service;
@@ -0,0 +1,2 @@
1
+ import { IOauth2Service } from '../Oauth2Service';
2
+ export declare const createWindowOauth2Service: () => IOauth2Service;
@@ -0,0 +1,172 @@
1
+ 'use client'
2
+ import { __awaiter } from '../../../../_virtual/_tslib.js';
3
+ import { ProviderEnum, SocialOAuthErrorCode } from '@dynamic-labs/types';
4
+ import { logger } from '../../../logger/logger.js';
5
+ import { connectWithAppleId } from '../utils/connectWithAppleId/connectWithAppleId.js';
6
+ import { isSafariBrowser, isIOS } from '../../../isMobile.js';
7
+
8
+ let authWindowInterval;
9
+ const createWindowOauth2Service = () => ({
10
+ getOauthCode: ({ apiProvider, provider, redirectUrl, setIsProcessing, state, oauthLoginUrl, initWebAuth, strategy, }) => new Promise((resolve, _reject) => {
11
+ /**
12
+ * Use AppleID SDK for Apple provider on mobile
13
+ * It should use the strategy setting, but on ios or safari
14
+ * it should use the appleId always as it is the best experience
15
+ */
16
+ if (provider === ProviderEnum.Apple &&
17
+ (isSafariBrowser() || isIOS() || strategy === 'redirect')) {
18
+ initWebAuth({
19
+ redirectUrl: redirectUrl || window.location.href,
20
+ }).then(() => connectWithAppleId({
21
+ clientId: apiProvider === null || apiProvider === void 0 ? void 0 : apiProvider.clientId,
22
+ oauthLoginUrl,
23
+ state,
24
+ }).catch(_reject));
25
+ return;
26
+ }
27
+ /**
28
+ * Use redirect flow on mobile for all providers except Telegram
29
+ */
30
+ if (strategy === 'redirect' && provider !== ProviderEnum.Telegram) {
31
+ initWebAuth({
32
+ redirectUrl: redirectUrl || window.location.href,
33
+ }).then(() => {
34
+ window.location.assign(oauthLoginUrl);
35
+ });
36
+ return;
37
+ }
38
+ // When we catch this error we assume it follows this type, so we must enforce it
39
+ // here to ensure the assumption is correct
40
+ const typedReject = (params) => _reject(params);
41
+ // Clear any potential pending timeouts and intervals
42
+ clearInterval(authWindowInterval);
43
+ const providersWaitingOauthMessage = {};
44
+ const authWindow = window.open('', '_blank', 'width=500,height=600');
45
+ const clearListeners = () => {
46
+ window.removeEventListener('message', handleWindowMessage);
47
+ providersWaitingOauthMessage[provider] = false;
48
+ };
49
+ const handleWindowMessage = (event) => __awaiter(void 0, void 0, void 0, function* () {
50
+ const message = event.data;
51
+ const expectedOrigin = getExpectedOrigin(apiProvider);
52
+ if (!expectedOrigin) {
53
+ return;
54
+ }
55
+ if ((message === null || message === void 0 ? void 0 : message.type) === 'origin_check' && authWindow) {
56
+ logger.debug('Origin check message received. Sending response now.', {
57
+ data: message,
58
+ expectedOrigin,
59
+ });
60
+ authWindow.postMessage('origin_check_response', expectedOrigin);
61
+ return;
62
+ }
63
+ const isTelegramCompletedMessage = (message === null || message === void 0 ? void 0 : message.type) === 'telegram_completed';
64
+ const isAuthorizationMessage = (message === null || message === void 0 ? void 0 : message.type) === 'authorization_response';
65
+ if (isAuthorizationMessage || isTelegramCompletedMessage) {
66
+ logger.debug('Message received', { data: message });
67
+ }
68
+ const isExpectedOrigin = event.origin === expectedOrigin;
69
+ const isValidMessage = ((isAuthorizationMessage && (message === null || message === void 0 ? void 0 : message.provider) === provider) ||
70
+ isTelegramCompletedMessage) &&
71
+ isExpectedOrigin;
72
+ // don't process invalid messages for provider
73
+ if (!isValidMessage) {
74
+ return;
75
+ }
76
+ setIsProcessing(true);
77
+ if (!providersWaitingOauthMessage[provider]) {
78
+ typedReject({
79
+ code: SocialOAuthErrorCode.SESSION_TIMEOUT,
80
+ message: `Connecting ${provider} account session timeout.`,
81
+ });
82
+ return;
83
+ }
84
+ clearListeners();
85
+ if (isTelegramCompletedMessage) {
86
+ handleTelegramCompletionMessage(message, state);
87
+ return;
88
+ }
89
+ handleAuthorizationMessage(message, provider, state);
90
+ });
91
+ const getExpectedOrigin = (apiProvider) => {
92
+ if (!(apiProvider === null || apiProvider === void 0 ? void 0 : apiProvider.redirectUrl)) {
93
+ return;
94
+ }
95
+ try {
96
+ const redirectUri = new URL(apiProvider.redirectUrl);
97
+ return redirectUri.origin;
98
+ }
99
+ catch (e) {
100
+ logger.error('Failed to parse social provider redirect url', {
101
+ error: e,
102
+ });
103
+ return;
104
+ }
105
+ };
106
+ const handleTelegramCompletionMessage = (message, state) => {
107
+ logger.debug('Telegram completion message received', {
108
+ data: message,
109
+ });
110
+ const { code, state: authState } = message;
111
+ // check that the state we receive from message is the same state we calculated earlier
112
+ // this could be an attack
113
+ if (state !== authState) {
114
+ typedReject({
115
+ code: SocialOAuthErrorCode.OAUTH_ERROR,
116
+ message: 'Failed to connect telegram account: Invalid random state',
117
+ });
118
+ return;
119
+ }
120
+ resolve(code);
121
+ setIsProcessing(false);
122
+ };
123
+ const handleAuthorizationMessage = (message, provider, state) => {
124
+ const { code, error, state: authState } = message;
125
+ if (error && error !== 'undefined') {
126
+ typedReject({
127
+ code: SocialOAuthErrorCode.OAUTH_ERROR,
128
+ message: `Failed to connect ${provider} social account: ${error}`,
129
+ });
130
+ return;
131
+ }
132
+ // check that the state we receive from message is the same state we calculated earlier
133
+ // this could be an attack
134
+ // this state check is used only by providers with an open window opener reference (eg, not twitter)
135
+ if (state !== authState) {
136
+ typedReject({
137
+ code: SocialOAuthErrorCode.OAUTH_ERROR,
138
+ message: `Failed to connect ${provider} social account: Invalid random state`,
139
+ });
140
+ return;
141
+ }
142
+ if (!code) {
143
+ typedReject({
144
+ code: SocialOAuthErrorCode.NO_AUTH_CODE,
145
+ message: `Failed to connect ${provider} social account: no authorization code`,
146
+ });
147
+ return;
148
+ }
149
+ resolve(code);
150
+ setIsProcessing(false);
151
+ };
152
+ if (!providersWaitingOauthMessage[provider]) {
153
+ window.addEventListener('message', handleWindowMessage);
154
+ providersWaitingOauthMessage[provider] = true;
155
+ }
156
+ // First we store the state in backend
157
+ initWebAuth().then(() => {
158
+ authWindow === null || authWindow === void 0 ? void 0 : authWindow.location.assign(oauthLoginUrl);
159
+ authWindowInterval = setInterval(() => {
160
+ if (!(authWindow === null || authWindow === void 0 ? void 0 : authWindow.closed))
161
+ return;
162
+ clearInterval(authWindowInterval);
163
+ setIsProcessing(false);
164
+ // user didn't complete oauth
165
+ if (providersWaitingOauthMessage[provider])
166
+ typedReject('user-cancelled');
167
+ }, 2000);
168
+ });
169
+ }),
170
+ });
171
+
172
+ export { createWindowOauth2Service };
@@ -0,0 +1 @@
1
+ export * from './createWindowOauth2Service';
@@ -0,0 +1,2 @@
1
+ export * from './Oauth2Service';
2
+ export * from './createWindowOauth2Service';
@@ -0,0 +1,26 @@
1
+ 'use client'
2
+ 'use strict';
3
+
4
+ Object.defineProperty(exports, '__esModule', { value: true });
5
+
6
+ var _tslib = require('../../../../../_virtual/_tslib.cjs');
7
+ var loadAppleId = require('../loadAppleId/loadAppleId.cjs');
8
+
9
+ const connectWithAppleId = (_a) => _tslib.__awaiter(void 0, [_a], void 0, function* ({ clientId, oauthLoginUrl, state, }) {
10
+ yield loadAppleId.loadAppleId();
11
+ // Because the AppleID is loaded from a script tag, there is not type for it
12
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
13
+ // @ts-ignore
14
+ AppleID.auth.init({
15
+ clientId,
16
+ redirectURI: oauthLoginUrl.searchParams.get('redirect_uri'),
17
+ scope: 'name email',
18
+ state,
19
+ usePopup: false,
20
+ });
21
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
22
+ // @ts-ignore
23
+ AppleID.auth.signIn();
24
+ });
25
+
26
+ exports.connectWithAppleId = connectWithAppleId;
@@ -0,0 +1,7 @@
1
+ type ConnectWithAppleIdOptions = {
2
+ clientId: string | undefined;
3
+ oauthLoginUrl: URL;
4
+ state: string;
5
+ };
6
+ export declare const connectWithAppleId: ({ clientId, oauthLoginUrl, state, }: ConnectWithAppleIdOptions) => Promise<void>;
7
+ export {};
@@ -0,0 +1,22 @@
1
+ 'use client'
2
+ import { __awaiter } from '../../../../../_virtual/_tslib.js';
3
+ import { loadAppleId } from '../loadAppleId/loadAppleId.js';
4
+
5
+ const connectWithAppleId = (_a) => __awaiter(void 0, [_a], void 0, function* ({ clientId, oauthLoginUrl, state, }) {
6
+ yield loadAppleId();
7
+ // Because the AppleID is loaded from a script tag, there is not type for it
8
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
9
+ // @ts-ignore
10
+ AppleID.auth.init({
11
+ clientId,
12
+ redirectURI: oauthLoginUrl.searchParams.get('redirect_uri'),
13
+ scope: 'name email',
14
+ state,
15
+ usePopup: false,
16
+ });
17
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
18
+ // @ts-ignore
19
+ AppleID.auth.signIn();
20
+ });
21
+
22
+ export { connectWithAppleId };
@@ -0,0 +1 @@
1
+ export { connectWithAppleId } from './connectWithAppleId';
@@ -0,0 +1 @@
1
+ export { loadAppleId } from './loadAppleId';
@@ -0,0 +1,34 @@
1
+ 'use client'
2
+ 'use strict';
3
+
4
+ Object.defineProperty(exports, '__esModule', { value: true });
5
+
6
+ const appleIdScriptSrc = 'https://appleid.cdn-apple.com/appleauth/static/jsapi/appleid/1/en_US/appleid.auth.js';
7
+ const loadAppleId = () => new Promise((resolve, reject) => {
8
+ const script = document.querySelector('script[data-apple-sdk]');
9
+ if (script) {
10
+ // Script already exists, attach event listeners
11
+ if (script.hasAttribute('data-loaded')) {
12
+ resolve();
13
+ }
14
+ else {
15
+ script.addEventListener('load', () => resolve());
16
+ script.addEventListener('error', () => reject(new Error('Failed to load Apple SDK')));
17
+ }
18
+ }
19
+ else {
20
+ // If the script does not exist, create and add it
21
+ const script = document.createElement('script');
22
+ script.type = 'text/javascript';
23
+ script.src = appleIdScriptSrc;
24
+ script.setAttribute('data-apple-sdk', 'true');
25
+ script.onload = () => {
26
+ script === null || script === void 0 ? void 0 : script.setAttribute('data-loaded', 'true');
27
+ resolve();
28
+ };
29
+ script.onerror = () => reject(new Error('Failed to load Apple SDK'));
30
+ window.document.head.appendChild(script);
31
+ }
32
+ });
33
+
34
+ exports.loadAppleId = loadAppleId;
@@ -0,0 +1 @@
1
+ export declare const loadAppleId: () => Promise<void>;
@@ -0,0 +1,30 @@
1
+ 'use client'
2
+ const appleIdScriptSrc = 'https://appleid.cdn-apple.com/appleauth/static/jsapi/appleid/1/en_US/appleid.auth.js';
3
+ const loadAppleId = () => new Promise((resolve, reject) => {
4
+ const script = document.querySelector('script[data-apple-sdk]');
5
+ if (script) {
6
+ // Script already exists, attach event listeners
7
+ if (script.hasAttribute('data-loaded')) {
8
+ resolve();
9
+ }
10
+ else {
11
+ script.addEventListener('load', () => resolve());
12
+ script.addEventListener('error', () => reject(new Error('Failed to load Apple SDK')));
13
+ }
14
+ }
15
+ else {
16
+ // If the script does not exist, create and add it
17
+ const script = document.createElement('script');
18
+ script.type = 'text/javascript';
19
+ script.src = appleIdScriptSrc;
20
+ script.setAttribute('data-apple-sdk', 'true');
21
+ script.onload = () => {
22
+ script === null || script === void 0 ? void 0 : script.setAttribute('data-loaded', 'true');
23
+ resolve();
24
+ };
25
+ script.onerror = () => reject(new Error('Failed to load Apple SDK'));
26
+ window.document.head.appendChild(script);
27
+ }
28
+ });
29
+
30
+ export { loadAppleId };