Skip to content

Commit 00ba391

Browse files
authored
Merge branch 'master' into beta-new
2 parents ee67ae7 + 6981fec commit 00ba391

8 files changed

Lines changed: 264 additions & 28 deletions

File tree

functions/utilities/privacy/debugRouter.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
const express = require("express");
22
const router = express.Router();
33
const firebase = require("firebase-admin");
4+
const {
5+
isUnderThirteen,
6+
getPrivacyState,
7+
generateGuardianPrivacyAuthToken,
8+
} = require("./utils");
49
const {
510
firstSeenKey,
611
dueByKey,
@@ -10,10 +15,7 @@ const {
1015
acceptedByKey,
1116
variantModeKey,
1217
latestTouchKey,
13-
isUnderThirteen,
14-
getPrivacyState,
15-
generateGuardianPrivacyAuthToken,
16-
} = require("./utils");
18+
} = require("./privacyKeys");
1719

1820
// /api/privacy/student/ultra-secret/view (GET)
1921
// /api/privacy/student/ultra-secret/reset (POST)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
const latestPrivacyVersion = 'privacy-sept-2025-001';
2+
3+
const firstSeenKey = `${latestPrivacyVersion}-firstSeen`;
4+
const latestTouchKey = `${latestPrivacyVersion}-latestTouch`;
5+
const dueByKey = `${latestPrivacyVersion}-dueBy`;
6+
const userNeedsGuardianTouchKey = `${latestPrivacyVersion}-ng-touch`;
7+
const guardianPrivacyAuthTokenKey = "guardianPrivacyAuthToken";
8+
const acceptedKey = `${latestPrivacyVersion}-accepted`;
9+
const acceptedByKey = `${latestPrivacyVersion}-acceptedBy`;
10+
const variantModeKey = `${latestPrivacyVersion}-variant`;
11+
12+
module.exports = {
13+
firstSeenKey,
14+
latestTouchKey,
15+
dueByKey,
16+
userNeedsGuardianTouchKey,
17+
guardianPrivacyAuthTokenKey,
18+
acceptedKey,
19+
acceptedByKey,
20+
variantModeKey,
21+
};

functions/utilities/privacy/router.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,17 @@ const router = express.Router();
33
const firebase = require("firebase-admin");
44
const {
55
generateGuardianPrivacyAuthToken,
6+
validateGuardianToken,
7+
} = require("./utils");
8+
const {
69
firstSeenKey,
710
dueByKey,
811
userNeedsGuardianTouchKey,
912
guardianPrivacyAuthTokenKey,
1013
acceptedKey,
1114
acceptedByKey,
12-
latestTouchKey,
13-
validateGuardianToken,
14-
} = require("./utils");
15+
latestTouchKey
16+
} = require("./privacyKeys");
1517
const debugRouter = require("./debugRouter");
1618

1719
router.use("/student/ultra-secret", debugRouter);

functions/utilities/privacy/utils.js

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
11
const firebase = require("firebase-admin");
2+
const {
3+
firstSeenKey,
4+
latestTouchKey,
5+
dueByKey,
6+
acceptedKey,
7+
variantModeKey,
8+
} = require("./privacyKeys");
29

310
const userDB = firebase.firestore().collection("users");
411

@@ -8,18 +15,6 @@ function generateGuardianPrivacyAuthToken() {
815
.toLowerCase();
916
}
1017

11-
// const latestPrivacyVersion = 'privacy-sept-2025-001';
12-
const latestPrivacyVersion = "privacy-testing-002";
13-
14-
const firstSeenKey = `${latestPrivacyVersion}-firstSeen`;
15-
const latestTouchKey = `${latestPrivacyVersion}-latestTouch`;
16-
const dueByKey = `${latestPrivacyVersion}-dueBy`;
17-
const userNeedsGuardianTouchKey = `${latestPrivacyVersion}-ng-touch`;
18-
const guardianPrivacyAuthTokenKey = "guardianPrivacyAuthToken";
19-
const acceptedKey = `${latestPrivacyVersion}-accepted`;
20-
const acceptedByKey = `${latestPrivacyVersion}-acceptedBy`;
21-
const variantModeKey = `${latestPrivacyVersion}-variant`;
22-
2318
const supportedCustomVariants = ['year8webinar']
2419

