Build verified checkpoint containers for TrueNAS
This commit is contained in:
1 parent
c5508b727a
commit
64e8299aeb
27 files changed
+536
-16
No files matched your search
@@ -0,0 +1,15 @@
|
||||
/** UUID v4 for browser operations, including private LAN HTTP origins. */
|
||||
export function randomId(): string {
|
||||
// Unlike randomUUID(), getRandomValues is available outside secure contexts.
|
||||
const bytes = globalThis.crypto.getRandomValues(new Uint8Array(16));
|
||||
bytes[6] = (bytes[6] & 0x0f) | 0x40;
|
||||
bytes[8] = (bytes[8] & 0x3f) | 0x80;
|
||||
const hex = Array.from(bytes, (byte) => byte.toString(16).padStart(2, '0'));
|
||||
return [
|
||||
hex.slice(0, 4).join(''),
|
||||
hex.slice(4, 6).join(''),
|
||||
hex.slice(6, 8).join(''),
|
||||
hex.slice(8, 10).join(''),
|
||||
hex.slice(10).join(''),
|
||||
].join('-');
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
/** The administrator configures the external origin; forwarded headers are untrusted. */
|
||||
export function requestOrigin(request: Request, configured?: string): string {
|
||||
if (!configured) return new URL(request.url).origin;
|
||||
const url = new URL(configured);
|
||||
if (
|
||||
!['http:', 'https:'].includes(url.protocol) ||
|
||||
url.username || url.password || url.search || url.hash || url.pathname !== '/'
|
||||
) throw new Error('DUNE_PUBLIC_ORIGIN must be an HTTP(S) origin without a path.');
|
||||
return url.origin;
|
||||
}
|
||||
+2
-1
@@ -1,3 +1,4 @@
|
||||
import { randomId } from './random-id';
|
||||
import { EXPANSIONS, FACTIONS } from '../game/catalog';
|
||||
import { requestMayHaveCompleted } from './client-request';
|
||||
|
||||
@@ -108,7 +109,7 @@ export function createRoomEntry(
|
||||
roomCode?: string,
|
||||
): RoomEntryAttempt {
|
||||
const entry = {
|
||||
operationId: globalThis.crypto.randomUUID(),
|
||||
operationId: randomId(),
|
||||
sessionToken: Array.from(
|
||||
globalThis.crypto.getRandomValues(new Uint8Array(32)),
|
||||
(byte) => byte.toString(16).padStart(2, '0'),
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { randomId } from './random-id';
|
||||
import type { GameView } from '../game/engine';
|
||||
|
||||
export const HANDOVER_CLAIM_STORAGE_KEY = 'dune.pending-seat-handover.v1';
|
||||
@@ -98,7 +99,7 @@ export function createHandoverKit(
|
||||
version: 1,
|
||||
roomCode,
|
||||
playerId,
|
||||
offerId: crypto.randomUUID(),
|
||||
offerId: randomId(),
|
||||
handoverSecret: secret(),
|
||||
}),
|
||||
);
|
||||
@@ -111,7 +112,7 @@ export function createHandoverClaim(kit: SeatHandoverKit): SavedHandoverClaim {
|
||||
playerId: kit.playerId,
|
||||
offerId: kit.offerId,
|
||||
handoverSecret: kit.handoverSecret,
|
||||
operationId: crypto.randomUUID(),
|
||||
operationId: randomId(),
|
||||
newSessionToken: secret(),
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { randomId } from './random-id';
|
||||
export type SeatRecoveryKit = Readonly<{
|
||||
format: 'dune-seat-recovery';
|
||||
version: 1;
|
||||
@@ -106,7 +107,7 @@ export function createRecoveryAttempt(
|
||||
type: 'recoverSeat',
|
||||
playerId: kit.playerId,
|
||||
recoverySecret: kit.recoverySecret,
|
||||
operationId: globalThis.crypto.randomUUID(),
|
||||
operationId: randomId(),
|
||||
newSessionToken: secret256(),
|
||||
});
|
||||
}
|
||||
Reference in new issue
Block a user