Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: supabase auth #4112

Draft
wants to merge 48 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 44 commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
e02543f
chore: add tenant_id to cypress environment
mariojsnunes Dec 10, 2024
1d508aa
chore: seed database
mariojsnunes Dec 10, 2024
4df42f0
wip questions
mariojsnunes Dec 10, 2024
e3d8b6a
wip questions
mariojsnunes Dec 17, 2024
eb170c5
Merge branch 'master' into feat/questions-supabase
mariojsnunes Dec 20, 2024
69912aa
feat: questions supabase
mariojsnunes Dec 28, 2024
ee6c71d
fix: discussions with supabase questions
mariojsnunes Dec 29, 2024
e58c5f8
fix: notifications with supabase questions;
mariojsnunes Dec 29, 2024
09139cd
feat: image public url and transforms
mariojsnunes Jan 3, 2025
9790968
fix: questions list
mariojsnunes Jan 4, 2025
0469958
merge
mariojsnunes Jan 4, 2025
c8c306a
feat: added sort by comments
mariojsnunes Jan 6, 2025
f42a0a3
fix import
mariojsnunes Jan 7, 2025
d73ce48
questions migration script
mariojsnunes Jan 7, 2025
758b146
Merge branch 'master' into feat/questions-supabase
mariojsnunes Jan 9, 2025
cee0ed1
merge
mariojsnunes Jan 9, 2025
9a5f00a
remove guidance for files
mariojsnunes Jan 9, 2025
3b78489
remove question store
mariojsnunes Jan 9, 2025
27037b2
remove question store
mariojsnunes Jan 9, 2025
35390e5
feat: duplicate question validation and error message
mariojsnunes Jan 9, 2025
43ae242
fix: spec for file category guidance
mariojsnunes Jan 9, 2025
a9cfe8f
Merge branch 'chore/comments-v2-tests' into feat/questions-supabase
mariojsnunes Jan 9, 2025
9beeb20
chore: updated cypress tests with supabase
mariojsnunes Jan 9, 2025
476f89c
chore: update migration script;
mariojsnunes Jan 9, 2025
f71fc3d
fix
mariojsnunes Jan 10, 2025
c08417e
remove unique check
mariojsnunes Jan 10, 2025
2491f44
chore: fix tests to work with supabase;
mariojsnunes Jan 11, 2025
56e8293
fix: edit question submit button
mariojsnunes Jan 11, 2025
be11d96
fix
mariojsnunes Jan 11, 2025
f38567c
fix: library category
mariojsnunes Jan 11, 2025
f6f1b09
wip
mariojsnunes Jan 13, 2025
41a53b3
wip
mariojsnunes Jan 15, 2025
c5c2815
Merge branch 'master' into feat/supabase-auth
mariojsnunes Jan 17, 2025
cbefe2e
wip
mariojsnunes Jan 18, 2025
f50d31d
merge
mariojsnunes Jan 18, 2025
627506b
rollback
mariojsnunes Jan 18, 2025
c24af0d
clean
mariojsnunes Jan 18, 2025
a2a33be
updated apis to use supabase auth;
mariojsnunes Jan 19, 2025
7ac6a95
merge
mariojsnunes Jan 27, 2025
375cbd1
email change
mariojsnunes Jan 27, 2025
d9c0d7a
change password
mariojsnunes Jan 27, 2025
9c568ca
auth work
mariojsnunes Jan 27, 2025
653fec6
cleanup
mariojsnunes Jan 27, 2025
be79325
firebase auth
mariojsnunes Jan 27, 2025
14c8ae0
chore: quick lint
benfurber Jan 28, 2025
fd030f3
feat: add ReturnPathLink for consistent auth flows
benfurber Jan 28, 2025
5459631
fix: ReturnPathLink actually going somewhere
benfurber Jan 28, 2025
84f24f4
feat: add login redirect back to previous page
benfurber Jan 28, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 3 additions & 32 deletions functions/src/supabaseSync/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,6 @@ import { IUser } from 'oa-shared'
* Side-effects to be carried out on various question updates, namely:
* - update the _createdBy user stats with the question id
*********************************************************************/
export const supabaseProfileCreate = functions
.runWith({
memory: '512MB',
secrets: ['SUPABASE_API_URL', 'SUPABASE_API_KEY', 'TENANT_ID'],
})
.firestore.document(`${DB_ENDPOINTS.users}/{id}`)
.onCreate(async (docSnapshot, _) => {
await insertOrUpdateProfile(docSnapshot)
})

