Skip to content

Commit

Permalink
frontend
Browse files Browse the repository at this point in the history
  • Loading branch information
matmut7 committed Oct 25, 2023
1 parent 37f2826 commit 084f8a7
Show file tree
Hide file tree
Showing 13 changed files with 123 additions and 90 deletions.
13 changes: 9 additions & 4 deletions packages/hasura/metadata/actions.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,39 @@ actions:
- name: disableAction
definition:
kind: synchronous
handler: '{{APP_URL}}/api/accounts/disable'
handler: "{{APP_URL}}/api/accounts/disable"
forward_client_headers: true
request_transform:
method: PUT
query_params: {}
template_engine: Kriti
version: 2
permissions:
- role: user
- name: enableAction
definition:
kind: synchronous
handler: '{{APP_URL}}/api/accounts/enable'
handler: "{{APP_URL}}/api/accounts/enable"
forward_client_headers: true
request_transform:
method: PUT
query_params: {}
template_engine: Kriti
version: 2
permissions:
- role: user
- name: onboardingRequestAction
definition:
kind: synchronous
handler: '{{APP_URL}}/api/onboarding/request'
handler: "{{APP_URL}}/api/onboarding/request"
forward_client_headers: true
permissions:
- role: anonymous
- role: user
- name: onboardingReviewAction
definition:
kind: synchronous
handler: '{{APP_URL}}/api/onboarding/review'
handler: "{{APP_URL}}/api/onboarding/review"
forward_client_headers: true
permissions:
- role: user
Expand Down
41 changes: 25 additions & 16 deletions src/components/users/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,23 @@ import statusOk from "@/utils/status-ok"
import UserList from "@/components/users/user-list"
import { usePagedUsers } from "@/hooks/use-paged-users"
import useSelectedUser from "@/hooks/use-selected-user"
import AccountDeleteModal from "./delete-account-modal"
import UserSelected from "@/components/users/user-selected"
import {
revokeAccount,
disableAccount,
detachUserServiceAccount,
mapUser,
mergeUsers,
mutateUser,
enableAccount,
} from "@/hooks/use-users"
import AccountToggleModal from "./toggle-account-modal"

