mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-05-28 18:26:54 +00:00
feat: add email sign up alert (#61218)
Co-authored-by: Niraj Nandish <nirajnandish@icloud.com> Co-authored-by: Mrugesh Mohapatra <1884376+raisedadead@users.noreply.github.com> Co-authored-by: Oliver Eyton-Williams <ojeytonwilliams@gmail.com> Co-authored-by: Shaun Hamilton <shauhami020@gmail.com>
This commit is contained in:
@@ -147,7 +147,8 @@ model user {
|
||||
/// Valuable for selectively performing random logic.
|
||||
rand Float?
|
||||
savedChallenges SavedChallenge[] // Undefined | SavedChallenge[]
|
||||
sendQuincyEmail Boolean
|
||||
// Nullable tri-state: null (likely new user), true (subscribed), false (unsubscribed)
|
||||
sendQuincyEmail Boolean?
|
||||
theme String? // Undefined
|
||||
timezone String? // Undefined
|
||||
twitter String? // Null | Undefined
|
||||
|
||||
@@ -79,7 +79,7 @@ export const newUser = (email: string) => ({
|
||||
progressTimestamps: [expect.any(Number)],
|
||||
rand: null, // TODO(Post-MVP): delete from schema (it's not used or required).
|
||||
savedChallenges: [],
|
||||
sendQuincyEmail: false,
|
||||
sendQuincyEmail: null,
|
||||
theme: 'default',
|
||||
timezone: null,
|
||||
twitter: null,
|
||||
|
||||
@@ -332,26 +332,6 @@ describe('auth0 plugin', () => {
|
||||
expect(res.headers.location).toMatch(HOME_LOCATION);
|
||||
});
|
||||
|
||||
test('should redirect to email-sign-up if the user has not acceptedPrivacyTerms', async () => {
|
||||
mockAuthSuccess();
|
||||
// Using an italian path to make sure redirection works.
|
||||
const italianReturnTo = 'https://www.freecodecamp.org/italian/settings';
|
||||
|
||||
const res = await fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/auth/auth0/callback?state=valid',
|
||||
cookies: {
|
||||
'login-returnto': sign(italianReturnTo)
|
||||
}
|
||||
});
|
||||
|
||||
expect(res.headers.location).toEqual(
|
||||
expect.stringContaining(
|
||||
'https://www.freecodecamp.org/italian/email-sign-up?'
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
test('should populate the user with the correct data', async () => {
|
||||
mockAuthSuccess();
|
||||
|
||||
|
||||
@@ -15,10 +15,7 @@ import {
|
||||
} from '../utils/env';
|
||||
import { findOrCreateUser } from '../routes/helpers/auth-helpers';
|
||||
import { createAccessToken } from '../utils/tokens';
|
||||
import {
|
||||
getLoginRedirectParams,
|
||||
getPrefixedLandingPath
|
||||
} from '../utils/redirection';
|
||||
import { getLoginRedirectParams } from '../utils/redirection';
|
||||
|
||||
declare module 'fastify' {
|
||||
interface FastifyInstance {
|
||||
@@ -108,8 +105,7 @@ export const auth0Client: FastifyPluginCallbackTypebox = fp(
|
||||
}
|
||||
}
|
||||
|
||||
const { returnTo, pathPrefix, origin } = getLoginRedirectParams(req);
|
||||
const redirectBase = getPrefixedLandingPath(origin, pathPrefix);
|
||||
const { returnTo } = getLoginRedirectParams(req);
|
||||
|
||||
let token;
|
||||
try {
|
||||
@@ -166,24 +162,14 @@ export const auth0Client: FastifyPluginCallbackTypebox = fp(
|
||||
});
|
||||
}
|
||||
|
||||
const { id, acceptedPrivacyTerms } = await findOrCreateUser(
|
||||
fastify,
|
||||
email
|
||||
);
|
||||
const { id } = await findOrCreateUser(fastify, email);
|
||||
|
||||
reply.setAccessTokenCookie(createAccessToken(id));
|
||||
|
||||
if (acceptedPrivacyTerms) {
|
||||
void reply.redirectWithMessage(returnTo, {
|
||||
type: 'success',
|
||||
content: 'flash.signin-success'
|
||||
});
|
||||
} else {
|
||||
void reply.redirectWithMessage(`${redirectBase}/email-sign-up`, {
|
||||
type: 'success',
|
||||
content: 'flash.signin-success'
|
||||
});
|
||||
}
|
||||
void reply.redirectWithMessage(returnTo, {
|
||||
type: 'success',
|
||||
content: 'flash.signin-success'
|
||||
});
|
||||
});
|
||||
|
||||
done();
|
||||
|
||||
@@ -151,7 +151,8 @@ const testUserData: Prisma.userCreateInput = {
|
||||
],
|
||||
yearsTopContributor: ['2018'],
|
||||
twitter: '@foobar',
|
||||
linkedin: 'linkedin.com/foobar'
|
||||
linkedin: 'linkedin.com/foobar',
|
||||
sendQuincyEmail: false
|
||||
};
|
||||
|
||||
const minimalUserData: Prisma.userCreateInput = {
|
||||
@@ -301,6 +302,7 @@ const publicUserData = {
|
||||
profileUI: testUserData.profileUI,
|
||||
savedChallenges: testUserData.savedChallenges,
|
||||
twitter: 'https://twitter.com/foobar',
|
||||
sendQuincyEmail: testUserData.sendQuincyEmail,
|
||||
username: testUserData.username,
|
||||
usernameDisplay: testUserData.usernameDisplay,
|
||||
website: testUserData.website,
|
||||
|
||||
@@ -697,6 +697,7 @@ export const userGetRoutes: FastifyPluginCallbackTypebox = (
|
||||
user: {
|
||||
[username]: {
|
||||
...removeNulls(publicUser),
|
||||
sendQuincyEmail: publicUser.sendQuincyEmail,
|
||||
...normalizeFlags(flags),
|
||||
picture: publicUser.picture ?? '',
|
||||
email: email ?? '',
|
||||
|
||||
@@ -26,6 +26,7 @@ vi.spyOn(globalThis, 'fetch').mockImplementation(mockedFetch);
|
||||
// This is used to build a test user.
|
||||
const testUserData: Prisma.userCreateInput = {
|
||||
...createUserInput(defaultUserEmail),
|
||||
sendQuincyEmail: true,
|
||||
username: 'foobar',
|
||||
usernameDisplay: 'Foo Bar',
|
||||
progressTimestamps: [1520002973119, 1520440323273],
|
||||
|
||||
@@ -108,7 +108,7 @@ export const getSessionUser = {
|
||||
})
|
||||
),
|
||||
profileUI: Type.Optional(profileUI),
|
||||
sendQuincyEmail: Type.Boolean(),
|
||||
sendQuincyEmail: Type.Union([Type.Null(), Type.Boolean()]), // // Tri-state: null (likely new user), true (subscribed), false (unsubscribed)
|
||||
theme: Type.String(),
|
||||
twitter: Type.Optional(Type.String()),
|
||||
website: Type.Optional(Type.String()),
|
||||
|
||||
@@ -82,7 +82,7 @@ export function createUserInput(email: string) {
|
||||
showPortfolio: false,
|
||||
showTimeLine: false
|
||||
},
|
||||
sendQuincyEmail: false,
|
||||
sendQuincyEmail: null,
|
||||
theme: 'default',
|
||||
username,
|
||||
usernameDisplay: username,
|
||||
|
||||
Reference in New Issue
Block a user