Skip to content

Commit

Permalink
Merge pull request #252 from w3b3d3v/fix/name-missing-at-login-providers
Browse files Browse the repository at this point in the history
Fix user storage to avoid saving empty data
  • Loading branch information
nomadbitcoin committed Sep 25, 2024
2 parents a595f83 + a0f10ce commit 8b1a679
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 88 deletions.
87 changes: 45 additions & 42 deletions context/AuthContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
} from 'firebase/auth'
import { auth } from '../firebase/initFirebase.js'
import { getUserFromFirestore, createUserinFirestore, updateUserGithub } from '../lib/user.js'
import { useTranslation } from "react-i18next"
import { useTranslation } from 'react-i18next'

const AuthContext = createContext()

Expand Down Expand Up @@ -71,9 +71,9 @@ export function AuthProvider({ children }) {
const signup = (data) => {
setLoading(true)
createUserWithEmailAndPassword(auth, data.email, data.password)
.then((userCredential) => {
.then(async (userCredential) => {
setUser(userCredential.user)
createUserinFirestore(userCredential.user)
await createUserinFirestore(userCredential.user)
Router.push('/courses')
toast.success(t('messages.registration_success'), {
toastParameters,
Expand Down Expand Up @@ -122,7 +122,35 @@ export function AuthProvider({ children }) {
}

const loginGithub = async () => {
return loginWithProvider(GithubAuthProvider)
setLoading(true)
try {
const result = await signInWithPopup(auth, new GithubAuthProvider())
await handleGithubLogin(result.user)
} catch (error) {
console.error('GitHub login error:', error)
toast.error(t('messages.something_wrong_try_again'), {
toastParameters,
})
} finally {
setLoading(false)
}
}

const handleGithubLogin = async (user) => {
const userData = await getUserFromFirestore(user)
if (!userData) {
await createUserinFirestore(user)
}
setUser(user)
const providerData = user.providerData.find((provider) => provider.providerId === 'github.com')
if (providerData) {
const githubUrl = `https://github.com/${providerData.uid}`
await updateUserGithub(githubUrl, user.uid)
}
Router.push('/courses')
toast.success(t('messages.login_success'), {
toastParameters,
})
}

const loginWithProvider = async (Provider) => {
Expand All @@ -133,51 +161,26 @@ export function AuthProvider({ children }) {

useEffect(() => {
async function fetchUser() {
await getRedirectResult(auth)
.then(async (result) => {
const user = result?.user
if (!user) return
const cred = JSON.parse(sessionStorage.getItem('credential'))

if (cred?.providerId == 'github.com') {
await linkGithub(cred, user)
}
const providerObj = user.reloadUserInfo.providerUserInfo[0]
if (providerObj.providerId !== 'github.com') return
await getUserFromFirestore(user)
githubUrl = `https://${providerObj.providerId}/${providerObj.screenName}`
await updateUserGithub(githubUrl, user.uid)
sessionStorage.clear()

toast.success(t('messages.login_success'), {
toastParameters,
})
})
.catch((error) => {
console.log(error)
if (error.code === 'auth/account-exists-with-different-credential') {
const credential = OAuthProvider.credentialFromResult(error.customData)
sessionStorage.setItem('credential', JSON.stringify(credential))
Router.push('/auth')
}
})
try {
const result = await getRedirectResult(auth)
if (result?.user) {
await handleGithubLogin(result.user)
}
} catch (error) {
console.error('Redirect result error:', error)
if (error.code === 'auth/account-exists-with-different-credential') {
const credential = OAuthProvider.credentialFromResult(error.customData)
sessionStorage.setItem('credential', JSON.stringify(credential))
Router.push('/auth')
}
}
}
fetchUser()
if (user) {
mixpanel.identify(user?.uid)
mixpanel.people.set(user)
}
}, [auth.currentUser])

async function linkGithub(cred, user) {
if (user) {
const credential = GithubAuthProvider.credential(cred.accessToken)
const userCredential = await linkWithCredential(user, credential)
githubUrl = JSON.parse(userCredential._tokenResponse.rawUserInfo).html_url
await updateUserGithub(githubUrl, user.uid)
await getUserFromFirestore(user, user.providerData)
}
}
const logout = async () => {
try {
sessionStorage.clear()
Expand Down
14 changes: 3 additions & 11 deletions functions/lib/mailchimp.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,11 @@ exports.createUser = async function (user) {
const result = await mailchimp.lists.addListMember('b578d43584', {
email_address: user.email,
status: 'subscribed',
merge_fields: objectWithUppercasedKeys(user),
full_name: user.name,
merge_fields: { WALLET: user.wallet_address, NAME: user.name },
})
console.log('User added to Mailchimp successfully:')
} catch (error) {
console.error(error)
}
}

function objectWithUppercasedKeys(object) {
const newObject = {}
Object.keys(object).forEach((key) => {
if(object[key]) {
newObject[key.toUpperCase()] = object[key]
}
})
return newObject
}
48 changes: 25 additions & 23 deletions functions/test/lib/mailchimp.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,56 +5,58 @@ jest.mock('@mailchimp/mailchimp_marketing', () => ({
setConfig: jest.fn(),
lists: {
addListMember: jest.fn(),
}
},
}))

describe('add User to list', function() {
describe('add User to list', function () {
beforeEach(() => {
mailchimp.lists.addListMember.mockClear()
})
it("Should add users to list correctly", async () => {
it('Should add users to list correctly', async () => {
const emailData = {
user_email: "[email protected]",
firstName: "John",
lastName: "Doe",
user_email: '[email protected]',
firstName: 'John',
lastName: 'Doe',
params: {
cohort: "test",
course: "test",
cohort: 'cohort_list_id',
course: 'course_list_id',
},
}
await addUserToList(emailData)
expect(mailchimp.setConfig).toHaveBeenCalledTimes(1)
expect(mailchimp.lists.addListMember).toHaveBeenCalledWith("test", {
email_address: "[email protected]",
expect(mailchimp.lists.addListMember).toHaveBeenCalledWith('cohort_list_id', {
email_address: '[email protected]',
status: 'subscribed',
})
expect(mailchimp.lists.addListMember).toHaveBeenCalledWith('course_list_id', {
email_address: '[email protected]',
status: 'subscribed',
})

expect(mailchimp.lists.addListMember).toHaveBeenCalledTimes(2)
})
})

describe("create user in mailchimp", () => {
describe('create user in mailchimp', () => {
beforeEach(() => {
mailchimp.lists.addListMember.mockClear()
})

const user = {
email: "[email protected]",
firstName: "John",
lastName: "Doe",
email: '[email protected]',
name: 'John',
wallet_address: '0x1234567890abcdef',
}

it("Should create user in mailchimp", async () => {
it('Should create user in mailchimp', async () => {
await createUser(user)

expect(mailchimp.lists.addListMember).toHaveBeenCalledWith("b578d43584", {
email_address: "[email protected]",
status: "subscribed",
expect(mailchimp.lists.addListMember).toHaveBeenCalledWith('b578d43584', {
email_address: '[email protected]',
status: 'subscribed',
merge_fields: {
EMAIL: "[email protected]",
FIRSTNAME: "John",
LASTNAME: "Doe",
NAME: 'John',
WALLET: '0x1234567890abcdef',
},
})
})
})
})
32 changes: 20 additions & 12 deletions lib/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,24 @@ export const getUserFromFirestore = async (userCredential) => {
}

export const createUserinFirestore = async (userCredential) => {
const docRef = doc(collectionRef, userCredential.uid)
const docSnap = await getDoc(docRef)

if (docSnap.exists()) {
console.log('User already exists in Firestore')
return
}

let githubUrl = ''
if (userCredential?.providerData) {
const github_id = userCredential.providerData.find(
(item) => item.providerId == 'github.com'
)?.uid
await fetch(`https://api.github.com/user/${github_id}`)
.then((res) => res.json())
.then(async (data) => {
githubUrl = data.html_url
})
if (userCredential.providerData && Array.isArray(userCredential.providerData)) {
const githubProvider = userCredential.providerData.find(
(item) => item.providerId === 'github.com'
)
if (githubProvider) {
githubUrl = `https://github.com/${githubProvider.uid}`
}
}

const userProps = {
uid: userCredential?.uid,
name: userCredential?.displayName || null,
Expand Down Expand Up @@ -65,6 +72,7 @@ export const createUserinFirestore = async (userCredential) => {
},
],
}

mixpanel.track('user_created', userProps)
await setDoc(doc(collectionRef, userProps.uid), userProps)
}
Expand Down Expand Up @@ -168,7 +176,7 @@ export const submitLessonInFirestore = async (

export const findSocialLinks = (name, user) => user?.socialLinks?.find((link) => link.name === name)

export const getUserByDiscordId = async(discordId) => {
export const getUserByDiscordId = async (discordId) => {
const q = query(usersRef, where('discord.id', '==', discordId))
const querySnapshot = await getDocs(q)

Expand All @@ -193,10 +201,10 @@ export const registerUserInStudyGroupInFirestore = async (studyGroupId, userCred
}),
study_group_ids: arrayUnion(studyGroupId),
}

await updateDoc(doc(collectionRef, userCredential), userProps)
mixpanel.track('study_group_signup', studyGroupData)
} else {
console.error(`Study group with ID ${studyGroupId} does not exist`)
}
}
}

0 comments on commit 8b1a679

Please sign in to comment.