const Users = () => {
const { mutate } = useSWRConfig()
const { pagedUsers } = usePagedUsers()
const [droppedUser, setDroppedUser] = useState<User>()
const { selectedUser, setSelectedUser } = useSelectedUser()
const [accountToDelete, setAccountToDelete] = useState<ServiceAccount>()
const [accountToToggle, setAccountToToggle] = useState<AccountToToggle>()

useEffect(() => {
if (pagedUsers && pagedUsers.length && !selectedUser) {
Expand Down Expand Up @@ -51,27 +52,35 @@ const Users = () => {
}
}

const handleDeleteAccount = (account: ServiceAccount) => {
setAccountToDelete(account)
const handleToggleAccount = (accountToToggle: AccountToToggle) => {
setAccountToToggle(accountToToggle)
}

const handleConfirmDeleteAccount = async () => {
const { status, body } = await revokeAccount(
accountToDelete as ServiceAccount
)
if (statusOk(status)) {
const handleConfirmToggleAccount = async (
accountToToggle: AccountToToggle
) => {
let response
if (accountToToggle.disable) {
response = await disableAccount(accountToToggle.account)
} else {
response = await enableAccount(accountToToggle.account)
}
if (statusOk(response.status)) {
mutate("/users")
}
return { status, body }
return response
}

return (
<DndProvider backend={HTML5Backend}>
<div className="users-view">
<AccountDeleteModal
isOpen={!!accountToDelete}
onConfirm={handleConfirmDeleteAccount}
onRequestClose={() => setAccountToDelete(undefined)}
<AccountToggleModal
disable={accountToToggle?.disable}
isOpen={!!accountToToggle}
onConfirm={() =>
handleConfirmToggleAccount(accountToToggle as AccountToToggle)
}
onRequestClose={() => setAccountToToggle(undefined)}
/>
<UserList
users={pagedUsers}
Expand All @@ -83,7 +92,7 @@ const Users = () => {
onUserDrop={setDroppedUser}
onUserEdit={handleUserEdit}
onAccountsChange={(account) => handleAccountsChange(account)}
onDeleteAccount={handleDeleteAccount}
onToggleAccount={handleToggleAccount}
/>
</div>
</DndProvider>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ import { useState } from "react"
import Modal from "react-modal"
import Loader from "../common/loader"

const AccountDeleteModal = ({
const AccountToggleModal = ({
disable,
isOpen,
onConfirm,
onRequestClose,
}: {
disable: boolean | undefined
isOpen: boolean
onConfirm: () => Promise<{ status: number; body: string }>
onRequestClose: () => void
Expand Down Expand Up @@ -36,24 +38,21 @@ const AccountDeleteModal = ({
className="modal"
ariaHideApp={false}
onRequestClose={handleRequestClose}
contentLabel="Delete account modal"
contentLabel="Toggle account modal"
overlayClassName="modal-overlay"
>
<button className="close" onClick={handleRequestClose}>
<i className="ri-close-line"></i>
</button>
<h2>Révoquer un accès</h2>
<h2>{disable ? "Désactiver" : "Activer"} un accès</h2>
<br />
{!isConfirmed ? (
<>
<p>
Vous allez supprimer un accès utilisateur sur un outil de la
Fabrique.
</p>
<p>
Cela sera réellement répercuté sur le service concerné et peut être
irréversible.
Vous allez {disable ? "désactiver" : "activer"} un accès utilisateur
sur un outil de la Fabrique.
</p>
<p>Cela sera répercuté sur le service concerné.</p>
<br />
<div className="confirm-buttons">
<button className="secondary" onClick={handleRequestClose}>
Expand Down Expand Up @@ -82,4 +81,4 @@ const AccountDeleteModal = ({
)
}

export default AccountDeleteModal
export default AccountToggleModal
6 changes: 3 additions & 3 deletions src/components/users/user-profile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ const UserProfile = ({
onUserDrop,
onUserEdit,
onAccountsChange,
onDeleteAccount,
onToggleAccount,
}: {
user: User
onUserDrop: (user: User) => void
onUserEdit: (user: User) => void
onAccountsChange: (account: ServiceAccount) => void
onDeleteAccount: (account: ServiceAccount) => void
onToggleAccount: (account: AccountToToggle) => void
}) => {
const [{ canDrop, isOver }, drop] = useDrop(
() => ({
Expand Down Expand Up @@ -65,7 +65,7 @@ const UserProfile = ({
<UserServices
services={user.services}
onDetachAccount={onAccountsChange}
onDeleteAccount={onDeleteAccount}
onToggleAccount={onToggleAccount}
/>
</div>
</div>
Expand Down
6 changes: 3 additions & 3 deletions src/components/users/user-selected.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ const UserSelected = ({
onUserDrop,
onUserEdit,
onAccountsChange,
onDeleteAccount,
onToggleAccount,
}: {
onUserDrop: (user: User) => void
onUserEdit: (user: User) => void
onAccountsChange: (account: ServiceAccount) => void
onDeleteAccount: (account: ServiceAccount) => void
onToggleAccount: (account: AccountToToggle) => void
}) => {
const users = useUsers()
const { selectedUser, setSelectedUser } = useSelectedUser()
Expand All @@ -34,7 +34,7 @@ const UserSelected = ({
onUserDrop={onUserDrop}
onUserEdit={onUserEdit}
onAccountsChange={onAccountsChange}
onDeleteAccount={onDeleteAccount}
onToggleAccount={onToggleAccount}
/>
) : (
<div className="no-user-selected">
Expand Down
26 changes: 17 additions & 9 deletions src/components/users/user-service-info.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -185,12 +185,12 @@ const UserServiceInfo = ({
account,
isSingleAccount,
onDetachAccount,
onDeleteAccount,
onToggleAccount,
}: {
account: ServiceAccount
isSingleAccount: boolean
onDetachAccount: (account: ServiceAccount) => void
onDeleteAccount: (account: ServiceAccount) => void
onToggleAccount: (account: AccountToToggle) => void
}) => {
const ref = useSpringRef()

Expand Down Expand Up @@ -221,13 +221,21 @@ const UserServiceInfo = ({
<i className="ri-eject-fill"></i>
</button>
)}
<button
title="révoquer"
className="secondary sm icon"
onClick={() => onDeleteAccount(account)}
>
<i className="ri-close-line"></i>
</button>
{account.disabled ? (
<button
className="primary sm"
onClick={() => onToggleAccount({ disable: false, account })}
>
activer
</button>
) : (
<button
className="secondary sm"
onClick={() => onToggleAccount({ disable: true, account })}
>
désactiver
</button>
)}
</div>
</h3>
{account.type === "github" && <GithubUserInfo account={account} />}
Expand Down
6 changes: 3 additions & 3 deletions src/components/users/user-services.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ import UserServiceInfo from "@/components/users/user-service-info"
const UserServices = ({
services,
onDetachAccount,
onDeleteAccount,
onToggleAccount,
}: {
services: ServiceAccount[]
onDetachAccount: (account: ServiceAccount) => void
onDeleteAccount: (account: ServiceAccount) => void
onToggleAccount: (account: AccountToToggle) => void
}) => {
const isSingleAccount = services.length <= 1

Expand All @@ -19,7 +19,7 @@ const UserServices = ({
account={account}
isSingleAccount={isSingleAccount}
onDetachAccount={onDetachAccount}
onDeleteAccount={onDeleteAccount}
onToggleAccount={onToggleAccount}
/>
))}
</div>
Expand Down
32 changes: 19 additions & 13 deletions src/hooks/use-users.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import {
insertUser,
updateService,
mergeUsers as mergeUsersQuery,
revokeAction,
disableAction,
enableAction,
} from "@/queries/index"
import logAction from "@/utils/log-action"
import { getSession } from "next-auth/react"
Expand Down Expand Up @@ -160,23 +161,28 @@ export const detachUserServiceAccount = async (account: ServiceAccount) => {
})
}

export const revokeAccount = async (account: ServiceAccount) => {
const accountServiceID =
account.type === "ovh"
? account.data.primaryEmailAddress
: account.type === "github" || account.type === "matomo"
? account.data.login
: account.data.id
export const disableAccount = async (account: ServiceAccount) => {
const {
disableAction: { status, body },
} = await graphQLFetcher({
query: disableAction,
includeCookie: true,
parameters: {
serviceAccountId: account.id,
},
})

return { status, body }
}

export const enableAccount = async (account: ServiceAccount) => {
const {
revokeAction: { status, body },
enableAction: { status, body },
} = await graphQLFetcher({
query: revokeAction,
query: enableAction,
includeCookie: true,
parameters: {
serviceName: account.type,
accountID: account.id,
accountServiceID,
serviceAccountId: account.id,
},
})

Expand Down
22 changes: 11 additions & 11 deletions src/pages/api/accounts/disable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const Disable = async (req: NextApiRequest, res: NextApiResponse) => {
const bodySchema = z.object({
id: z.string().uuid(),
})
const parsedBody = bodySchema.safeParse(req.body)
const parsedBody = bodySchema.safeParse(req.body.input.data)
if (!parsedBody.success) {
logger.error(parsedBody.error)
res.status(400).json({ message: "Bad Request" })
Expand Down Expand Up @@ -63,16 +63,16 @@ const Disable = async (req: NextApiRequest, res: NextApiResponse) => {

let response: APIResponse
if (serviceAccount.type === "mattermost") {
const res = await disableMattermostAccount(serviceAccount.data.id)
response = { status: res.status, body: await res.json() }
const r = await disableMattermostAccount(serviceAccount.data.id)
response = { status: r.status, body: await r.json() }
} else if (serviceAccount.type === "github") {
const res = await disableGithubAccount(serviceAccount.data.login)
response = { status: res.status, body: await res.json() }
const r = await disableGithubAccount(serviceAccount.data.login)
response = { status: r.status, body: await r.text() } // Github does not always send valid JSON
} else if (serviceAccount.type == "ovh") {
const res = await disableOvhAccount(serviceAccount.data.primaryEmailAddress)
return {
status: res.success ? "200" : "500",
body: res.success ? res.data : res.error,
const r = await disableOvhAccount(serviceAccount.data.primaryEmailAddress)
response = {
status: r.success ? 200 : 500,
body: r.success ? (r.data as string) : JSON.stringify(r.error),
}
} else {
logger.error(
Expand All @@ -90,8 +90,8 @@ const Disable = async (req: NextApiRequest, res: NextApiResponse) => {
query: updateService,
token,
parameters: {
id: serviceAccount.id,
_set: { disabled: true },
serviceId: serviceAccount.id,
service: { disabled: true },
},
})
}
Expand Down
Loading

0 comments on commit 084f8a7

Please sign in to comment.