Skip to content

Commit 67bd900

Browse files
authored
Merge branch 'master' into beta-new
2 parents 54e474d + ca613e8 commit 67bd900

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+1325
-555
lines changed

functions/index.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ const path = require('path');
1414
const functions = require('firebase-functions/v1');
1515
const express = require('express');
1616
const user = require('./utilities/user');
17+
const privacyRouter = require('./utilities/privacy/router');
1718
const { countries } = require('./utilities/countries')
1819
const isProfileComplete = require('./utilities/profileComplete');
1920
const { getCleanAnswers, getPgPoints } = require('./utilities/pgPoints')
@@ -129,7 +130,12 @@ app.use((req, res, next) => {
129130

130131
app.get('/', (req, res) => res.render('home'));
131132
app.get('/parallelograms', (req, res) => {
132-
const latest = res.locals?.pages[res.locals?.user?.level]?.[0];
133+
// If ?latest is set, redirect to latest PG for their level
134+
// Graduated users are treated as year11 for this purpose
135+
// This avoids a bug where `showWelcomeMsg` gets stuck on true
136+
// because they retain the `latest` query param
137+
const levelWithoutGraduated = (res.locals.user?.level === 'graduated') ? 'year11' : res.locals.user?.level;
138+
const latest = res.locals?.pages[levelWithoutGraduated]?.[0];
133139

134140
if(latest && req.query.latest) {
135141
return res.redirect(`/${latest.url}`)
@@ -152,6 +158,8 @@ app.get('/api/user', async (req, res) => {
152158
})
153159
});
154160

161+
app.use('/api/privacy', privacyRouter)
162+
155163
app.get('/api/get-user', async (req, res) => {
156164
const token = req.headers['parallel-token'];
157165

@@ -193,7 +201,7 @@ app.get('/api/find-user', async (req, res) => {
193201

194202
if(!found) return res.status(401).send({ error: 'no user data found' });
195203

196-
res.status(200).send(getTypeSafeUser({...found, email: authUser.email, privacy: user.getPrivacyState(authUser.email) }))
204+
res.status(200).send(getTypeSafeUser({...found, email: authUser.email, privacy: user.getPrivacyState(authUser.email, found) }))
197205
});
198206

199207
app.get('/api/user-answers', async (req, res) => {
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
const express = require("express");
2+
const router = express.Router();
3+
const firebase = require("firebase-admin");
4+
const {
5+
firstSeenKey,
6+
userNeedsGuardianTouchKey,
7+
guardianPrivacyAuthTokenKey,
8+
acceptedKey,
9+
acceptedByKey,
10+
isUnderThirteen,
11+
getPrivacyState,
12+
generateGuardianPrivacyAuthToken
13+
} = require("./utils");
14+
15+
// /api/privacy/student/ultra-secret/view
16+
// /api/privacy/student/ultra-secret/reset/under13/new
17+
// /api/privacy/student/ultra-secret/reset/under13/8daysago
18+
// /api/privacy/student/ultra-secret/reset/over13/new
19+
// /api/privacy/student/ultra-secret/reset/over13/8daysago
20+
21+
const userDB = firebase.firestore().collection("users");
22+
23+
const studentMiddleware = (req, res, next) => {
24+
if (!res?.locals?.user) {
25+
return res.status(200).send({ error: "not logged in" });
26+
}
27+
next();
28+
};
29+
30+
const getViewData = (req) => {
31+
const allKeys = [
32+
firstSeenKey,
33+
userNeedsGuardianTouchKey,
34+
guardianPrivacyAuthTokenKey,
35+
acceptedKey,
36+
acceptedByKey,
37+
"birthMonth",
38+
"birthYear",
39+
];
40+
41+
const data = {};
42+
43+
allKeys.forEach((key) => {
44+
data[key] = req.user[key] || null;
45+
});
46+
47+
data.privacyState = req.user.privacy || null;
48+
data.isUnderThirteen = isUnderThirteen(req.user);
49+
50+
return data;
51+
};
52+
53+
const getResponseBody = (req, updateBody) => {
54+
return {
55+
data: {
56+
...getViewData(req),
57+
...updateBody,
58+
privacyState: getPrivacyState(req.user.email, { ...req.user, ...updateBody }),
59+
isUnderThirteen: isUnderThirteen({ ...req.user, ...updateBody }),
60+
},
61+
}
62+
}
63+
64+
router.get(
65+
"/reset/under13/new",
66+
studentMiddleware,
67+
async (req, res) => {
68+
const updateBody = {
69+
[firstSeenKey]: null,
70+
[userNeedsGuardianTouchKey]: null,
71+
[guardianPrivacyAuthTokenKey]: null,
72+
[acceptedKey]: null,
73+
[acceptedByKey]: null,
74+
birthMonth: '1',
75+
birthYear: '2025',
76+
};
77+
78+
await userDB.doc(req.user.uid).update(updateBody);
79+
80+
return res.status(200).send(getResponseBody(req, updateBody));
81+
},
82+
);
83+
84+
router.get(
85+
"/reset/over13/new",
86+
studentMiddleware,
87+
async (req, res) => {
88+
const updateBody = {
89+
[firstSeenKey]: null,
90+
[userNeedsGuardianTouchKey]: null,
91+
[guardianPrivacyAuthTokenKey]: null,
92+
[acceptedKey]: null,
93+
[acceptedByKey]: null,
94+
birthMonth: '1',
95+
birthYear: '1990',
96+
};
97+
98+
await userDB.doc(req.user.uid).update(updateBody);
99+
100+
return res.status(200).send(getResponseBody(req, updateBody));
101+
},
102+
);
103+
104+
router.get(
105+
"/reset/under13/8daysago",
106+
studentMiddleware,
107+
async (req, res) => {
108+
const updateBody = {
109+
[firstSeenKey]: Date.now() - (8 * 24 * 60 * 60 * 1000),
110+
[userNeedsGuardianTouchKey]: Date.now() - (8 * 24 * 60 * 60 * 1000),
111+
[guardianPrivacyAuthTokenKey]: generateGuardianPrivacyAuthToken(),
112+
[acceptedKey]: null,
113+
[acceptedByKey]: null,
114+
birthMonth: '1',
115+
birthYear: '2025',
116+
};
117+
118+
await userDB.doc(req.user.uid).update(updateBody);
119+
120+
return res.status(200).send(getResponseBody(req, updateBody));
121+
},
122+
);
123+
124+
router.get(
125+
"/reset/over13/8daysago",
126+
studentMiddleware,
127+
async (req, res) => {
128+
const updateBody = {
129+
[firstSeenKey]: Date.now() - (8 * 24 * 60 * 60 * 1000),
130+
[userNeedsGuardianTouchKey]: null,
131+
[guardianPrivacyAuthTokenKey]: null,
132+
[acceptedKey]: null,
133+
[acceptedByKey]: null,
134+
birthMonth: '1',
135+
birthYear: '1990',
136+
};
137+
138+
await userDB.doc(req.user.uid).update(updateBody);
139+
140+
return res.status(200).send(getResponseBody(req, updateBody));
141+
},
142+
);
143+
144+
router.get(
145+
"/view",
146+
studentMiddleware,
147+
async (req, res) => {
148+
return res.status(200).send({ data: getViewData(req) });
149+
},
150+
);
151+
152+
module.exports = router;

0 commit comments

Comments
 (0)