@makefully/adaptfully 3.3.0 → 3.5.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 CHANGED
@@ -2,6 +2,20 @@
2
2
 
3
3
  All notable changes to this project are documented in this file.
4
4
 
5
+ ## 3.5.0 — 2026-06-27
6
+
7
+ ### Added
8
+
9
+ - **`adaptfully steam-auth`** — installs steamcmd if missing, runs an interactive login, and writes `assets/meta/publish/steam.json` with `configVdf` and optional `ssfn` sentry data for Steam Guard accounts.
10
+ - Exported helpers: `runSteamAuth`, `buildSteamPublishJson`, `collectSteamAuthFiles`, `ensureSteamcmd`.
11
+
12
+ ## 3.4.0 — 2026-06-25
13
+
14
+ ### Changed
15
+
16
+ - Electron **`main.js`** allows same-app `file://` navigation while still opening external http(s) links in the system browser.
17
+ - Steam builds (`steam-auth`) set renderer **`sandbox: false`** so the steamworks preload bridge can reach the main process; non-Steam Electron builds keep `sandbox: true`.
18
+
5
19
  ## 3.3.0 — 2026-06-23
6
20
 
7
21
  ### Added
package/README.md CHANGED
@@ -24,6 +24,7 @@ Games register platform services before load and retrieve them in-game. Adaptful
24
24
  adaptfully prebuild web # deploy/ → output/web-prebuild/
25
25
  adaptfully build steam # prebuild + zip and send to Wrapfully
26
26
  adaptfully deploy steam # build + platform release when credentials are present
27
+ adaptfully steam-auth # one-time: log in with steamcmd → assets/meta/publish/steam.json
27
28
  ```
28
29
 
29
30
  | Stage | What it does |
@@ -31,6 +32,7 @@ adaptfully deploy steam # build + platform release when credentials are pres
31
32
  | `prebuild` | Copy `deploy/` to `output/<platform>-prebuild/` and inject registrations into `config.htmlInjections` |
32
33
  | `build` | Prebuild, then POST the result to Wrapfully |
33
34
  | `deploy` | Build, then release to the target platform (Steam upload, webapp SFTP, etc. via Wrapfully when credentials are in `assets/meta/publish/`) |
35
+ | `steam-auth` | One-time local setup: install steamcmd, interactive login, write `assets/meta/publish/steam.json` |
34
36
 
35
37
  `wrapfully-deploy` is a compatibility alias for `adaptfully deploy` when invoked with a Wrapfully builder name (`steam`, `win`, `android`, etc.).
36
38
 
@@ -199,6 +201,7 @@ Run from your project root:
199
201
 
200
202
  ```bash
201
203
  npx adaptfully <prebuild|build|deploy> <platform> [server] [mode]
204
+ npx adaptfully steam-auth [--username U] [--password P] [--output path]
202
205
  ```
203
206
 
204
207
  | Stage | Description |
@@ -375,7 +378,7 @@ Standard npm fields (`name`, `version`, `description`) are used directly. Add a
375
378
  | `publisherWebsite` | Cordova, web | Company URL |
376
379
  | `publisherEmailAddress` | Cordova | Contact email |
377
380
  | `scope` | Web/PWA | Base URL scope for the web app |
378
- | `themeColor` | Cordova, UWP, web | Loading screen / theme color |
381
+ | `themeColor` | Cordova, Electron, UWP, web | Loading screen / theme color |
379
382
  | `twitterId` | Web | Twitter handle for meta tags |
380
383
  | `steamId` | Steam | Steam app ID |
381
384
  | `deployFolder` | Client | Neutral deploy directory staged before prebuild (default: `deploy`) |
@@ -522,15 +525,22 @@ Requires the Android and Apple package requirements above.
522
525
 
523
526
  `steam-dev` builds debug Electron binaries for Windows, Mac, and Linux without uploading to Steam. No `steam.json` credentials are required.
524
527
 
525
- For release uploads, include `assets/meta/publish/steam.json`:
528
+ For release uploads, run **`adaptfully steam-auth`** once on your machine. It installs steamcmd if needed, logs you in interactively (enter a Steam Guard code if prompted), and writes `assets/meta/publish/steam.json`:
526
529
 
527
530
  ```json
