gamedev 0.2.2 → 0.2.4
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/app-server/cliAuth.js +24 -224
- package/app-server/commands.js +7 -7
- package/bin/gamedev.mjs +11 -5
- package/build/index.js +15 -54
- package/build/index.js.map +2 -2
- package/build/public/admin.html +2 -2
- package/build/public/index.html +2 -2
- package/docs/App-server.md +3 -2
- package/package.json +1 -1
- package/src/server/admin.js +7 -3
- package/src/server/cliAuth.js +7 -46
- package/src/server/index.js +2 -6
package/build/public/admin.html
CHANGED
|
@@ -25,14 +25,14 @@
|
|
|
25
25
|
<meta name="apple-mobile-web-app-capable" content="yes" />
|
|
26
26
|
<meta name="mobile-web-app-capable" content="yes" />
|
|
27
27
|
<link rel="preload" href="/SpaceMono-regular.woff2" as="font" type="font/woff2" crossorigin />
|
|
28
|
-
<link rel="stylesheet" type="text/css" href="/index.css?v=
|
|
28
|
+
<link rel="stylesheet" type="text/css" href="/index.css?v=1774801170959" />
|
|
29
29
|
<script>
|
|
30
30
|
window.PARTICLES_PATH = '/particles-4YQR4CFO.js'
|
|
31
31
|
</script>
|
|
32
32
|
</head>
|
|
33
33
|
<body>
|
|
34
34
|
<div id="root"></div>
|
|
35
|
-
<script src="/env.js?v=
|
|
35
|
+
<script src="/env.js?v=1774801170959"></script>
|
|
36
36
|
<script src="/admin-3ATEWWG5.js" type="module"></script>
|
|
37
37
|
</body>
|
|
38
38
|
</html>
|
package/build/public/index.html
CHANGED
|
@@ -44,14 +44,14 @@
|
|
|
44
44
|
<meta name="theme-color" content="#ffffff"> -->
|
|
45
45
|
|
|
46
46
|
<link rel="preload" href="/SpaceMono-regular.woff2" as="font" type="font/woff2" crossorigin />
|
|
47
|
-
<link rel="stylesheet" type="text/css" href="/index.css?v=
|
|
47
|
+
<link rel="stylesheet" type="text/css" href="/index.css?v=1774801170822" />
|
|
48
48
|
<script>
|
|
49
49
|
window.PARTICLES_PATH = '/particles-4YQR4CFO.js'
|
|
50
50
|
</script>
|
|
51
51
|
</head>
|
|
52
52
|
<body>
|
|
53
53
|
<div id="root"></div>
|
|
54
|
-
<script src="/env.js?v=
|
|
54
|
+
<script src="/env.js?v=1774801170822"></script>
|
|
55
55
|
<script src="/index-4H3CVLQ5.js" type="module"></script>
|
|
56
56
|
</body>
|
|
57
57
|
</html>
|
package/docs/App-server.md
CHANGED
|
@@ -12,7 +12,8 @@ App-server is the dev server that syncs local files to a world via `/admin`. It
|
|
|
12
12
|
- direct runtime: `http://localhost:3000`
|
|
13
13
|
- platform slug proxy: `https://<host>/worlds/<slug>`
|
|
14
14
|
- `WORLD_ID` (must match the target worldId)
|
|
15
|
-
- Run `gamedev auth` once in the project to cache a browser-authenticated world token in `.lobby/auth.json`.
|
|
15
|
+
- Run `gamedev auth` or start `gamedev dev`/`gamedev app-server` once in the project to cache a browser-authenticated world token in `.lobby/auth.json`.
|
|
16
|
+
Continuous script sync requires deploy access; if the cached token only has builder access, the CLI will prompt for stronger auth.
|
|
16
17
|
- `ADMIN_CODE` is no longer used by the CLI or app-server. On standalone worlds it is only for in-world `/admin <code>` privilege escalation. Bootstrapped worlds ignore admin-code auth and rely on account roles instead.
|
|
17
18
|
|
|
18
19
|
---
|
|
@@ -130,7 +131,7 @@ For prod targets, the CLI asks for confirmation unless you pass `--yes`.
|
|
|
130
131
|
### Troubleshooting
|
|
131
132
|
|
|
132
133
|
- Bootstrap didn’t happen: ensure the target world is empty/default or run `gamedev world export` (add `--include-built-scripts` for legacy single-file apps).
|
|
133
|
-
- Unauthorized: rerun `gamedev auth`, then confirm the signed-in account has
|
|
134
|
+
- Unauthorized: rerun `gamedev auth`, then confirm the signed-in account has deploy access in the world.
|
|
134
135
|
- Script updates rejected: confirm the signed-in account has deploy access and the deploy lock is free.
|
|
135
136
|
- WORLD_ID mismatch: set `WORLD_ID` to match the target world id.
|
|
136
137
|
- Changes not appearing: confirm `apps/<appName>/index.js` (or blueprint JSON) is being edited and app-server is connected.
|
package/package.json
CHANGED
package/src/server/admin.js
CHANGED
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
handleRuntimeCredentialCommand,
|
|
11
11
|
} from './adminCredentials.js'
|
|
12
12
|
import { ADMIN_SHUTDOWN_COMMAND, handleAdminShutdownCommand } from './adminShutdown.js'
|
|
13
|
-
import { hasSupportedAdminCode } from './runtimeBootstrap.js'
|
|
13
|
+
import { allowsOpenAdminAccess, hasSupportedAdminCode } from './runtimeBootstrap.js'
|
|
14
14
|
import { describeWebSocketConnection, resolveWebSocketConnection } from './websocketConnection.js'
|
|
15
15
|
import { getMaxUploadSizeBytes, getMaxUploadSizeMb } from './worldLimits.js'
|
|
16
16
|
|
|
@@ -390,6 +390,9 @@ export async function admin(
|
|
|
390
390
|
}
|
|
391
391
|
|
|
392
392
|
async function getCapabilitiesFromAuthToken(token) {
|
|
393
|
+
if (allowsOpenAdminAccess(process.env)) {
|
|
394
|
+
return { builder: true, deploy: true }
|
|
395
|
+
}
|
|
393
396
|
if (!token || !db) return { builder: false, deploy: false }
|
|
394
397
|
const worldId = world?.network?.worldId || process.env.WORLD_ID
|
|
395
398
|
const claims = await readJWT(token, { worldId })
|
|
@@ -828,9 +831,10 @@ export async function admin(
|
|
|
828
831
|
ws.close()
|
|
829
832
|
return
|
|
830
833
|
}
|
|
834
|
+
const openAdminAccess = allowsOpenAdminAccess(process.env)
|
|
831
835
|
const codeCapabilities = getCapabilitiesFromAdminCode(data?.code)
|
|
832
|
-
let builderOk = codeCapabilities.builder
|
|
833
|
-
let deployOk = codeCapabilities.deploy
|
|
836
|
+
let builderOk = openAdminAccess || codeCapabilities.builder
|
|
837
|
+
let deployOk = openAdminAccess || codeCapabilities.deploy
|
|
834
838
|
if (!builderOk || !deployOk) {
|
|
835
839
|
const payloadToken = typeof data?.authToken === 'string' ? data.authToken.trim() : ''
|
|
836
840
|
const headerToken = getRuntimeAuthTokenFromRequest(req) || ''
|
package/src/server/cliAuth.js
CHANGED
|
@@ -243,17 +243,13 @@ export async function createStandaloneGuestSession({
|
|
|
243
243
|
}
|
|
244
244
|
|
|
245
245
|
export function buildCliAuthPage({
|
|
246
|
-
callbackUrl,
|
|
247
246
|
sessionId,
|
|
248
|
-
state,
|
|
249
247
|
worldId,
|
|
250
248
|
requiredCapability = 'builder',
|
|
251
249
|
publicAuthUrl = null,
|
|
252
250
|
} = {}) {
|
|
253
251
|
const config = JSON.stringify({
|
|
254
|
-
callbackUrl: normalizeString(callbackUrl),
|
|
255
252
|
sessionId: normalizeString(sessionId),
|
|
256
|
-
state: normalizeString(state),
|
|
257
253
|
worldId: normalizeString(worldId),
|
|
258
254
|
requiredCapability: normalizeString(requiredCapability) || 'builder',
|
|
259
255
|
publicAuthUrl: hasValue(publicAuthUrl) ? publicAuthUrl.trim() : null,
|
|
@@ -643,18 +639,6 @@ export function buildCliAuthPage({
|
|
|
643
639
|
return !!capabilities?.builder
|
|
644
640
|
}
|
|
645
641
|
|
|
646
|
-
function validateCallbackUrl(value) {
|
|
647
|
-
try {
|
|
648
|
-
const parsed = new URL(value)
|
|
649
|
-
const hostname = parsed.hostname
|
|
650
|
-
if (!hostname) return null
|
|
651
|
-
if (hostname !== '127.0.0.1' && hostname !== 'localhost' && hostname !== '::1') return null
|
|
652
|
-
return parsed.toString()
|
|
653
|
-
} catch {
|
|
654
|
-
return null
|
|
655
|
-
}
|
|
656
|
-
}
|
|
657
|
-
|
|
658
642
|
async function fetchStatus(token) {
|
|
659
643
|
const response = await fetch(\`\${apiBaseUrl()}/auth/cli/status\`, {
|
|
660
644
|
headers: {
|
|
@@ -712,47 +696,24 @@ export function buildCliAuthPage({
|
|
|
712
696
|
return token
|
|
713
697
|
}
|
|
714
698
|
|
|
715
|
-
async function submitToken(token
|
|
716
|
-
if (config.sessionId) {
|
|
717
|
-
|
|
718
|
-
method: 'POST',
|
|
719
|
-
headers: {
|
|
720
|
-
'content-type': 'application/json',
|
|
721
|
-
accept: 'application/json',
|
|
722
|
-
},
|
|
723
|
-
body: JSON.stringify({
|
|
724
|
-
worldUrl: worldRootUrl(),
|
|
725
|
-
authToken: token,
|
|
726
|
-
}),
|
|
727
|
-
})
|
|
728
|
-
if (!response.ok) {
|
|
729
|
-
const payload = await response.json().catch(() => null)
|
|
730
|
-
throw new Error(payload?.error || 'session_complete_failed')
|
|
731
|
-
}
|
|
732
|
-
return
|
|
699
|
+
async function submitToken(token) {
|
|
700
|
+
if (!config.sessionId) {
|
|
701
|
+
throw new Error('Invalid session id')
|
|
733
702
|
}
|
|
734
|
-
|
|
735
|
-
const callbackUrl = validateCallbackUrl(config.callbackUrl)
|
|
736
|
-
if (!callbackUrl) {
|
|
737
|
-
throw new Error('Invalid callback URL')
|
|
738
|
-
}
|
|
739
|
-
const response = await fetch(callbackUrl, {
|
|
703
|
+
const response = await fetch(\`\${apiBaseUrl()}/auth/cli/session/\${encodeURIComponent(config.sessionId)}\`, {
|
|
740
704
|
method: 'POST',
|
|
741
705
|
headers: {
|
|
742
706
|
'content-type': 'application/json',
|
|
707
|
+
accept: 'application/json',
|
|
743
708
|
},
|
|
744
709
|
body: JSON.stringify({
|
|
745
|
-
state: config.state,
|
|
746
|
-
worldId: status?.worldId || config.worldId || '',
|
|
747
710
|
worldUrl: worldRootUrl(),
|
|
748
711
|
authToken: token,
|
|
749
|
-
user: status?.user || null,
|
|
750
|
-
capabilities: status?.capabilities || null,
|
|
751
712
|
}),
|
|
752
713
|
})
|
|
753
714
|
if (!response.ok) {
|
|
754
715
|
const payload = await response.json().catch(() => null)
|
|
755
|
-
throw new Error(payload?.error || '
|
|
716
|
+
throw new Error(payload?.error || 'session_complete_failed')
|
|
756
717
|
}
|
|
757
718
|
}
|
|
758
719
|
|
|
@@ -794,7 +755,7 @@ export function buildCliAuthPage({
|
|
|
794
755
|
'success'
|
|
795
756
|
)
|
|
796
757
|
setHint('Permission confirmed. The CLI is storing this world token locally.', 'success')
|
|
797
|
-
await submitToken(token
|
|
758
|
+
await submitToken(token)
|
|
798
759
|
clearInterval(polling)
|
|
799
760
|
setTimeout(() => {
|
|
800
761
|
window.close()
|
package/src/server/index.js
CHANGED
|
@@ -1117,21 +1117,17 @@ async function handleCliAuthPage(req, reply) {
|
|
|
1117
1117
|
if (!isRuntimeReady(runtimeState)) {
|
|
1118
1118
|
return sendRuntimeNotReady(reply, runtimeState, { html: true })
|
|
1119
1119
|
}
|
|
1120
|
-
const callbackUrl = typeof req.query?.callback === 'string' ? req.query.callback.trim() : ''
|
|
1121
1120
|
const sessionId = typeof req.query?.session === 'string' ? req.query.session.trim() : ''
|
|
1122
|
-
const state = typeof req.query?.state === 'string' ? req.query.state.trim() : ''
|
|
1123
1121
|
const worldId = typeof req.query?.worldId === 'string' ? req.query.worldId.trim() : resolveBoundWorldId() || ''
|
|
1124
1122
|
const requiredCapability = typeof req.query?.required === 'string' ? req.query.required.trim() : 'builder'
|
|
1125
|
-
if (!sessionId
|
|
1123
|
+
if (!sessionId) {
|
|
1126
1124
|
return reply.code(400).type('text/html').send(
|
|
1127
|
-
'<!doctype html><html><body>Missing session
|
|
1125
|
+
'<!doctype html><html><body>Missing session.</body></html>'
|
|
1128
1126
|
)
|
|
1129
1127
|
}
|
|
1130
1128
|
reply.type('text/html').send(
|
|
1131
1129
|
buildCliAuthPage({
|
|
1132
|
-
callbackUrl,
|
|
1133
1130
|
sessionId,
|
|
1134
|
-
state,
|
|
1135
1131
|
worldId,
|
|
1136
1132
|
requiredCapability,
|
|
1137
1133
|
publicAuthUrl: process.env.PUBLIC_AUTH_URL || null,
|