1
0
Fork 0

[org] fix: Don't hammer backend when consent is lacking

This commit is contained in:
joostdecock 2025-04-23 20:30:57 +02:00
parent aaed36a46a
commit f9d68bd2e1
3 changed files with 66 additions and 26 deletions

View file

@ -181,6 +181,21 @@ export const Hits = ({ results, Link = false }) => {
export const User = ({ user, Link }) => {
const { setModal } = useContext(ModalContext)
const { setLoadingStatus } = useContext(LoadingStatusContext)
const backend = useBackend()
/*
* We had a bug with the signUp flow where consent was
* not set. Users cannot get out of this, so this allows
* admins to grant consent on their behalf.
*/
const setConsent = async () => {
setLoadingStatus([true, 'Contacting backend'])
const [status, body] = await backend.adminUpdateUser({ id: user.id, data: { consent: 2 } })
if (status === 200 && body.result === 'success') {
setLoadingStatus([true, 'Consent updated', true, true])
} else setLoadingStatus([true, 'An error occured', true, false])
}
return (
<div className="tw:flex tw:flex-row tw:w-full tw:gap-4 tw:my-2">
@ -222,6 +237,14 @@ export const User = ({ user, Link }) => {
Details
</button>
<ImpersonateButton userId={user.id} />
{user.consent < 1 ? (
<button
className="tw:daisy-btn tw:daisy-btn-warning tw:daisy-btn-sm"
onClick={setConsent}
>
Grant Consent
</button>
) : null}
</div>
</div>
</div>

View file

@ -8,11 +8,9 @@ import { useBackend } from '@freesewing/react/hooks/useBackend'
import { Link as DefaultLink } from '@freesewing/react/components/Link'
import { LockIcon, PlusIcon } from '@freesewing/react/components/Icon'
import { Spinner } from '@freesewing/react/components/Spinner'
import { Popout } from '@freesewing/react/components/Popout'
import { H1, H2, H3 } from '@freesewing/react/components/Heading'
//import { ConsentForm, ns as gdprNs } from 'shared/components/gdpr/form.mjs'
const ConsentForm = () => null
import { Consent } from '@freesewing/react/components/Account'
const Wrap = ({ children }) => (
<div className="tw:m-auto tw:max-w-xl tw:text-center tw:mt-8 tw:p-8">{children}</div>
@ -144,7 +142,20 @@ const ConsentLacking = ({ banner, refresh }) => {
<Wrap>
<div className="tw:text-left">
{banner}
<ConsentForm submit={updateConsent} />
<Popout warning>
<h2>Your account lacks consent</h2>
<p>
This should have been taken care of when onboarding your account, but due to a earlier
bug in the registration, a small subsection of accounts ended up in this state.
</p>
<p>
Please complete the form to give your consent, that may resolve the matter.
<br />
If it does not, please <a href="/support">contact support</a> so we may help you.
</p>
</Popout>
<h1>Consent & Privacy</h1>
<Consent submit={updateConsent} />
</div>
</Wrap>
)
@ -167,32 +178,35 @@ export const RoleBlock = ({ children, user = false, Link = false }) => {
* Avoid hydration errors
*/
useEffect(() => {
if (admin?.account?.username && account?.username)
if (admin?.account?.username && account?.username && !impersonating.admin)
setImpersonating({
admin: admin.account.username,
user: account.username,
})
}, [admin])
useEffect(() => {
const verifyUser = async () => {
const [status, data] = await backend.ping()
if (status === 200 && data.result === 'success') {
// Refresh account in local storage
setAccount({
...account,
...data.account,
bestBefore: Date.now() + 3600000,
})
} else {
if (data?.error?.error) setError(data.error.error)
if (!error) {
const [status, data] = await backend.ping()
if (status === 200 && data.result === 'success') {
// Refresh account in local storage
setAccount({
...account,
...data.account,
bestBefore: Date.now() + 3600000,
})
} else if (status === 451) setError('consentLacking')
else {
signOut()
console.log({ status, data })
if (data?.error?.error) setError(data.error.error)
else signOut()
}
setReady(true)
}
setReady(true)
}
if (token) {
// Don't hammer the backend. Check once per hour.
if (!account.bestBefore || account.bestBefore < Date.now()) verifyUser()
}
// Don't hammer the backend. Check once per hour.
if (token && !error && (!account.bestBefore || account.bestBefore < Date.now())) verifyUser()
setReady(true)
}, [admin, refreshCount, signOut])
@ -201,7 +215,7 @@ export const RoleBlock = ({ children, user = false, Link = false }) => {
setError(false)
}
if (!ready) return <Spinner />
if (!ready) <Spinner />
const banner = impersonating ? (
<div className="tw:bg-warning tw:rounded-lg tw:shadow tw:py-4 tw:px-6 tw:flex tw:flex-row tw:items-center tw:gap-4 tw:justify-between">

View file

@ -3,10 +3,13 @@ title: Your Account
sidebar_label: Account
---
import { DocusaurusDoc } from '@freesewing/react/components/Docusaurus'
import { RoleBlock } from '@freesewing/react/components/Role'
import { Links as AccountLinks } from '@freesewing/react/components/Account'
import Link from '@docusaurus/Link'
<RoleBlock user>
<AccountLinks Link={Link} />
</RoleBlock>
<DocusaurusDoc>
<RoleBlock user>
<AccountLinks Link={Link} />
</RoleBlock>
</DocusaurusDoc>