528
531
  {
529
- "username": "(your username)",
530
- "password": "(your password)"
532
+ "username": "(your Steam build account)",
533
+ "password": "(your password)",
534
+ "configVdf": "(base64 login token from steamcmd)",
535
+ "sentryFileName": "(only when Steam Guard is enabled)",
536
+ "sentryFile": "(base64 ssfn file — only when Steam Guard is enabled)"
531
537
  }
532
538
  ```
533
539
 
540
+ Accounts **without** Steam Guard only need `username`, `password`, and `configVdf`. Accounts **with** Steam Guard also include the `ssfn` sentry file so the Wrapfully server can log in without a live 2FA prompt.
541
+
542
+ Re-run `adaptfully steam-auth` if Steam invalidates the token (new machine, password change, or expired guard).
543
+
534
544
  Also set `steamId` in your `config` block.
535
545
 
536
546
  Steam builds can run on either the Windows or Mac server. The server that receives the request builds its own platforms and requests the rest from the other server (Windows builds `win` and requests `mac`/`linux`; Mac builds `mac`/`linux` and requests `win`). Install the Steamworks SDK ContentBuilder on any server that will upload to Steam.
package/lib/node/index.js CHANGED
@@ -34,3 +34,12 @@ export {
34
34
  resolveRegistrationAssets,
35
35
  } from './registrations.js';
36
36
  export { printBuildReport } from './report.js';
37
+ export {
38
+ buildSteamPublishJson,
39
+ collectSteamAuthFiles,
40
+ defaultSteamPublishPath,
41
+ defaultSteamcmdCacheDir,
42
+ ensureSteamcmd,
43
+ runSteamAuth,
44
+ steamAuthFromCli,
45
+ } from './steam-auth.js';
@@ -24,16 +24,22 @@ const
24
24
 
25
25
  const ELECTRON_MAIN_BODY = `
26
26
  /**
27
- * Opens external URLs in the system browser and blocks in-app navigation.
27
+ * Opens http(s) links in the system browser; allows same-app file:// navigation.
28
28
  * @param {Electron.BrowserWindow} win
29
29
  */
30
30
  function attachExternalLinkHandlers(win) {
31
31
  win.webContents.setWindowOpenHandler(({url}) => {
32
+ if (url.startsWith('file:')) {
33
+ return {action: 'deny'};
34
+ }
32
35
  shell.openExternal(url);
33
36
  return {action: 'deny'};
34
37
  });
35
38
 
36
39
  win.webContents.on('will-navigate', (event, url) => {
40
+ if (url.startsWith('file:')) {
41
+ return;
42
+ }
37
43
  event.preventDefault();
38
44
  shell.openExternal(url);
39
45
  });
@@ -63,7 +69,7 @@ function createWindow () {
63
69
  };
64
70
  })(),
