Files
halobestie-clone/backend/scripts/setup-test-mitra-otp.mjs
Ramadhan Sjamsani 12cf9f80e9 chore(backend): add dev helper to provision a static-OTP mitra login
setup-test-mitra-otp.mjs adds a phone+mitra-scoped entry to the
app_config.test_otp_bypass allowlist and ensures an ACTIVE mitra row
(createMitra defaults inactive -> 403). Dev/QA convenience; the bypass is
checked before Fazpass in requestOtp so it short-circuits even when
FAZPASS_ENABLED=true. Idempotent.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 21:57:42 +08:00

86 lines
3.3 KiB
JavaScript

// Dev helper: provision a STATIC-OTP mitra login for local/QA testing.
//
// Uses the existing test-OTP-bypass allowlist (app_config.test_otp_bypass),
// the same mechanism shipped for Apple-reviewer QA. It:
// 1. ensures an ACTIVE mitra exists with the test phone (mitras default to
// is_active=false, which the mitra verify route rejects with 403),
// 2. adds a phone-scoped, mitra-scoped static OTP entry (bcrypt-hashed),
// 3. flips the global bypass kill-switch on.
//
// After running, log into the mitra app with PHONE + OTP below — no Fazpass,
// no console code-reading. Re-running is idempotent.
//
// Usage (from backend/): node scripts/setup-test-mitra-otp.mjs
// Override defaults: TEST_MITRA_PHONE=+628... TEST_MITRA_OTP=123456 node scripts/setup-test-mitra-otp.mjs
import 'dotenv/config'
import { getDb } from '../src/db/client.js'
import {
getTestOtpBypass,
addTestOtpBypassEntry,
setTestOtpBypassEnabled,
} from '../src/services/config.service.js'
const PHONE = process.env.TEST_MITRA_PHONE || '+6281200000001'
const OTP = process.env.TEST_MITRA_OTP || '123456'
const LABEL = process.env.TEST_MITRA_LABEL || 'Dev static OTP (mitra)'
const DISPLAY_NAME = process.env.TEST_MITRA_NAME || 'Test Bestie'
// Far-future expiry — the allowlist requires a future expires_at per entry.
const EXPIRES_AT = '2099-01-01T00:00:00.000Z'
const sql = getDb()
async function main () {
// 1. Ensure an ACTIVE mitra with this phone (raw SQL — avoids importing
// mitra.service, which pulls in the valkey plugin and would leave an open
// handle keeping this script alive).
const [existing] = await sql`SELECT id, is_active FROM mitras WHERE phone = ${PHONE}`
if (!existing) {
const [m] = await sql`
INSERT INTO mitras (phone, display_name, is_active)
VALUES (${PHONE}, ${DISPLAY_NAME}, true)
RETURNING id
`
console.log(` created active mitra ${m.id} (${PHONE})`)
} else if (!existing.is_active) {
await sql`UPDATE mitras SET is_active = true WHERE id = ${existing.id}`
console.log(` mitra ${existing.id} existed — activated`)
} else {
console.log(` mitra ${existing.id} already exists and active`)
}
// 2. Add the static-OTP allowlist entry (skip if one already exists for this
// phone+mitra — addTestOtpBypassEntry throws on duplicate).
const current = await getTestOtpBypass()
const exists = current.entries.some(e => e.phone === PHONE && e.user_type === 'mitra')
if (exists) {
console.log(' bypass entry already present for this phone+mitra — leaving as is')
console.log(' (to rotate the OTP: delete the entry in CC → Settings, then re-run)')
} else {
await addTestOtpBypassEntry({
phone: PHONE,
otp: OTP,
user_type: 'mitra',
label: LABEL,
expires_at: EXPIRES_AT,
})
console.log(` added bypass entry: ${PHONE} → otp ${OTP} (mitra)`)
}
// 3. Global kill-switch ON.
await setTestOtpBypassEnabled(true)
console.log(' bypass allowlist ENABLED')
console.log('\n✅ Static mitra OTP ready:')
console.log(` phone: ${PHONE}`)
console.log(` otp: ${exists ? '(unchanged — set on a previous run)' : OTP}`)
}
main()
.then(() => sql.end({ timeout: 5 }))
.catch(async (err) => {
console.error('FAILED:', err.message)
await sql.end({ timeout: 5 })
process.exit(1)
})