Skip to content

Commit

Permalink
OAuth login
Browse files Browse the repository at this point in the history
  • Loading branch information
matthieusieben committed Sep 3, 2024
1 parent 7452bcc commit 5caf421
Show file tree
Hide file tree
Showing 102 changed files with 4,541 additions and 2,161 deletions.
10 changes: 9 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
{
"extends": "next/core-web-vitals"
"extends": "next/core-web-vitals",
"rules": {
"react-hooks/exhaustive-deps": [
"warn",
{
"additionalHooks": "(useSignaledEffect)"
}
]
}
}
5 changes: 4 additions & 1 deletion .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ on:
push:
branches:
- main

env:
NEXT_PUBLIC_OZONE_SERVICE_DID: did:plc:ar7c4by46qjdydhdevvrndac
NEXT_PUBLIC_PLC_DIRECTORY_URL: https://plc.directory
NEXT_PUBLIC_HANDLE_RESOLVER_URL: https://api.bsky.app
jobs:
cypress-run:
runs-on: ubuntu-22.04
Expand Down
126 changes: 71 additions & 55 deletions app/actions/ModActionPanel/QuickAction.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// TODO: This is badly named so that we can rebuild this component without breaking the old one
import { useQuery } from '@tanstack/react-query'
import { useQuery, useQueryClient } from '@tanstack/react-query'
import {
ComAtprotoModerationDefs,
ToolsOzoneModerationDefs,
Expand All @@ -10,9 +10,7 @@ import { ActionPanel } from '@/common/ActionPanel'
import { ButtonPrimary, ButtonSecondary } from '@/common/buttons'
import { Checkbox, FormLabel, Input, Textarea } from '@/common/forms'
import { PropsOf } from '@/lib/types'
import client from '@/lib/client'
import { BlobList } from './BlobList'
import { queryClient } from 'components/QueryClient'
import {
LabelChip,
LabelList,
Expand All @@ -38,8 +36,8 @@ import { ActionDurationSelector } from '@/reports/ModerationForm/ActionDurationS
import { MOD_EVENTS } from '@/mod-event/constants'
import { ModEventList } from '@/mod-event/EventList'
import { ModEventSelectorButton } from '@/mod-event/SelectorButton'
import { createSubjectFromId } from '@/reports/helpers/subject'
import { SubjectReviewStateBadge } from '@/subject/ReviewStateMarker'
import { useCreateSubjectFromId } from '@/reports/helpers/subject'
import { getProfileUriForDid } from '@/reports/helpers/subject'
import { Dialog } from '@headlessui/react'
import { SubjectSwitchButton } from '@/common/SubjectSwitchButton'
Expand All @@ -50,7 +48,11 @@ import { DM_DISABLE_TAG, VIDEO_UPLOAD_DISABLE_TAG } from '@/lib/constants'
import { MessageActorMeta } from '@/dms/MessageActorMeta'
import { ModEventDetailsPopover } from '@/mod-event/DetailsPopover'
import { LockClosedIcon } from '@heroicons/react/24/solid'
import { checkPermission } from '@/lib/server-config'
import {
useConfigurationContext,
useLabelerAgent,
usePermission,
} from '@/shell/ConfigurationContext'

const FORM_ID = 'mod-action-panel'
const useBreakpoint = createBreakpoint({ xs: 340, sm: 640 })
Expand Down Expand Up @@ -144,7 +146,10 @@ export function ModActionPanelQuick(
const getDeactivatedAt = ({
repo,
record,
}: Awaited<ReturnType<typeof getSubject>>) => {
}: {
repo?: ToolsOzoneModerationDefs.RepoViewDetail
record?: ToolsOzoneModerationDefs.RecordViewDetail
}) => {
const deactivatedAt = repo?.deactivatedAt || record?.repo?.deactivatedAt

if (!deactivatedAt) {
Expand All @@ -160,6 +165,11 @@ function Form(
replaceFormWithEvents: boolean
} & Pick<Props, 'setSubject' | 'subject' | 'subjectOptions' | 'onSubmit'>,
) {
const { config } = useConfigurationContext()
const queryClient = useQueryClient()
const labelerAgent = useLabelerAgent()
const accountDid = labelerAgent.assertDid

const {
subject,
setSubject,
Expand All @@ -173,16 +183,13 @@ function Form(
isSubmitting: boolean
error: string
}>({ isSubmitting: false, error: '' })
const { data: subjectStatus, refetch: refetchSubjectStatus } = useQuery({
// subject of the report
queryKey: ['modSubjectStatus', { subject }],
queryFn: () => getSubjectStatus(subject),
})
const { data: { record, repo } = {}, refetch: refetchSubject } = useQuery({
// subject of the report
queryKey: ['modActionSubject', { subject }],
queryFn: () => getSubject(subject),
})

const { data: subjectStatus, refetch: refetchSubjectStatus } =
useSubjectStatusQuery(subject)

const { data: { record, repo } = {}, refetch: refetchSubject } =
useSubjectQuery(subject)

const isSubjectDid = subject.startsWith('did:')
const isReviewClosed =
subjectStatus?.reviewState === ToolsOzoneModerationDefs.REVIEWCLOSED
Expand All @@ -207,7 +214,7 @@ function Form(
const deactivatedAt = getDeactivatedAt(
repo ? { repo } : record ? { record } : {},
)
const canManageChat = checkPermission('canManageChat')
const canManageChat = usePermission('canManageChat')

// navigate to next or prev report
const navigateQueue = (delta: 1 | -1) => {
Expand Down Expand Up @@ -253,6 +260,9 @@ function Form(
window.removeEventListener('keydown', downHandler)
}
}, [])

const createSubjectFromId = useCreateSubjectFromId()

// on form submit
const onFormSubmit = async (
ev: FormEvent<HTMLFormElement> & { target: HTMLFormElement },
Expand Down Expand Up @@ -380,7 +390,7 @@ function Form(
labelSubmissions.push(
onSubmit({
subject: { ...subjectInfo, cid: labelCid },
createdBy: client.session.did,
createdBy: accountDid,
subjectBlobCids: formData
.getAll('subjectBlobCids')
.map((cid) => String(cid)),
Expand All @@ -402,7 +412,7 @@ function Form(
labelSubmissions.push(
onSubmit({
subject: subjectInfo,
createdBy: client.session.did,
createdBy: accountDid,
subjectBlobCids: formData
.getAll('subjectBlobCids')
.map((cid) => String(cid)),
Expand All @@ -415,7 +425,7 @@ function Form(
} else {
await onSubmit({
subject: subjectInfo,
createdBy: client.session.did,
createdBy: accountDid,
subjectBlobCids,
event: coreEvent,
})
Expand All @@ -424,7 +434,7 @@ function Form(
if (formData.get('additionalAcknowledgeEvent')) {
await onSubmit({
subject: subjectInfo,
createdBy: client.session.did,
createdBy: accountDid,
subjectBlobCids: formData
.getAll('subjectBlobCids')
.map((cid) => String(cid)),
Expand Down Expand Up @@ -680,9 +690,8 @@ function Form(
name="labels"
formId={FORM_ID}
defaultLabels={currentLabels.filter((label) => {
const serviceDid = client.getServiceDid()?.split('#')[0]
const isExternalLabel = allLabels.some((l) => {
return l.val === label && l.src !== serviceDid
return l.val === label && l.src !== config.did
})
return !isSelfLabel(label) && !isExternalLabel
})}
Expand Down Expand Up @@ -830,41 +839,48 @@ function Form(
)
}

async function getSubject(subject: string) {
if (subject.startsWith('did:')) {
const { data: repo } = await client.api.tools.ozone.moderation.getRepo(
{
did: subject,
},
{ headers: client.proxyHeaders() },
)
return { repo }
} else if (subject.startsWith('at://')) {
const { data: record } = await client.api.tools.ozone.moderation.getRecord(
{
uri: subject,
},
{ headers: client.proxyHeaders() },
)

return { record }
} else {
return {}
}
function useSubjectQuery(subject: string) {
const labelerAgent = useLabelerAgent()

return useQuery({
// subject of the report
queryKey: ['modActionSubject', { subject }],
queryFn: async () => {
if (subject.startsWith('did:')) {
const { data: repo } =
await labelerAgent.api.tools.ozone.moderation.getRepo({
did: subject,
})
return { repo }
} else if (subject.startsWith('at://')) {
const { data: record } =
await labelerAgent.api.tools.ozone.moderation.getRecord({
uri: subject,
})
return { record }
} else {
return {}
}
},
})
}

async function getSubjectStatus(subject: string) {
const {
data: { subjectStatuses },
} = await client.api.tools.ozone.moderation.queryStatuses(
{
subject,
includeMuted: true,
limit: 1,
function useSubjectStatusQuery(subject: string) {
const labelerAgent = useLabelerAgent()
return useQuery({
// subject of the report
queryKey: ['modSubjectStatus', { subject }],
queryFn: async () => {
const {
data: { subjectStatuses },
} = await labelerAgent.api.tools.ozone.moderation.queryStatuses({
subject,
includeMuted: true,
limit: 1,
})
return subjectStatuses.at(0) || null
},
{ headers: client.proxyHeaders() },
)
return subjectStatuses.at(0) || null
})
}

function isMultiPress(ev: KeyboardEvent) {
Expand Down
12 changes: 5 additions & 7 deletions app/actions/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
'use client'
import { useQuery } from '@tanstack/react-query'
import client from '@/lib/client'
import { Loading, LoadingFailed } from '@/common/Loader'
import { EventView } from '@/mod-event/View'
import { useLabelerAgent } from '@/shell/ConfigurationContext'

export default function Action({ params }: { params: { id: string } }) {
const labelerAgent = useLabelerAgent()
const id = decodeURIComponent(params.id)

const { data: action, error } = useQuery({
queryKey: ['action', { id }],
queryFn: async () => {
const { data } = await client.api.tools.ozone.moderation.getEvent(
{
id: parseInt(id, 10),
},
{ headers: client.proxyHeaders() },
)
const { data } = await labelerAgent.api.tools.ozone.moderation.getEvent({
id: parseInt(id, 10),
})
return data
},
})
Expand Down
7 changes: 4 additions & 3 deletions app/communication-template/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,8 @@ import { Loading, LoadingFailed } from '@/common/Loader'
import { useCommunicationTemplateList } from 'components/communication-template/hooks'
import { CommunicationTemplateDeleteConfirmationModal } from 'components/communication-template/delete-confirmation-modal'
import { ActionButton, LinkButton } from '@/common/buttons'
import client from '@/lib/client'
import { ErrorInfo } from '@/common/ErrorInfo'
import { checkPermission } from '@/lib/server-config'
import { usePermission } from '@/shell/ConfigurationContext'

export default function CommunicationTemplatePage() {
const { data, error, isLoading } = useCommunicationTemplateList({})
Expand All @@ -25,7 +24,9 @@ export default function CommunicationTemplatePage() {
: []
useTitle(`Communication Templates`)

if (!checkPermission('canManageTemplates')) {
const canManageTemplates = usePermission('canManageTemplates')

if (!canManageTemplates) {
return (
<ErrorInfo type="warn">
Sorry, you don{"'"}t have permission to manage communication templates.
Expand Down
21 changes: 9 additions & 12 deletions app/configure/page-content.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import { useEffect } from 'react'
import { useTitle } from 'react-use'
import client from '@/lib/client'
import { useSession } from '@/lib/useSession'
import { Tabs, TabView } from '@/common/Tabs'
import { LabelerConfig } from 'components/config/Labeler'
import { MemberConfig } from 'components/config/Member'
import { ModActionPanelQuick } from 'app/actions/ModActionPanel/QuickAction'
import { ToolsOzoneModerationEmitEvent } from '@atproto/api'
import { emitEvent } from '@/mod-event/helpers/emitEvent'
import { useEmitEvent } from '@/mod-event/helpers/emitEvent'
import { usePathname, useSearchParams, useRouter } from 'next/navigation'
import { useConfigurationContext } from '@/shell/ConfigurationContext'
import { WorkspacePanel } from '@/workspace/Panel'
import { useWorkspaceOpener } from '@/common/useWorkspaceOpener'

Expand All @@ -24,11 +23,12 @@ const TabKeys = {

export default function ConfigurePageContent() {
useTitle('Configure')
const session = useSession()
useEffect(() => {
client.reconfigure() // Ensure config is up to date
}, [])
const isServiceAccount = !!session && session?.did === session?.config.did

const { reconfigure } = useConfigurationContext()
useEffect(() => void reconfigure(), [reconfigure]) // Ensure config is up to date

const emitEvent = useEmitEvent()

const searchParams = useSearchParams()
const router = useRouter()
const pathname = usePathname()
Expand All @@ -54,7 +54,6 @@ export default function ConfigurePageContent() {
router.push((pathname ?? '') + '?' + newParams.toString())
}

if (!session) return null
const views: TabView<Views>[] = [
{
view: Views.Configure,
Expand All @@ -74,9 +73,7 @@ export default function ConfigurePageContent() {
views={views}
fullWidth
/>
{currentView === Views.Configure && (
<LabelerConfig session={session} isServiceAccount={isServiceAccount} />
)}
{currentView === Views.Configure && <LabelerConfig />}
{currentView === Views.Members && <MemberConfig />}

<ModActionPanelQuick
Expand Down
13 changes: 6 additions & 7 deletions app/events/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
'use client'
import { useQuery } from '@tanstack/react-query'
import { useTitle } from 'react-use'
import client from '@/lib/client'

import { Loading, LoadingFailed } from '@/common/Loader'
import { EventView } from '@/mod-event/View'
import { MOD_EVENT_TITLES } from '@/mod-event/constants'
import { useLabelerAgent } from '@/shell/ConfigurationContext'

export default function EventViewPage({ params }: { params: { id: string } }) {
const id = decodeURIComponent(params.id)
const labelerAgent = useLabelerAgent()
const { data: event, error } = useQuery({
queryKey: ['event', { id }],
queryFn: async () => {
const { data } = await client.api.tools.ozone.moderation.getEvent(
{
id: parseInt(id, 10),
},
{ headers: client.proxyHeaders() },
)
const { data } = await labelerAgent.api.tools.ozone.moderation.getEvent({
id: parseInt(id, 10),
})
return data
},
})
Expand Down
Loading

0 comments on commit 5caf421

Please sign in to comment.