File size: 2,530 Bytes
c904036
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/*
 * Migration: Backfill auth flags on User documents
 * - passwordSetup: boolean (true if user has explicitly set a password)
 * - authMethods: ['password','google']
 * - primaryAuthMethod: 'password' | 'google'
 *
 * Heuristics:
 * - If passwordSetup is undefined, infer from passwordHash containing 'google_user_' (legacy google-first accounts)
 * - If googleLinked true, include 'google' in authMethods
 * - If passwordSetup true, include 'password' in authMethods
 * - If primaryAuthMethod missing, prefer 'google' when googleLinked && !passwordSetup, else 'password'
 */

const mongoose = require('mongoose');
const User = require('../Models/User');

async function run() {
  const mongoUri =
    process.env.MONGO_URI || 'mongodb://127.0.0.1:27017/campverse';
  await mongoose.connect(mongoUri);
  process.stdout.write('Connected to MongoDB\n');

  const cursor = User.find({}).cursor();
  let examined = 0;
  let updated = 0;

  for (
    let user = await cursor.next();
    user != null;
    user = await cursor.next()
  ) {
    examined += 1;
    const changes = {};

    // passwordSetup inference
    if (typeof user.passwordSetup !== 'boolean') {
      const isGoogleGenerated =
        typeof user.passwordHash === 'string' &&
        user.passwordHash.includes('google_user_');
      changes.passwordSetup = !isGoogleGenerated;
    }

    // authMethods
    const methods = new Set(
      Array.isArray(user.authMethods) ? user.authMethods : [],
    );
    const effectivePasswordSetup =
      typeof changes.passwordSetup === 'boolean'
        ? changes.passwordSetup
        : !!user.passwordSetup;
    if (effectivePasswordSetup) methods.add('password');
    if (user.googleLinked) methods.add('google');
    const authMethods = Array.from(methods);
    if (
      authMethods.length !== (user.authMethods ? user.authMethods.length : 0) ||
      (user.authMethods || []).some((m) => !methods.has(m))
    ) {
      changes.authMethods = authMethods;
    }

    // primaryAuthMethod
    if (!user.primaryAuthMethod) {
      changes.primaryAuthMethod =
        user.googleLinked && !effectivePasswordSetup ? 'google' : 'password';
    }

    if (Object.keys(changes).length > 0) {
      await User.updateOne({ _id: user._id }, { $set: changes });
      updated += 1;
    }
  }

  process.stdout.write(`Examined: ${examined}, Updated: ${updated}\n`);
  await mongoose.disconnect();
  process.stdout.write('Done\n');
}

run().catch((err) => {
  process.stderr.write(`${err?.stack || err}\n`);
  process.exit(1);
});