@makefully/adaptfully 3.15.0 → 3.16.0
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.
- package/CHANGELOG.md +18 -0
- package/README.md +23 -26
- package/lib/node/packagers/base.js +93 -23
- package/lib/node/packagers/capacitor.js +29 -5
- package/lib/node/packagers/index.js +6 -1
- package/lib/node/publish-credentials.js +1 -0
- package/lib/runtime/auth/social-auth.js +3 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,24 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project are documented in this file.
|
|
4
4
|
|
|
5
|
+
## 3.16.0 — 2026-09-02
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- **Apple-only iOS `social-auth`** — `providers.google: false` + `providers.apple: true` no longer requires `google.webClientId`. On iOS, missing `apple.clientId` defaults to the platform `packageName`; runtime also falls back to `window.gameConfig.packageName`.
|
|
10
|
+
- **Publish gitignore** — ignore `assets/meta/deployments/**/apple/` (`.p12` / `.mobileprovision`).
|
|
11
|
+
|
|
12
|
+
### Docs
|
|
13
|
+
|
|
14
|
+
- Registrations are owned by prebuild HTML markers (do not double-inline at compile time).
|
|
15
|
+
- Capacitor iOS signing is file-based under `apple/` (not Cordova-era `build.json` ios fields).
|
|
16
|
+
|
|
17
|
+
## 3.15.1 — 2026-09-01
|
|
18
|
+
|
|
19
|
+
### Fixed
|
|
20
|
+
|
|
21
|
+
- **Capacitor/Cordova HTML injection** — packager `<meta>` tags (CSP, viewport) are injected into `<head>`; script tags stay in the body `<!-- adaptfully -->` slot. Fixes browsers ignoring CSP delivered outside `<head>`.
|
|
22
|
+
|
|
5
23
|
## 3.15.0 — 2026-08-24
|
|
6
24
|
|
|
7
25
|
### Added
|
package/README.md
CHANGED
|
@@ -63,7 +63,7 @@ A **platform** (`config.platforms.<key>`) describes *how* to build — registrat
|
|
|
63
63
|
|
|
64
64
|
> **Back-compat:** projects with no `assets/meta/deployments/` directory keep the legacy behavior — the entire `assets/meta/` tree (including `assets/meta/publish/`) is shipped as `meta/`, and a single set of credentials is read from `meta/publish/`.
|
|
65
65
|
|
|
66
|
-
Place `<!-- adaptfully -->` / `<!-- /adaptfully -->` markers in your HTML templates where registrations should be injected (typically between split bundle scripts, before `account.js` runs).
|
|
66
|
+
Place `<!-- adaptfully -->` / `<!-- /adaptfully -->` markers in your HTML templates where registrations should be injected (typically between split bundle scripts, before `account.js` runs). **Do not also inline Adaptfully auth scripts at game compile time** — prebuild/release owns the marker block for each platform.
|
|
67
67
|
|
|
68
68
|
```javascript
|
|
69
69
|
// Injected into deploy/index.html for the target platform (before game code):
|
|
@@ -224,7 +224,11 @@ The renderer `steam-auth` plugin reads the Steam ID from that bridge. When Steam
|
|
|
224
224
|
|
|
225
225
|
When `social-auth` is registered on a **`capacitor`** platform, Adaptfully prebuild writes **`social-login-config.js`** (`window.__ADAPTFULLY_SOCIAL_LOGIN__`) from `platforms.<name>.socialLogin`. Wrapfully installs [`@capgo/capacitor-social-login`](https://github.com/Cap-go/capacitor-social-login) and syncs it into the native project (same role as `steamworks.js` for Electron).
|
|
226
226
|
|
|
227
|
-
The runtime plugin calls Capgo `SocialLogin.initialize` / `login` / `logout` / `isLoggedIn`. Default provider is `google` on Android and `apple` on iOS when both are enabled (override with `socialLogin.defaultProvider`).
|
|
227
|
+
The runtime plugin calls Capgo `SocialLogin.initialize` / `login` / `logout` / `isLoggedIn`. Default provider is `google` on Android and `apple` on iOS when both are enabled (override with `socialLogin.defaultProvider`).
|
|
228
|
+
|
|
229
|
+
**Apple-only iOS** (`providers.google: false`, `providers.apple: true`) is supported — Google `webClientId` is not required. On iOS, if `apple.clientId` is omitted, Adaptfully defaults it to the platform `packageName` (Capgo uses this as a plugin label on native iOS, not an Apple Services ID). On Android, Apple Sign-In still requires `apple.clientId`. At runtime, an empty Apple `clientId` also falls back to `window.gameConfig.packageName`.
|
|
230
|
+
|
|
231
|
+
Optional config keys:
|
|
228
232
|
|
|
229
233
|
| Key | Default | Purpose |
|
|
230
234
|
|-----|---------|---------|
|
|
@@ -604,29 +608,21 @@ The file looks like:
|
|
|
604
608
|
|
|
605
609
|
#### Apple (`ios`, `ios-dev`, `ios-sim`, `mac`)
|
|
606
610
|
|
|
607
|
-
|
|
611
|
+
**Capacitor iOS** signing is file-based under the deployment folder (not the Cordova-style `build.json` `ios.*` identity fields):
|
|
608
612
|
|
|
609
|
-
```
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
"packageType": "development",
|
|
617
|
-
"automaticProvisioning": false
|
|
618
|
-
},
|
|
619
|
-
"release": {
|
|
620
|
-
"codeSignIdentity": "iPhone Distribution",
|
|
621
|
-
"provisioningProfile": "(your distribution provisioning profile id)",
|
|
622
|
-
"developmentTeam": "(your team id)",
|
|
623
|
-
"packageType": "app-store",
|
|
624
|
-
"automaticProvisioning": false
|
|
625
|
-
}
|
|
626
|
-
}
|
|
627
|
-
}
|
|
613
|
+
```
|
|
614
|
+
assets/meta/deployments/<deployment>/
|
|
615
|
+
apple.json
|
|
616
|
+
apple/distribution.p12 # release
|
|
617
|
+
apple/app-store.mobileprovision # release
|
|
618
|
+
apple/development.p12 # ios-dev device
|
|
619
|
+
apple/development.mobileprovision # ios-dev device
|
|
628
620
|
```
|
|
629
621
|
|
|
622
|
+
The `.p12` passphrase must match `MAC_KEYCHAIN_PASSWORD` on the Mac Wrapfully host. Team ID and profile UUID are read from the `.mobileprovision`. Enable **Sign in with Apple** on the App ID when using Capgo Apple auth.
|
|
623
|
+
|
|
624
|
+
Optional `build.json` may still be present for tooling compatibility; Capacitor does not require its `ios.*` code-sign fields.
|
|
625
|
+
|
|
630
626
|
To deploy to the App Store, include `assets/meta/deployments/<deployment>/apple.json`. The easiest path is:
|
|
631
627
|
|
|
632
628
|
```bash
|
|
@@ -638,13 +634,14 @@ The file looks like:
|
|
|
638
634
|
|
|
639
635
|
```json
|
|
640
636
|
{
|
|
641
|
-
"category": "
|
|
642
|
-
"identity": "(your team
|
|
643
|
-
"username": "(
|
|
644
|
-
"password": "(
|
|
637
|
+
"category": "public.app-category.games",
|
|
638
|
+
"identity": "(your team id)",
|
|
639
|
+
"username": "(Apple ID email)",
|
|
640
|
+
"password": "(app-specific password)"
|
|
645
641
|
}
|
|
646
642
|
```
|
|
647
643
|
|
|
644
|
+
iOS IPA upload uses `username` + `password` via `xcrun altool --upload-app`. `category` / `identity` matter more for macOS Electron signing/notarization.
|
|
648
645
|
#### Cordova
|
|
649
646
|
|
|
650
647
|
Set `packager: "cordova"` on an `android` or `ios` platform to use Cordova instead of Capacitor. Requires the Android and Apple package requirements above.
|
|
@@ -11,6 +11,8 @@ export const VALID_PACKAGERS = ['web', 'electron', 'cordova', 'capacitor'];
|
|
|
11
11
|
|
|
12
12
|
const PACKAGER_MARKER = '<!-- adaptfully-packager -->';
|
|
13
13
|
const PACKAGER_END_MARKER = '<!-- /adaptfully-packager -->';
|
|
14
|
+
const HEAD_PACKAGER_MARKER = '<!-- adaptfully-packager-head -->';
|
|
15
|
+
const HEAD_PACKAGER_END_MARKER = '<!-- /adaptfully-packager-head -->';
|
|
14
16
|
|
|
15
17
|
/**
|
|
16
18
|
* @typedef {Object} PackagerOptions
|
|
@@ -58,21 +60,64 @@ function writeGameConfig(dest, platformKey, pkg, log) {
|
|
|
58
60
|
|
|
59
61
|
/**
|
|
60
62
|
* @param {string} html
|
|
63
|
+
* @param {string} marker
|
|
64
|
+
* @param {string} endMarker
|
|
61
65
|
* @param {string} injection
|
|
62
66
|
*/
|
|
63
|
-
function
|
|
64
|
-
if (!injection) {
|
|
65
|
-
return html;
|
|
66
|
-
}
|
|
67
|
-
|
|
67
|
+
function replaceMarkedBlock(html, marker, endMarker, injection) {
|
|
68
68
|
const markerPattern = new RegExp(
|
|
69
|
-
`${escapeRegExp(
|
|
69
|
+
`${escapeRegExp(marker)}[\\s\\S]*?${escapeRegExp(endMarker)}\\n?`,
|
|
70
70
|
);
|
|
71
71
|
|
|
72
72
|
if (markerPattern.test(html)) {
|
|
73
73
|
return html.replace(markerPattern, injection);
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
+
if (html.includes(marker)) {
|
|
77
|
+
return html.replace(marker, `${injection}${marker}`);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return html;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* @param {string} html
|
|
85
|
+
* @param {string} injection
|
|
86
|
+
*/
|
|
87
|
+
function injectHeadPackagerExtras(html, injection) {
|
|
88
|
+
if (!injection) {
|
|
89
|
+
return html;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
let updated = replaceMarkedBlock(html, HEAD_PACKAGER_MARKER, HEAD_PACKAGER_END_MARKER, injection);
|
|
93
|
+
|
|
94
|
+
if (updated === html && html.includes('</head>')) {
|
|
95
|
+
updated = html.replace('</head>', `${injection}</head>`);
|
|
96
|
+
} else if (updated === html) {
|
|
97
|
+
throw new Error(
|
|
98
|
+
'Cannot inject packager head extras: HTML needs '
|
|
99
|
+
+ `${HEAD_PACKAGER_MARKER}…${HEAD_PACKAGER_END_MARKER} or </head>`,
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return updated;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* @param {string} html
|
|
108
|
+
* @param {string} injection
|
|
109
|
+
*/
|
|
110
|
+
function injectBodyPackagerExtras(html, injection) {
|
|
111
|
+
if (!injection) {
|
|
112
|
+
return html;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
let updated = replaceMarkedBlock(html, PACKAGER_MARKER, PACKAGER_END_MARKER, injection);
|
|
116
|
+
|
|
117
|
+
if (updated !== html) {
|
|
118
|
+
return updated;
|
|
119
|
+
}
|
|
120
|
+
|
|
76
121
|
if (html.includes(PACKAGER_MARKER)) {
|
|
77
122
|
return html.replace(PACKAGER_MARKER, `${injection}${PACKAGER_MARKER}`);
|
|
78
123
|
}
|
|
@@ -85,17 +130,36 @@ function injectPackagerExtras(html, injection) {
|
|
|
85
130
|
return html.replace('<!-- scripts -->', `${injection}<!-- scripts -->`);
|
|
86
131
|
}
|
|
87
132
|
|
|
88
|
-
if (html.includes('</
|
|
89
|
-
return html.replace('</
|
|
133
|
+
if (html.includes('</body>')) {
|
|
134
|
+
return html.replace('</body>', `${injection}</body>`);
|
|
90
135
|
}
|
|
91
136
|
|
|
92
137
|
throw new Error(
|
|
93
|
-
'Cannot inject packager extras: HTML needs '
|
|
138
|
+
'Cannot inject packager body extras: HTML needs '
|
|
94
139
|
+ '<!-- adaptfully-packager -->…<!-- /adaptfully-packager -->, '
|
|
95
|
-
+ '<!-- adaptfully -->, <!-- scripts -->, or </
|
|
140
|
+
+ '<!-- adaptfully -->, <!-- scripts -->, or </body>',
|
|
96
141
|
);
|
|
97
142
|
}
|
|
98
143
|
|
|
144
|
+
/**
|
|
145
|
+
* @param {string} html
|
|
146
|
+
* @param {{ head?: string, body?: string }} injection
|
|
147
|
+
*/
|
|
148
|
+
function injectPackagerExtras(html, injection) {
|
|
149
|
+
if (!injection?.head && !injection?.body) {
|
|
150
|
+
return html;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
let updated = html;
|
|
154
|
+
if (injection.head) {
|
|
155
|
+
updated = injectHeadPackagerExtras(updated, injection.head);
|
|
156
|
+
}
|
|
157
|
+
if (injection.body) {
|
|
158
|
+
updated = injectBodyPackagerExtras(updated, injection.body);
|
|
159
|
+
}
|
|
160
|
+
return updated;
|
|
161
|
+
}
|
|
162
|
+
|
|
99
163
|
function escapeRegExp(value) {
|
|
100
164
|
return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
101
165
|
}
|
|
@@ -243,22 +307,28 @@ export class Packager {
|
|
|
243
307
|
/**
|
|
244
308
|
* @param {string[]} headExtras
|
|
245
309
|
* @param {string[]} bodyScripts
|
|
246
|
-
* @returns {string}
|
|
310
|
+
* @returns {{ head: string, body: string }}
|
|
247
311
|
*/
|
|
248
312
|
formatHtmlInjection(headExtras, bodyScripts) {
|
|
249
|
-
|
|
250
|
-
|
|
313
|
+
let head = '';
|
|
314
|
+
if (headExtras.length > 0) {
|
|
315
|
+
head = `${HEAD_PACKAGER_MARKER}\n`;
|
|
316
|
+
for (const extra of headExtras) {
|
|
317
|
+
head += `${extra}\n`;
|
|
318
|
+
}
|
|
319
|
+
head += `${HEAD_PACKAGER_END_MARKER}\n`;
|
|
251
320
|
}
|
|
252
321
|
|
|
253
|
-
let
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
322
|
+
let body = '';
|
|
323
|
+
if (bodyScripts.length > 0) {
|
|
324
|
+
body = `${PACKAGER_MARKER}\n`;
|
|
325
|
+
for (const script of bodyScripts) {
|
|
326
|
+
body += `${script}\n`;
|
|
327
|
+
}
|
|
328
|
+
body += `${PACKAGER_END_MARKER}\n`;
|
|
259
329
|
}
|
|
260
|
-
|
|
261
|
-
return
|
|
330
|
+
|
|
331
|
+
return { head, body };
|
|
262
332
|
}
|
|
263
333
|
|
|
264
334
|
/** @param {string} dest */
|
|
@@ -268,7 +338,7 @@ export class Packager {
|
|
|
268
338
|
}
|
|
269
339
|
}
|
|
270
340
|
|
|
271
|
-
/** @returns {string} */
|
|
341
|
+
/** @returns {{ head: string, body: string }} */
|
|
272
342
|
buildHtmlInjection() {
|
|
273
343
|
const bodyScripts = [];
|
|
274
344
|
if (this.needsGameConfig()) {
|
|
@@ -283,7 +353,7 @@ export class Packager {
|
|
|
283
353
|
*/
|
|
284
354
|
applyHtmlExtras(dest, htmlPaths) {
|
|
285
355
|
const injection = this.buildHtmlInjection();
|
|
286
|
-
if (!injection) {
|
|
356
|
+
if (!injection.head && !injection.body) {
|
|
287
357
|
return;
|
|
288
358
|
}
|
|
289
359
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { Packager } from './base.js';
|
|
4
|
+
import { resolvePlatformConfig } from '../platform-config.js';
|
|
4
5
|
|
|
5
6
|
const CAPACITOR_CSP = '<meta http-equiv="Content-Security-Policy" content="default-src * \'self\' data: blob: \'unsafe-inline\' \'unsafe-eval\'; style-src * \'self\' \'unsafe-inline\'; script-src * \'self\' \'unsafe-inline\' \'unsafe-eval\'; connect-src *; img-src * data: blob:; media-src * data: blob:; frame-src *;" />';
|
|
6
7
|
|
|
@@ -17,24 +18,40 @@ export function resolvePlatformSocialLogin(platformKey, pkg) {
|
|
|
17
18
|
return pkg.config?.platforms?.[platformKey]?.socialLogin;
|
|
18
19
|
}
|
|
19
20
|
|
|
21
|
+
/**
|
|
22
|
+
* @param {string} platformKey
|
|
23
|
+
*/
|
|
24
|
+
function isIosPlatformKey(platformKey) {
|
|
25
|
+
return platformKey === 'ios'
|
|
26
|
+
|| platformKey === 'ios-dev'
|
|
27
|
+
|| platformKey === 'ios-sim'
|
|
28
|
+
|| String(platformKey).startsWith('ios');
|
|
29
|
+
}
|
|
30
|
+
|
|
20
31
|
/**
|
|
21
32
|
* @param {object} socialLogin
|
|
22
33
|
* @param {string} platformKey
|
|
34
|
+
* @param {{ packageName?: string }} [options]
|
|
23
35
|
*/
|
|
24
|
-
function normalizeSocialLoginConfig(socialLogin = {}, platformKey) {
|
|
36
|
+
export function normalizeSocialLoginConfig(socialLogin = {}, platformKey, options = {}) {
|
|
25
37
|
const providers = socialLogin.providers ?? { google: true, apple: true };
|
|
26
38
|
const googleEnabled = providers.google !== false;
|
|
27
39
|
const appleEnabled = providers.apple !== false;
|
|
28
40
|
|
|
29
41
|
let defaultProvider = socialLogin.defaultProvider;
|
|
30
42
|
if (!defaultProvider) {
|
|
31
|
-
if (platformKey
|
|
43
|
+
if (isIosPlatformKey(platformKey)) {
|
|
32
44
|
defaultProvider = appleEnabled ? 'apple' : 'google';
|
|
33
45
|
} else {
|
|
34
46
|
defaultProvider = googleEnabled ? 'google' : 'apple';
|
|
35
47
|
}
|
|
36
48
|
}
|
|
37
49
|
|
|
50
|
+
const apple = { ...(socialLogin.apple ?? {}) };
|
|
51
|
+
if (appleEnabled && !apple.clientId && options.packageName && isIosPlatformKey(platformKey)) {
|
|
52
|
+
apple.clientId = options.packageName;
|
|
53
|
+
}
|
|
54
|
+
|
|
38
55
|
return {
|
|
39
56
|
providers: {
|
|
40
57
|
google: googleEnabled,
|
|
@@ -43,7 +60,7 @@ function normalizeSocialLoginConfig(socialLogin = {}, platformKey) {
|
|
|
43
60
|
twitter: providers.twitter === true,
|
|
44
61
|
},
|
|
45
62
|
google: socialLogin.google ?? {},
|
|
46
|
-
apple
|
|
63
|
+
apple,
|
|
47
64
|
defaultProvider,
|
|
48
65
|
platform: platformKey,
|
|
49
66
|
};
|
|
@@ -52,7 +69,7 @@ function normalizeSocialLoginConfig(socialLogin = {}, platformKey) {
|
|
|
52
69
|
/**
|
|
53
70
|
* @param {object} config
|
|
54
71
|
*/
|
|
55
|
-
function validateSocialLoginConfig(config) {
|
|
72
|
+
export function validateSocialLoginConfig(config) {
|
|
56
73
|
const { providers, google, apple } = config;
|
|
57
74
|
|
|
58
75
|
if (!providers.google && !providers.apple) {
|
|
@@ -83,6 +100,10 @@ export class CapacitorPackager extends Packager {
|
|
|
83
100
|
/** @type {string[]} */
|
|
84
101
|
static defaultPlatforms = ['ios', 'android'];
|
|
85
102
|
|
|
103
|
+
#socialLoginPackageName() {
|
|
104
|
+
return resolvePlatformConfig(this.pkg, this.platformKey).packageName;
|
|
105
|
+
}
|
|
106
|
+
|
|
86
107
|
validate() {
|
|
87
108
|
super.validate();
|
|
88
109
|
|
|
@@ -98,6 +119,7 @@ export class CapacitorPackager extends Packager {
|
|
|
98
119
|
const config = normalizeSocialLoginConfig(
|
|
99
120
|
socialLogin ?? this.pkg.config?.socialLogin,
|
|
100
121
|
this.platformKey ?? 'android',
|
|
122
|
+
{ packageName: this.#socialLoginPackageName() },
|
|
101
123
|
);
|
|
102
124
|
validateSocialLoginConfig(config);
|
|
103
125
|
}
|
|
@@ -113,7 +135,9 @@ export class CapacitorPackager extends Packager {
|
|
|
113
135
|
const socialLogin = resolvePlatformSocialLogin(this.platformKey, this.pkg)
|
|
114
136
|
?? this.pkg.config?.socialLogin
|
|
115
137
|
?? {};
|
|
116
|
-
const config = normalizeSocialLoginConfig(socialLogin, this.platformKey
|
|
138
|
+
const config = normalizeSocialLoginConfig(socialLogin, this.platformKey, {
|
|
139
|
+
packageName: this.#socialLoginPackageName(),
|
|
140
|
+
});
|
|
117
141
|
const content = `window.__ADAPTFULLY_SOCIAL_LOGIN__ = ${JSON.stringify(config, null, 4)};\n`;
|
|
118
142
|
fs.writeFileSync(path.join(dest, 'social-login-config.js'), content);
|
|
119
143
|
this.log('adaptfully: write social-login-config.js (social-auth)');
|
|
@@ -4,7 +4,12 @@ import { ElectronPackager } from './electron.js';
|
|
|
4
4
|
import { Packager, VALID_PACKAGERS } from './base.js';
|
|
5
5
|
import { WebPackager } from './web.js';
|
|
6
6
|
|
|
7
|
-
export {
|
|
7
|
+
export {
|
|
8
|
+
CapacitorPackager,
|
|
9
|
+
normalizeSocialLoginConfig,
|
|
10
|
+
resolvePlatformSocialLogin,
|
|
11
|
+
validateSocialLoginConfig,
|
|
12
|
+
} from './capacitor.js';
|
|
8
13
|
export { CordovaPackager } from './cordova.js';
|
|
9
14
|
export {
|
|
10
15
|
ElectronPackager,
|
|
@@ -12,6 +12,7 @@ export const PUBLISH_CREDENTIAL_GITIGNORE_PATTERNS = [
|
|
|
12
12
|
'assets/meta/deployments/**/apple.json',
|
|
13
13
|
'assets/meta/deployments/**/ms.json',
|
|
14
14
|
'assets/meta/deployments/**/android/',
|
|
15
|
+
'assets/meta/deployments/**/apple/',
|
|
15
16
|
'assets/meta/deployments/**/ms/',
|
|
16
17
|
];
|
|
17
18
|
|
|
@@ -119,7 +119,9 @@
|
|
|
119
119
|
|
|
120
120
|
if (config.providers?.apple !== false) {
|
|
121
121
|
options.apple = {
|
|
122
|
-
clientId: config.apple?.clientId
|
|
122
|
+
clientId: config.apple?.clientId
|
|
123
|
+
|| window.gameConfig?.packageName
|
|
124
|
+
|| '',
|
|
123
125
|
redirectUrl: config.apple?.redirectUrl,
|
|
124
126
|
useProperTokenExchange: config.apple?.useProperTokenExchange !== false,
|
|
125
127
|
useBroadcastChannel: config.apple?.useBroadcastChannel !== false,
|