65
71
  win = new BrowserWindow({
66
- backgroundColor: '#E4378E',
72
+ backgroundColor: __THEME_COLOR__,
67
73
  width: lastState.bounds.width,
68
74
  height: lastState.bounds.height,
69
75
  minWidth: 200,
@@ -72,7 +78,7 @@ function createWindow () {
72
78
  devTools: debugMode,
73
79
  nodeIntegration: false,
74
80
  contextIsolation: true,
75
- sandbox: true`;
81
+ sandbox: __SANDBOX__`;
76
82
 
77
83
  const ELECTRON_MAIN_TAIL = `
78
84
  },
@@ -153,11 +159,16 @@ if (steamClient) {
153
159
 
154
160
  /**
155
161
  * @param {boolean} withSteam
162
+ * @param {string} [themeColor]
156
163
  */
157
- export function buildElectronMain(withSteam) {
164
+ export function buildElectronMain(withSteam, themeColor) {
158
165
  const steamInit = withSteam ? STEAM_INIT : '';
159
166
  const steamPreload = withSteam ? STEAM_PRELOAD : '';
160
- return ELECTRON_MAIN_HEAD + steamInit + ELECTRON_MAIN_BODY + steamPreload + ELECTRON_MAIN_TAIL;
167
+ const sandbox = withSteam ? 'false' : 'true';
168
+ const mainBody = ELECTRON_MAIN_BODY
169
+ .replace('__SANDBOX__', sandbox)
170
+ .replace('__THEME_COLOR__', String(JSON.stringify(themeColor)));
171
+ return ELECTRON_MAIN_HEAD + steamInit + mainBody + steamPreload + ELECTRON_MAIN_TAIL;
161
172
  }
162
173
 
163
174
  /**
@@ -198,7 +209,7 @@ export class ElectronPackager extends Packager {
198
209
  /** @param {string} dest */
199
210
  writeElectronMain(dest) {
200
211
  const withSteam = this.usesPlugin('steam-auth');
201
- const mainContent = buildElectronMain(withSteam);
212
+ const mainContent = buildElectronMain(withSteam, this.pkg.config?.themeColor);
202
213
 
203
214
  if (withSteam) {
204
215
  fs.writeFileSync(
@@ -2,6 +2,7 @@ import { loadProjectConfig, resolveServerUrl } from './config.js';
2
2
  import { send } from './deploy.js';
3
3
  import { prebuildPlatform } from './prebuild.js';
4
4
  import { resolveBuilderForPlatform } from './registrations.js';
5
+ import { steamAuthFromCli } from './steam-auth.js';
5
6
 
6
7
  /** @typedef {'prebuild' | 'build' | 'deploy'} AdaptfullyStage */
7
8
 
@@ -50,17 +51,29 @@ export async function runAdaptfullyStage(stage, platformKey, options) {
50
51
  * @param {string[]} [argv=process.argv]
51
52
  */
52
53
  export async function adaptfullyFromCli(argv = process.argv) {
53
- const stage = argv[2];
54
+ const command = argv[2];
55
+
56
+ if (command === 'steam-auth') {
57
+ return steamAuthFromCli(argv);
58
+ }
59
+
60
+ const stage = command;
54
61
  const platformKey = argv[3];
55
62
  const cliServer = argv[4];
56
63
  const mode = argv[5] ?? 'extract';
57
64
 
58
65
  if (!stage || !platformKey) {
59
66
  throw new Error(
60
- 'Usage: adaptfully <prebuild|build|deploy> <platform> [server] [mode]\n'
67
+ 'Usage:\n'
68
+ + ' adaptfully <prebuild|build|deploy> <platform> [server] [mode]\n'
69
+ + ' adaptfully steam-auth [--username U] [--password P] [--output path]\n'
70
+ + '\n'
71
+ + 'Stages:\n'
61
72
  + ' prebuild Copy deploy/ and apply platform registrations → output/<platform>-prebuild/\n'
62
73
  + ' build prebuild + zip and send to Wrapfully\n'
63
- + ' deploy build + platform release when credentials are present (via Wrapfully)',
74
+ + ' deploy build + platform release when credentials are present (via Wrapfully)\n'
75
+ + '\n'
76
+ + ' steam-auth Install steamcmd if needed, log in interactively, write assets/meta/publish/steam.json',
64
77
  );
65
78
  }
66
79
 
@@ -0,0 +1,343 @@
1
+ import { spawn } from 'node:child_process';
2
+ import { createWriteStream } from 'node:fs';
3
+ import fsp from 'node:fs/promises';
4
+ import os from 'node:os';
5
+ import path from 'node:path';
6
+ import { pipeline } from 'node:stream/promises';
7
+ import readline from 'node:readline/promises';
8
+ import { stdin as input, stdout as output } from 'node:process';
9
+
10
+ const STEAMCMD_INSTALL = {
11
+ win32: {
12
+ url: 'https://steamcdn-a.akamaihd.net/client/installer/steamcmd.zip',
13
+ archive: 'zip',
14
+ },
15
+ linux: {
16
+ url: 'https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz',
17
+ archive: 'tar.gz',
18
+ },
19
+ darwin: {
20
+ url: 'https://steamcdn-a.akamaihd.net/client/installer/steamcmd_osx.tar.gz',
21
+ archive: 'tar.gz',
22
+ },
23
+ };
24
+
25
+ /**
26
+ * @param {string} [projectRoot]
27
+ */
28
+ export function defaultSteamPublishPath(projectRoot = '.') {
29
+ return path.resolve(projectRoot, 'assets', 'meta', 'publish', 'steam.json');
30
+ }
31
+
32
+ /**
33
+ * @param {string} [cacheRoot]
34
+ */
35
+ export function defaultSteamcmdCacheDir(cacheRoot) {
36
+ const root = cacheRoot ?? path.join(os.homedir(), '.adaptfully', 'steamcmd');
37
+
38
+ return path.join(root, process.platform);
39
+ }
40
+
41
+ /**
42
+ * @param {{ username: string, password: string, configVdfBuffer?: Buffer, sentryFileName?: string, sentryFileBuffer?: Buffer }} auth
43
+ */
44
+ export function buildSteamPublishJson(auth) {
45
+ /** @type {Record<string, string>} */
46
+ const result = {
47
+ username: auth.username,
48
+ password: auth.password,
49
+ };
50
+
51
+ if (auth.configVdfBuffer) {
52
+ result.configVdf = auth.configVdfBuffer.toString('base64');
53
+ }
54
+
55
+ if (auth.sentryFileName && auth.sentryFileBuffer) {
56
+ result.sentryFileName = auth.sentryFileName;
57
+ result.sentryFile = auth.sentryFileBuffer.toString('base64');
58
+ }
59
+
60
+ return result;
61
+ }
62
+
63
+ /**
64
+ * @param {string} steamcmdDir
65
+ */
66
+ export async function collectSteamAuthFiles(steamcmdDir) {
67
+ const configPath = path.join(steamcmdDir, 'config', 'config.vdf');
68
+ let configVdfBuffer;
69
+
70
+ try {
71
+ configVdfBuffer = await fsp.readFile(configPath);
72
+ } catch {
73
+ throw new Error(
74
+ `Steam login did not produce config/config.vdf at "${configPath}". `
75
+ + 'Check your username, password, and Steam Guard code.',
76
+ );
77
+ }
78
+
79
+ const entries = await fsp.readdir(steamcmdDir);
80
+ const sentryFileName = entries.find((name) => name.startsWith('ssfn'));
81
+ let sentryFileBuffer;
82
+
83
+ if (sentryFileName) {
84
+ sentryFileBuffer = await fsp.readFile(path.join(steamcmdDir, sentryFileName));
85
+ }
86
+
87
+ return { configVdfBuffer, sentryFileName, sentryFileBuffer };
88
+ }
89
+
90
+ /**
91
+ * @param {string} command
92
+ * @param {string[]} args
93
+ */
94
+ function runCommand(command, args) {
95
+ return new Promise((resolve, reject) => {
96
+ const child = spawn(command, args, { stdio: 'inherit' });
97
+ child.on('error', reject);
98
+ child.on('close', (code) => {
99
+ if (code === 0) {
100
+ resolve(code);
101
+ } else {
102
+ reject(new Error(`"${command}" exited with code ${code}`));
103
+ }
104
+ });
105
+ });
106
+ }
107
+
108
+ /**
109
+ * @param {string} url
110
+ * @param {string} dest
111
+ */
112
+ async function downloadFile(url, dest) {
113
+ const response = await fetch(url);
114
+
115
+ if (!response.ok || !response.body) {
116
+ throw new Error(`Failed to download ${url}: HTTP ${response.status}`);
117
+ }
118
+
119
+ await pipeline(response.body, createWriteStream(dest));
120
+ }
121
+
122
+ /**
123
+ * @param {string} archivePath
124
+ * @param {string} destDir
125
+ * @param {'zip' | 'tar.gz'} archiveType
126
+ */
127
+ async function extractArchive(archivePath, destDir, archiveType) {
128
+ await fsp.mkdir(destDir, { recursive: true });
129
+
130
+ if (archiveType === 'tar.gz') {
131
+ await runCommand('tar', ['-xzf', archivePath, '-C', destDir]);
132
+ return;
133
+ }
134
+
135
+ if (process.platform === 'win32') {
136
+ const escapedArchive = archivePath.replace(/'/g, "''");
137
+ const escapedDest = destDir.replace(/'/g, "''");
138
+
139
+ await runCommand('powershell', [
140
+ '-NoProfile',
141
+ '-Command',
142
+ `Expand-Archive -LiteralPath '${escapedArchive}' -DestinationPath '${escapedDest}' -Force`,
143
+ ]);
144
+ return;
145
+ }
146
+
147
+ await runCommand('tar', ['-xf', archivePath, '-C', destDir]);
148
+ }
149
+
150
+ /**
151
+ * @param {string} cacheDir
152
+ */
153
+ export function steamcmdExecutable(cacheDir) {
154
+ if (process.platform === 'win32') {
155
+ return path.join(cacheDir, 'steamcmd.exe');
156
+ }
157
+
158
+ return path.join(cacheDir, 'steamcmd.sh');
159
+ }
160
+
161
+ /**
162
+ * @param {string} cacheDir
163
+ */
164
+ async function steamcmdIsInstalled(cacheDir) {
165
+ const executable = steamcmdExecutable(cacheDir);
166
+
167
+ try {
168
+ await fsp.access(executable);
169
+ return true;
170
+ } catch {
171
+ return false;
172
+ }
173
+ }
174
+
175
+ /**
176
+ * @param {string} cacheDir
177
+ * @param {(message: string) => void} [log]
178
+ */
179
+ export async function ensureSteamcmd(cacheDir, log = console.log) {
180
+ if (await steamcmdIsInstalled(cacheDir)) {
181
+ log(`adaptfully: using steamcmd at ${steamcmdExecutable(cacheDir)}`);
182
+ return cacheDir;
183
+ }
184
+
185
+ const install = STEAMCMD_INSTALL[process.platform];
186
+
187
+ if (!install) {
188
+ throw new Error(`Steamcmd install is not supported on platform "${process.platform}".`);
189
+ }
190
+
191
+ await fsp.mkdir(cacheDir, { recursive: true });
192
+
193
+ const archiveName = install.archive === 'zip' ? 'steamcmd.zip' : 'steamcmd.tar.gz';
194
+ const archivePath = path.join(cacheDir, archiveName);
195
+
196
+ log(`adaptfully: downloading steamcmd from ${install.url}`);
197
+ await downloadFile(install.url, archivePath);
198
+ log('adaptfully: extracting steamcmd...');
199
+ await extractArchive(archivePath, cacheDir, install.archive);
200
+ await fsp.unlink(archivePath).catch(() => {});
201
+
202
+ if (!await steamcmdIsInstalled(cacheDir)) {
203
+ throw new Error(`Steamcmd install failed; expected executable at ${steamcmdExecutable(cacheDir)}`);
204
+ }
205
+
206
+ if (process.platform !== 'win32') {
207
+ await fsp.chmod(steamcmdExecutable(cacheDir), 0o755);
208
+ }
209
+
210
+ log(`adaptfully: installed steamcmd to ${cacheDir}`);
211
+ return cacheDir;
212
+ }
213
+
214
+ /**
215
+ * @param {string} cacheDir
216
+ * @param {string} username
217
+ * @param {string} password
218
+ */
219
+ export function runSteamcmdLogin(cacheDir, username, password) {
220
+ const executable = steamcmdExecutable(cacheDir);
221
+ const args = ['+login', username, password, '+quit'];
222
+ const command = process.platform === 'win32' ? executable : executable;
223
+ const spawnCommand = process.platform === 'win32' ? command : 'bash';
224
+ const spawnArgs = process.platform === 'win32' ? args : [command, ...args];
225
+
226
+ return new Promise((resolve, reject) => {
227
+ console.log('');
228
+ console.log('Steamcmd is starting. If Steam Guard is enabled, enter the code when prompted.');
229
+ console.log('');
230
+
231
+ const child = spawn(spawnCommand, spawnArgs, {
232
+ cwd: cacheDir,
233
+ stdio: 'inherit',
234
+ });
235
+
236
+ child.on('error', reject);
237
+ child.on('close', (code) => {
238
+ if (code === 0) {
239
+ resolve(code);
240
+ } else {
241
+ reject(new Error(`steamcmd login failed with exit code ${code}`));
242
+ }
243
+ });
244
+ });
245
+ }
246
+
247
+ /**
248
+ * @param {string[]} argv
249
+ */
250
+ function parseSteamAuthArgv(argv) {
251
+ /** @type {Record<string, string>} */
252
+ const options = {
253
+ projectRoot: '.',
254
+ };
255
+
256
+ for (let i = 3; i < argv.length; i++) {
257
+ const arg = argv[i];
258
+
259
+ if (arg === '--username' && argv[i + 1]) {
260
+ options.username = argv[++i];
261
+ } else if (arg === '--password' && argv[i + 1]) {
262
+ options.password = argv[++i];
263
+ } else if (arg === '--output' && argv[i + 1]) {
264
+ options.output = argv[++i];
265
+ } else if (arg === '--steamcmd-dir' && argv[i + 1]) {
266
+ options.steamcmdDir = argv[++i];
267
+ } else if (arg === '--project-root' && argv[i + 1]) {
268
+ options.projectRoot = argv[++i];
269
+ }
270
+ }
271
+
272
+ return options;
273
+ }
274
+
275
+ /**
276
+ * @param {{ username?: string, password?: string, output?: string, steamcmdDir?: string, projectRoot?: string, log?: (message: string) => void }} [options]
277
+ */
278
+ export async function runSteamAuth(options = {}) {
279
+ const log = options.log ?? console.log;
280
+ const username = options.username
281
+ ?? process.env.STEAM_USERNAME
282
+ ?? process.env.STEAM_BUILD_USERNAME;
283
+ const password = options.password
284
+ ?? process.env.STEAM_PASSWORD
285
+ ?? process.env.STEAM_BUILD_PASSWORD;
286
+ const outputPath = path.resolve(options.output ?? defaultSteamPublishPath(options.projectRoot ?? '.'));
287
+ const cacheDir = options.steamcmdDir ?? defaultSteamcmdCacheDir();
288
+
289
+ let resolvedUsername = username;
290
+ let resolvedPassword = password;
291
+
292
+ if (!resolvedUsername || !resolvedPassword) {
293
+ const rl = readline.createInterface({ input, output });
294
+
295
+ try {
296
+ if (!resolvedUsername) {
297
+ resolvedUsername = await rl.question('Steam build account username: ');
298
+ }
299
+
300
+ if (!resolvedPassword) {
301
+ resolvedPassword = await rl.question('Steam build account password: ');
302
+ }
303
+ } finally {
304
+ rl.close();
305
+ }
306
+ }
307
+
308
+ resolvedUsername = String(resolvedUsername).trim();
309
+ resolvedPassword = String(resolvedPassword);
310
+
311
+ if (!resolvedUsername || !resolvedPassword) {
312
+ throw new Error('Steam username and password are required.');
313
+ }
314
+
315
+ await ensureSteamcmd(cacheDir, log);
316
+ await runSteamcmdLogin(cacheDir, resolvedUsername, resolvedPassword);
317
+
318
+ const authFiles = await collectSteamAuthFiles(cacheDir);
319
+ const steamJson = buildSteamPublishJson({
320
+ username: resolvedUsername,
321
+ password: resolvedPassword,
322
+ ...authFiles,
323
+ });
324
+
325
+ await fsp.mkdir(path.dirname(outputPath), { recursive: true });
326
+ await fsp.writeFile(outputPath, `${JSON.stringify(steamJson, null, 4)}\n`);
327
+
328
+ log(`adaptfully: wrote ${outputPath}`);
329
+ if (authFiles.sentryFileName) {
330
+ log(`adaptfully: included Steam Guard sentry file ${authFiles.sentryFileName}`);
331
+ } else {
332
+ log('adaptfully: no sentry file was created (Steam Guard may be disabled on this account)');
333
+ }
334
+
335
+ return { outputPath, steamJson };
336
+ }
337
+
338
+ /**
339
+ * @param {string[]} [argv]
340
+ */
341
+ export async function steamAuthFromCli(argv = process.argv) {
342
+ return runSteamAuth(parseSteamAuthArgv(argv));
343
+ }
@@ -162,6 +162,7 @@
162
162
 
163
163
  whenReady(done) {
164
164
  if (!this.#hasSteamBridge()) {
165
+ console.warn('[adaptfully steam-auth] Steamworks bridge not found on window');
165
166
  this.online = false;
166
167
  done({ error: 'Steamworks client not available' });
167
168
  return;
@@ -179,6 +180,7 @@
179
180
  }
180
181
 
181
182
  if (Date.now() - started >= timeoutMs) {
183
+ console.warn('[adaptfully steam-auth] timed out waiting for Steam identity');
182
184
  this.online = false;
183
185
  done({ error: 'Steamworks client not available' });
184
186
  return;
@@ -200,10 +202,13 @@
200
202
  login(callback) {
201
203
  this.#resolveIdentity()
202
204
  .then((identity) => {
203
- this.#applyIdentity(identity);
205
+ if (!this.#applyIdentity(identity)) {
206
+ console.warn('[adaptfully steam-auth] login: no Steam identity available', identity);
207
+ }
204
208
  this.#complete(callback);
205
209
  })
206
- .catch(() => {
210
+ .catch((err) => {
211
+ console.error('[adaptfully steam-auth] login failed:', err);
207
212
  this.user = null;
208
213
  this.authenticated = false;
209
214
  this.online = false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@makefully/adaptfully",
3
- "version": "3.3.0",
3
+ "version": "3.5.0",
4
4
  "description": "Platform abstraction and Wrapfully deploy client for Makefully games",
5
5
  "type": "module",
6
6
  "main": "./lib/node/index.js",