Protected profiles: recovery email and Discord contacts with reset codes (Gmail SMTP, Discord relay)
This commit is contained in:
@@ -316,7 +316,7 @@ export async function initDb() {
|
||||
)`);
|
||||
// Optional profile protection: a password or generated key, stored only as a
|
||||
// slow salted hash (Bun.password / argon2id). NULL = the name alone opens it.
|
||||
for (const col of ['secret_hash TEXT', 'secret_kind TEXT']) {
|
||||
for (const col of ['secret_hash TEXT', 'secret_kind TEXT', 'recovery_email TEXT', 'recovery_discord TEXT']) {
|
||||
try { await db.execute(`ALTER TABLE profiles ADD COLUMN ${col}`); } catch { /* already there */ }
|
||||
}
|
||||
}
|
||||
@@ -763,12 +763,13 @@ export async function createProfile(name, dataJson) {
|
||||
|
||||
export async function getProfile(name) {
|
||||
const r = await db.execute({
|
||||
sql: 'SELECT data, updated_at, secret_hash, secret_kind FROM profiles WHERE name = ?',
|
||||
sql: 'SELECT data, updated_at, secret_hash, secret_kind, recovery_email, recovery_discord FROM profiles WHERE name = ?',
|
||||
args: [name],
|
||||
});
|
||||
const row = r.rows[0];
|
||||
if (!row) return null;
|
||||
return { data: row.data, updatedAt: Number(row.updated_at), secretHash: row.secret_hash || null, secretKind: row.secret_kind || null };
|
||||
return { data: row.data, updatedAt: Number(row.updated_at), secretHash: row.secret_hash || null, secretKind: row.secret_kind || null,
|
||||
recoveryEmail: row.recovery_email || null, recoveryDiscord: row.recovery_discord || null };
|
||||
}
|
||||
|
||||
export async function setProfileSecret(name, hash, kind) {
|
||||
|
||||
Reference in New Issue
Block a user