mirror of
https://github.com/jjbrunton/Sauci.git
synced 2026-10-31 18:19:43 +00:00
fix(backend): allow deferred provider integrations
This commit is contained in:
1 parent
96882642c7
commit
32f5214751
4 files changed
+44
-11
No files matched your search
@@ -1,5 +1,8 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
const optionalString = z.preprocess((value) => value === '' ? undefined : value, z.string().min(1).optional());
|
||||
const optionalUuid = z.preprocess((value) => value === '' ? undefined : value, z.string().uuid().optional());
|
||||
|
||||
const baseSchema = z.object({
|
||||
NODE_ENV: z.enum(['development', 'test', 'production']).default('development'),
|
||||
PORT: z.coerce.number().int().min(1).max(65535).default(3003),
|
||||
@@ -12,13 +15,13 @@ const baseSchema = z.object({
|
||||
MEDIA_ROOT: z.string().min(1).default('/data/media'),
|
||||
MEDIA_SIGNING_SECRET: z.string().min(32).optional(),
|
||||
MEDIA_PUBLIC_BASE_URL: z.string().url().optional(),
|
||||
SUPABASE_AUTH_SERVICE_ROLE_KEY: z.string().min(1).optional(),
|
||||
REVENUECAT_API_KEY: z.string().min(1).optional(),
|
||||
SUPABASE_AUTH_SERVICE_ROLE_KEY: optionalString,
|
||||
REVENUECAT_API_KEY: optionalString,
|
||||
REVENUECAT_ENTITLEMENT_ID: z.string().min(1).default('Sauci Pro'),
|
||||
REVENUECAT_WEBHOOK_SECRET: z.string().min(1).optional(),
|
||||
ADMIN_API_SERVICE_TOKEN: z.string().min(32).optional(),
|
||||
ADMIN_API_SERVICE_USER_ID: z.string().uuid().optional(),
|
||||
ADMIN_PRIVATE_KEY_JWK: z.string().optional(),
|
||||
REVENUECAT_WEBHOOK_SECRET: optionalString,
|
||||
ADMIN_API_SERVICE_TOKEN: z.preprocess((value) => value === '' ? undefined : value, z.string().min(32).optional()),
|
||||
ADMIN_API_SERVICE_USER_ID: optionalUuid,
|
||||
ADMIN_PRIVATE_KEY_JWK: optionalString,
|
||||
});
|
||||
|
||||
export interface AppConfig {
|
||||
|
||||
@@ -61,4 +61,28 @@ describe('Supabase Auth JWT verification', () => {
|
||||
AUTH_TEST_JWKS: jwks,
|
||||
})).toThrow('AUTH_TEST_JWKS is forbidden');
|
||||
});
|
||||
|
||||
it('treats empty optional deployment integrations as disabled', async () => {
|
||||
const { jwks } = await signedToken();
|
||||
const config = loadConfig({
|
||||
NODE_ENV: 'test',
|
||||
DATABASE_URL: 'postgresql://localhost/sauci_test',
|
||||
SUPABASE_AUTH_ISSUER: issuer,
|
||||
AUTH_TEST_JWKS: jwks,
|
||||
SUPABASE_AUTH_SERVICE_ROLE_KEY: '',
|
||||
REVENUECAT_API_KEY: '',
|
||||
REVENUECAT_WEBHOOK_SECRET: '',
|
||||
ADMIN_API_SERVICE_TOKEN: '',
|
||||
ADMIN_API_SERVICE_USER_ID: '',
|
||||
ADMIN_PRIVATE_KEY_JWK: '',
|
||||
});
|
||||
expect(config).toMatchObject({
|
||||
supabaseAuthServiceRoleKey: undefined,
|
||||
revenueCatApiKey: undefined,
|
||||
revenueCatWebhookSecret: undefined,
|
||||
adminApiServiceToken: undefined,
|
||||
adminApiServiceUserId: undefined,
|
||||
adminPrivateKeyJwk: undefined,
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -45,6 +45,12 @@ different name `SAUCI_ADMIN_API_TOKEN` plus its independent caller-facing
|
||||
`SAUCI_MCP_API_KEY`. The token does not confer Supabase authority: the API maps
|
||||
it to the configured administrator and applies normal permissions and auditing.
|
||||
Do not give either admin token to mobile, admin browser, or worker containers.
|
||||
An environment without an imported active administrator may leave both values
|
||||
empty; customer API routes still run, while MCP service authentication remains
|
||||
disabled until the pair is configured. RevenueCat credentials are likewise
|
||||
optional at infrastructure bootstrap, but purchase verification, webhooks, and
|
||||
account-deletion provider cleanup remain unavailable until their dedicated
|
||||
server-side credentials are installed.
|
||||
|
||||
Secret ownership is intentionally split:
|
||||
|
||||
|
||||
@@ -10,12 +10,12 @@ x-api-environment: &api-environment
|
||||
PORT: 3003
|
||||
SUPABASE_AUTH_URL: ${SUPABASE_AUTH_URL:?set SUPABASE_AUTH_URL}
|
||||
SUPABASE_AUTH_AUDIENCE: ${SUPABASE_AUTH_AUDIENCE:-authenticated}
|
||||
SUPABASE_AUTH_SERVICE_ROLE_KEY: ${SUPABASE_AUTH_SERVICE_ROLE_KEY:?set SUPABASE_AUTH_SERVICE_ROLE_KEY}
|
||||
REVENUECAT_API_KEY: ${REVENUECAT_API_KEY:?set REVENUECAT_API_KEY}
|
||||
SUPABASE_AUTH_SERVICE_ROLE_KEY: ${SUPABASE_AUTH_SERVICE_ROLE_KEY:-}
|
||||
REVENUECAT_API_KEY: ${REVENUECAT_API_KEY:-}
|
||||
REVENUECAT_ENTITLEMENT_ID: ${REVENUECAT_ENTITLEMENT_ID:-Sauci Pro}
|
||||
REVENUECAT_WEBHOOK_SECRET: ${REVENUECAT_WEBHOOK_SECRET:?set REVENUECAT_WEBHOOK_SECRET}
|
||||
ADMIN_API_SERVICE_TOKEN: ${ADMIN_API_SERVICE_TOKEN:?set ADMIN_API_SERVICE_TOKEN}
|
||||
ADMIN_API_SERVICE_USER_ID: ${ADMIN_API_SERVICE_USER_ID:?set ADMIN_API_SERVICE_USER_ID}
|
||||
REVENUECAT_WEBHOOK_SECRET: ${REVENUECAT_WEBHOOK_SECRET:-}
|
||||
ADMIN_API_SERVICE_TOKEN: ${ADMIN_API_SERVICE_TOKEN:-}
|
||||
ADMIN_API_SERVICE_USER_ID: ${ADMIN_API_SERVICE_USER_ID:-}
|
||||
ADMIN_PRIVATE_KEY_JWK: ${ADMIN_PRIVATE_KEY_JWK:-}
|
||||
|
||||
x-worker-environment: &worker-environment
|
||||
|
||||
Reference in new issue
Block a user