[org] fix: Don't hammer backend when consent is lacking
This commit is contained in:
parent
aaed36a46a
commit
f9d68bd2e1
3 changed files with 66 additions and 26 deletions
|
@ -181,6 +181,21 @@ export const Hits = ({ results, Link = false }) => {
|
||||||
|
|
||||||
export const User = ({ user, Link }) => {
|
export const User = ({ user, Link }) => {
|
||||||
const { setModal } = useContext(ModalContext)
|
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 (
|
return (
|
||||||
<div className="tw:flex tw:flex-row tw:w-full tw:gap-4 tw:my-2">
|
<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
|
Details
|
||||||
</button>
|
</button>
|
||||||
<ImpersonateButton userId={user.id} />
|
<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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -8,11 +8,9 @@ import { useBackend } from '@freesewing/react/hooks/useBackend'
|
||||||
import { Link as DefaultLink } from '@freesewing/react/components/Link'
|
import { Link as DefaultLink } from '@freesewing/react/components/Link'
|
||||||
import { LockIcon, PlusIcon } from '@freesewing/react/components/Icon'
|
import { LockIcon, PlusIcon } from '@freesewing/react/components/Icon'
|
||||||
import { Spinner } from '@freesewing/react/components/Spinner'
|
import { Spinner } from '@freesewing/react/components/Spinner'
|
||||||
|
import { Popout } from '@freesewing/react/components/Popout'
|
||||||
import { H1, H2, H3 } from '@freesewing/react/components/Heading'
|
import { H1, H2, H3 } from '@freesewing/react/components/Heading'
|
||||||
|
import { Consent } from '@freesewing/react/components/Account'
|
||||||
//import { ConsentForm, ns as gdprNs } from 'shared/components/gdpr/form.mjs'
|
|
||||||
|
|
||||||
const ConsentForm = () => null
|
|
||||||
|
|
||||||
const Wrap = ({ children }) => (
|
const Wrap = ({ children }) => (
|
||||||
<div className="tw:m-auto tw:max-w-xl tw:text-center tw:mt-8 tw:p-8">{children}</div>
|
<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>
|
<Wrap>
|
||||||
<div className="tw:text-left">
|
<div className="tw:text-left">
|
||||||
{banner}
|
{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>
|
</div>
|
||||||
</Wrap>
|
</Wrap>
|
||||||
)
|
)
|
||||||
|
@ -167,32 +178,35 @@ export const RoleBlock = ({ children, user = false, Link = false }) => {
|
||||||
* Avoid hydration errors
|
* Avoid hydration errors
|
||||||
*/
|
*/
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (admin?.account?.username && account?.username)
|
if (admin?.account?.username && account?.username && !impersonating.admin)
|
||||||
setImpersonating({
|
setImpersonating({
|
||||||
admin: admin.account.username,
|
admin: admin.account.username,
|
||||||
user: account.username,
|
user: account.username,
|
||||||
})
|
})
|
||||||
|
}, [admin])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
const verifyUser = async () => {
|
const verifyUser = async () => {
|
||||||
const [status, data] = await backend.ping()
|
if (!error) {
|
||||||
if (status === 200 && data.result === 'success') {
|
const [status, data] = await backend.ping()
|
||||||
// Refresh account in local storage
|
if (status === 200 && data.result === 'success') {
|
||||||
setAccount({
|
// Refresh account in local storage
|
||||||
...account,
|
setAccount({
|
||||||
...data.account,
|
...account,
|
||||||
bestBefore: Date.now() + 3600000,
|
...data.account,
|
||||||
})
|
bestBefore: Date.now() + 3600000,
|
||||||
} else {
|
})
|
||||||
if (data?.error?.error) setError(data.error.error)
|
} else if (status === 451) setError('consentLacking')
|
||||||
else {
|
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)
|
setReady(true)
|
||||||
}, [admin, refreshCount, signOut])
|
}, [admin, refreshCount, signOut])
|
||||||
|
|
||||||
|
@ -201,7 +215,7 @@ export const RoleBlock = ({ children, user = false, Link = false }) => {
|
||||||
setError(false)
|
setError(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ready) return <Spinner />
|
if (!ready) <Spinner />
|
||||||
|
|
||||||
const banner = impersonating ? (
|
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">
|
<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">
|
||||||
|
|
|
@ -3,10 +3,13 @@ title: Your Account
|
||||||
sidebar_label: Account
|
sidebar_label: Account
|
||||||
---
|
---
|
||||||
|
|
||||||
|
import { DocusaurusDoc } from '@freesewing/react/components/Docusaurus'
|
||||||
import { RoleBlock } from '@freesewing/react/components/Role'
|
import { RoleBlock } from '@freesewing/react/components/Role'
|
||||||
import { Links as AccountLinks } from '@freesewing/react/components/Account'
|
import { Links as AccountLinks } from '@freesewing/react/components/Account'
|
||||||
import Link from '@docusaurus/Link'
|
import Link from '@docusaurus/Link'
|
||||||
|
|
||||||
<RoleBlock user>
|
<DocusaurusDoc>
|
||||||
<AccountLinks Link={Link} />
|
<RoleBlock user>
|
||||||
</RoleBlock>
|
<AccountLinks Link={Link} />
|
||||||
|
</RoleBlock>
|
||||||
|
</DocusaurusDoc>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue