feat(deploy): add Contabo release workflow and portal payload gate

This commit is contained in:
DeCentN2Madness authored and AIAMarketing committed 2026-11-05 00:40:18 -07:00
1 parent 5fa54719b2
commit ba93a54942
18 files changed
+697 -28

No files matched your search

@@ -3,9 +3,11 @@ import { readPortalInput } from '../../utils/portal-input.mjs';
import Button from '../Button.astro';
// Non-PUBLIC, build-only ciphertext input. No passphrase is read by the build.
const payload = readPortalInput({
approved: import.meta.env.AIA_PORTAL_LOCAL_PREVIEW_APPROVED,
localApproved: import.meta.env.AIA_PORTAL_LOCAL_PREVIEW_APPROVED,
productionApproved: import.meta.env.AIA_PORTAL_PRODUCTION_APPROVED,
indexing: import.meta.env.PUBLIC_ALLOW_INDEXING,
file: import.meta.env.AIA_PORTAL_CIPHERTEXT_FILE,
localFile: import.meta.env.AIA_PORTAL_CIPHERTEXT_FILE,
productionFile: import.meta.env.AIA_PORTAL_PRODUCTION_CIPHERTEXT_FILE,
});
const serialized = payload ? JSON.stringify(payload).replaceAll('<', '\\u003c') : 'null';
---
+14 -4
View File
@@ -1,10 +1,20 @@
// Build-only reader; never imported by a browser script.
import fs from 'node:fs';
import { validatePortalPayload } from './portal-crypto.mjs';
export function readPortalInput({ approved, indexing, file }) {
if (approved !== 'true' || indexing !== 'false' || !file) return undefined;
/** Build-only reader. Local preview and approved public publication are distinct. */
export function readPortalInput({ localApproved, productionApproved, indexing, localFile, productionFile }) {
const local = localApproved === 'true';
const production = productionApproved === 'true';
if (local && production) throw new Error('Choose either local-preview or production portal ciphertext, never both');
const file = local ? localFile : production ? productionFile : undefined;
const permitted = (local && indexing === 'false') || (production && indexing === 'true');
if (!permitted) {
if (local || production) throw new Error('Portal ciphertext approval does not match this publication mode');
return undefined;
}
if (!file) throw new Error('Approved portal ciphertext file is required for this build');
try {
if (fs.statSync(file).size > 12_000_000) return undefined;
if (fs.lstatSync(file).isSymbolicLink() || fs.statSync(file).size > 12_000_000) throw new Error('Portal ciphertext must be a regular bounded file');
return validatePortalPayload(JSON.parse(fs.readFileSync(file, 'utf8')));
} catch { return undefined; }
} catch { throw new Error('Approved portal ciphertext is missing or malformed'); }
}