2520
const getCleanNumber = (n) => {
@@ -168,14 +163,5 @@ async function validateGuardianToken(req) {
168163

169164
exports.getPrivacyState = getPrivacyState;
170165
exports.generateGuardianPrivacyAuthToken = generateGuardianPrivacyAuthToken;
171-
exports.firstSeenKey = firstSeenKey;
172-
exports.dueByKey = dueByKey;
173-
exports.guardianPrivacyAuthTokenKey = guardianPrivacyAuthTokenKey;
174-
exports.acceptedKey = acceptedKey;
175-
exports.acceptedByKey = acceptedByKey;
176-
exports.latestPrivacyVersion = latestPrivacyVersion;
177166
exports.validateGuardianToken = validateGuardianToken;
178-
exports.userNeedsGuardianTouchKey = userNeedsGuardianTouchKey;
179167
exports.isUnderThirteen = isUnderThirteen;
180-
exports.variantModeKey = variantModeKey;
181-
exports.latestTouchKey = latestTouchKey;

package-lock.json

Lines changed: 70 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
"aws-sdk": "^2.1252.0",
6565
"caniuse-lite": "^1.0.3",
6666
"concurrently": "^7.3.0",
67+
"csvtojson": "^2.0.10",
6768
"firebase": "^9.0.0",
6869
"firebase-functions": "^6.3.2",
6970
"firebase-tools": "^13.33.0",

scripts/privacy-approve.js

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
const fs = require('fs');
2+
const path = require('path');
3+
const fb = require('firebase-admin');
4+
const csv = require("csvtojson");
5+
const serviceAccount = require('../private/service-account.json');
6+
const {
7+
acceptedKey,
8+
acceptedByKey,
9+
} = require('../functions/utilities/privacy/privacyKeys');
10+
11+
// --------
12+
13+
const csvPath = "/Users/drew.mcmillan/Downloads/exemptfromprivacypolicy.csv";
14+
const emailField = 'email';
15+
const dryRun = true; // when true, will just log what it will write, but not save it
16+
17+
// --------
18+
// here be dragons
19+
//
20+
21+
fb.initializeApp({
22+
credential: fb.credential.cert(serviceAccount),
23+
databaseURL: 'https://parallel-cf800.firebaseio.com'
24+
});
25+
26+
const userDb = fb.firestore().collection('users');
27+
28+
const run = async () => {
29+
const file = path.join(__dirname, `../private/tmp-users.json`);
30+
const accounts = JSON.parse(fs.readFileSync(file)).users;
31+
32+
const accountsByEmail = accounts.reduce((acc, account) => {
33+
acc[account.email.toLowerCase()] = account;
34+
return acc
35+
}, {});
36+
37+
let csvData;
38+
39+
try {
40+
csvData = await csv().fromFile(csvPath);
41+
} catch (error) {
42+
console.error(`\nError reading csv file: ${error.message}\n`);
43+
}
44+
45+
const data = csvData.map(d => {
46+
const account = accountsByEmail[d.email.toLowerCase()];
47+
48+
if (account) {
49+
return {
50+
id: account.localId,
51+
...d,
52+
}
53+
} else {
54+
console.log(`\nAccount not found for ${d.email}\n`);
55+
process.exit(1);
56+
}
57+
});
58+
59+
for (const d of data) {
60+
const id = d.id;
61+
62+
const mergeBody = {
63+
[acceptedKey]: Date.now(),
64+
[acceptedByKey]: "guardian-via-admin",
65+
};
66+
67+
console.log(`\nUpdating ${d.email} (${id}) with`);
68+
console.log(mergeBody);
69+
70+
if (!dryRun) {
71+
await userDb.doc(id).set(mergeBody, {merge: true});
72+
}
73+
}
74+
}
75+
76+
77+
run();

0 commit comments

Comments
 (0)