124 lines
3.5 KiB
JavaScript
124 lines
3.5 KiB
JavaScript
import { signInWithPassword, signUpWithPassword } from '../src/services/identity-toolkit.js';
|
|
import { applicationDefault, getApps, initializeApp } from 'firebase-admin/app';
|
|
import { getAuth } from 'firebase-admin/auth';
|
|
|
|
const ownerEmail = process.env.V2_DEMO_OWNER_EMAIL || 'legendary.owner+v2@krowd.com';
|
|
const staffEmail = process.env.V2_DEMO_STAFF_EMAIL || 'ana.barista+v2@krowd.com';
|
|
const staffPhone = process.env.V2_DEMO_STAFF_PHONE || '+15557654321';
|
|
const ownerPassword = process.env.V2_DEMO_OWNER_PASSWORD || 'Demo2026!';
|
|
const staffPassword = process.env.V2_DEMO_STAFF_PASSWORD || 'Demo2026!';
|
|
|
|
function ensureAdminApp() {
|
|
if (getApps().length === 0) {
|
|
initializeApp({ credential: applicationDefault() });
|
|
}
|
|
}
|
|
|
|
function getAdminAuth() {
|
|
ensureAdminApp();
|
|
return getAuth();
|
|
}
|
|
|
|
async function ensureUser({ email, password, displayName }) {
|
|
try {
|
|
const signedIn = await signInWithPassword({ email, password });
|
|
return {
|
|
uid: signedIn.localId,
|
|
email,
|
|
password,
|
|
created: false,
|
|
displayName,
|
|
};
|
|
} catch (error) {
|
|
const message = error?.message || '';
|
|
if (!message.includes('INVALID_LOGIN_CREDENTIALS') && !message.includes('EMAIL_NOT_FOUND')) {
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
try {
|
|
const signedUp = await signUpWithPassword({ email, password });
|
|
return {
|
|
uid: signedUp.localId,
|
|
email,
|
|
password,
|
|
created: true,
|
|
displayName,
|
|
};
|
|
} catch (error) {
|
|
const message = error?.message || '';
|
|
if (message.includes('EMAIL_EXISTS')) {
|
|
throw new Error(`Firebase user ${email} exists but password does not match expected demo password.`);
|
|
}
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
async function getUserByPhoneNumber(phoneNumber) {
|
|
try {
|
|
return await getAdminAuth().getUserByPhoneNumber(phoneNumber);
|
|
} catch (error) {
|
|
if (error?.code === 'auth/user-not-found') return null;
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
async function reconcileStaffPhoneIdentity({ uid, email, displayName, phoneNumber }) {
|
|
const auth = getAdminAuth();
|
|
const current = await auth.getUser(uid);
|
|
const existingPhoneUser = await getUserByPhoneNumber(phoneNumber);
|
|
let deletedConflictingUid = null;
|
|
|
|
if (existingPhoneUser && existingPhoneUser.uid !== uid) {
|
|
deletedConflictingUid = existingPhoneUser.uid;
|
|
await auth.deleteUser(existingPhoneUser.uid);
|
|
}
|
|
|
|
const updatePayload = {};
|
|
if (current.displayName !== displayName) updatePayload.displayName = displayName;
|
|
if (current.email !== email) updatePayload.email = email;
|
|
if (current.phoneNumber !== phoneNumber) updatePayload.phoneNumber = phoneNumber;
|
|
|
|
if (Object.keys(updatePayload).length > 0) {
|
|
await auth.updateUser(uid, updatePayload);
|
|
}
|
|
|
|
const reconciled = await auth.getUser(uid);
|
|
return {
|
|
uid: reconciled.uid,
|
|
email: reconciled.email,
|
|
phoneNumber: reconciled.phoneNumber,
|
|
deletedConflictingUid,
|
|
};
|
|
}
|
|
|
|
async function main() {
|
|
const owner = await ensureUser({
|
|
email: ownerEmail,
|
|
password: ownerPassword,
|
|
displayName: 'Legendary Demo Owner V2',
|
|
});
|
|
|
|
const staff = await ensureUser({
|
|
email: staffEmail,
|
|
password: staffPassword,
|
|
displayName: 'Ana Barista V2',
|
|
});
|
|
|
|
const reconciledStaff = await reconcileStaffPhoneIdentity({
|
|
uid: staff.uid,
|
|
email: staff.email,
|
|
displayName: staff.displayName,
|
|
phoneNumber: staffPhone,
|
|
});
|
|
|
|
// eslint-disable-next-line no-console
|
|
console.log(JSON.stringify({ owner, staff: { ...staff, ...reconciledStaff } }, null, 2));
|
|
}
|
|
|
|
main().catch((error) => {
|
|
// eslint-disable-next-line no-console
|
|
console.error(error);
|
|
process.exit(1);
|
|
});
|