export const supabaseProfileUpdate = functions
.runWith({
memory: '512MB',
Expand All @@ -45,16 +35,6 @@ export const supabaseProfileUpdate = functions
}
})

export const supabaseProfileDelete = functions
.runWith({
memory: '512MB',
secrets: ['SUPABASE_API_URL', 'SUPABASE_API_KEY', 'TENANT_ID'],
})
.firestore.document(`${DB_ENDPOINTS.users}/{id}`)
.onDelete(async (docSnapshot, _) => {
await deleteProfile(docSnapshot)
})

async function insertOrUpdateProfile(
docSnapshot: firestore.QueryDocumentSnapshot,
) {
Expand All @@ -64,7 +44,7 @@ async function insertOrUpdateProfile(
const profileRequest = await client
.from('profiles')
.select()
.eq('firebase_auth_id', user._authID)
.eq('username', user.userName)
.limit(1)

if (profileRequest.data?.at(0)) {
Expand All @@ -78,7 +58,7 @@ async function insertOrUpdateProfile(
country: user.location?.countryCode || null,
roles: user.userRoles,
})
.eq('firebase_auth_id', user._authID)
.eq('username', user.userName)

if (error) {
functions.logger.log({ ...error })
Expand All @@ -88,7 +68,6 @@ async function insertOrUpdateProfile(
const { error } = await client
.from('profiles')
.insert({
firebase_auth_id: user._authID,
display_name: user.displayName,
is_verified: user.verified,
photo_url: user.userImage?.downloadUrl || null,
Expand All @@ -97,22 +76,14 @@ async function insertOrUpdateProfile(
username: user.userName,
roles: user.userRoles,
})
.eq('firebase_auth_id', user._authID)
.eq('username', user.userName)

if (error) {
functions.logger.log({ ...error })
}
}
}

async function deleteProfile(docSnapshot: firestore.QueryDocumentSnapshot) {
const { client } = createSupabaseServerClient()

const user = docSnapshot.data() as IUser

await client.from('profiles').delete().eq('firebase_auth_id', user._authID)
}

function arraysAreEqual(arr1: string[], arr2: string[]) {
// Check if lengths are different
if (arr1.length !== arr2.length) {
Expand Down
2 changes: 1 addition & 1 deletion packages/components/src/CreateComment/CreateComment.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ const LoginPrompt = () => {
<Box sx={{ padding: [3, 4] }}>
<Text data-cy="comments-login-prompt">
<Link
to="/sign-in"
to={'/sign-in?returnUrl=' + encodeURIComponent(location.pathname)}
style={{
textDecoration: 'underline',
color: 'inherit',
Expand Down
8 changes: 7 additions & 1 deletion packages/components/src/FollowButton/FollowButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,13 @@ export const FollowButton = (props: IProps) => {
py: 0,
...sx,
}}
onClick={() => (isLoggedIn ? onFollowClick() : navigate('/sign-in'))}
onClick={() =>
isLoggedIn
? onFollowClick()
: navigate(
'/sign-in?returnUrl=' + encodeURIComponent(location.pathname),
)
}
>
{hasUserSubscribed ? 'Following' : 'Follow'}
</Button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,11 @@ export const UsefulStatsButton = (props: IProps) => {
data-tooltip-content={props.isLoggedIn ? '' : 'Login to add your vote'}
data-cy={props.isLoggedIn ? 'vote-useful' : 'vote-useful-redirect'}
onClick={() =>
props.isLoggedIn ? handleUsefulClick() : navigate('/sign-in')
props.isLoggedIn
? handleUsefulClick()
: navigate(
'/sign-in?returnUrl=' + encodeURIComponent(location.pathname),
)
Comment on lines 42 to +47
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Realising this should use the UserAction. I can do that quickly if you like?

}
disabled={disabled}
sx={{
Expand Down
3 changes: 2 additions & 1 deletion src/common/Alerts/AlertProfileVerification.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ export const AlertProfileVerification = () => {

if (!isVerificationSuccessful) {
try {
await userStore.sendEmailVerification()
// TODO
// await userStore.sendEmailVerification()
setVerificationState('sent')
} catch (error) {
setVerificationState('error')
Expand Down
15 changes: 6 additions & 9 deletions src/common/UserAction.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { observer } from 'mobx-react-lite'

import { useCommonStores } from './hooks/useCommonStores'
import { useContext } from 'react'
import { SessionContext } from 'src/pages/common/SessionContext'

interface IProps {
loggedIn: React.ReactNode
Expand All @@ -9,13 +8,11 @@ interface IProps {

type IUserVerificationConditions = 'loggedIn' | 'loggedOut'

export const UserAction = observer((props: IProps) => {
export const UserAction = (props: IProps) => {
const session = useContext(SessionContext)
const { loggedIn, loggedOut } = props

const { userStore } = useCommonStores().stores
const authUser = userStore.authUser

const userCondition: IUserVerificationConditions = authUser
const userCondition: IUserVerificationConditions = session?.id
? 'loggedIn'
: 'loggedOut'

Expand All @@ -25,4 +22,4 @@ export const UserAction = observer((props: IProps) => {
default:
return loggedOut
}
})
}
20 changes: 17 additions & 3 deletions src/pages/Question/QuestionListHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useCallback, useEffect, useState } from 'react'
import { useCallback, useContext, useEffect, useState } from 'react'
import { Link, useSearchParams } from '@remix-run/react'
import debounce from 'debounce'
import { CategoryVerticalList, SearchField, Select } from 'oa-components'
Expand All @@ -11,13 +11,15 @@ import {
import { Button, Flex } from 'theme-ui'

import { ListHeader } from '../common/Layout/ListHeader'
import { SessionContext } from '../common/SessionContext'
import { headings, listing } from './labels'
import { QuestionSortOptions } from './QuestionSortOptions'

import type { Category } from 'oa-shared'
import type { QuestionSortOption } from './QuestionSortOptions'

export const QuestionListHeader = () => {
const session = useContext(SessionContext)
const [categories, setCategories] = useState<Category[]>([])
const [searchString, setSearchString] = useState<string>('')

Expand Down Expand Up @@ -79,14 +81,26 @@ export const QuestionListHeader = () => {
const actionComponents = (
<UserAction
loggedIn={
<Link to="/questions/create">
<Link
to={
session?.id
? '/questions/create'
: '/sign-in?returnUrl=' + encodeURIComponent(location.pathname)
}
>
<Button type="button" data-cy="create-question" variant="primary">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change isn't needed, the user only gets this component if they're logged in.

{listing.create}
</Button>
</Link>
}
loggedOut={
<Link to="/sign-up">
<Link
to={
session?.id
? '/questions/create'
: '/sign-up?returnUrl=' + encodeURIComponent(location.pathname)
}
>
<Button type="button" data-cy="sign-up" variant="primary">
{listing.join}
</Button>
Expand Down
6 changes: 4 additions & 2 deletions src/pages/Research/Content/ResearchListHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useCallback, useEffect, useState } from 'react'
import { useCallback, useContext, useEffect, useState } from 'react'
import { Link, useSearchParams } from '@remix-run/react'
import debounce from 'debounce'
import { CategoryVerticalList, SearchField, Select } from 'oa-components'
Expand All @@ -9,6 +9,7 @@ import { UserAction } from 'src/common/UserAction'
import { isPreciousPlastic } from 'src/config/config'
import DraftButton from 'src/pages/common/Drafts/DraftButton'
import { ListHeader } from 'src/pages/common/Layout/ListHeader'
import { SessionContext } from 'src/pages/common/SessionContext'
import { Button, Flex } from 'theme-ui'

import { RESEARCH_EDITOR_ROLES } from '../constants'
Expand All @@ -35,6 +36,7 @@ const researchStatusOptions = [
]

export const ResearchFilterHeader = (props: IProps) => {
const session = useContext(SessionContext)
const { draftCount, handleShowDrafts, showDrafts } = props

const [categories, setCategories] = useState<ICategory[]>([])
Expand Down Expand Up @@ -106,7 +108,7 @@ export const ResearchFilterHeader = (props: IProps) => {
draftCount={draftCount}
handleShowDrafts={handleShowDrafts}
/>
<Link to="/research/create">
<Link to={session?.id ? '/research/create' : '/sign-in'}>
<Button type="button" variant="primary" data-cy="create">
{listing.create}
</Button>
Expand Down
4 changes: 2 additions & 2 deletions src/pages/Research/Content/ResearchUpdate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -125,11 +125,11 @@ const ResearchUpdate = (props: IProps) => {
<Flex sx={{ flexDirection: 'column' }} py={4} px={4}>
<Flex sx={{ flexDirection: ['column', 'row', 'row'] }}>
<Box sx={{ width: ['100%', '75%', '75%'] }}>
{contributors.length > 0 ? (
{contributors.length > 0 && (
<Box sx={{ mb: 2 }} data-testid="collaborator/creator">
<Username user={contributors[0]} />
</Box>
) : null}
)}
benfurber marked this conversation as resolved.
Show resolved Hide resolved

<Heading as="h2" sx={{ mb: 2 }}>
{title}
Expand Down
Loading
Loading