Add magic link login for trust center
Signed-off-by: Émile Ré <emile@getprobo.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
import { graphql } from "relay-runtime";
|
import { graphql } from "relay-runtime";
|
||||||
import type { AuditRowFragment$key } from "./__generated__/AuditRowFragment.graphql";
|
import type { AuditRowFragment$key } from "./__generated__/AuditRowFragment.graphql";
|
||||||
import { useFragment } from "react-relay";
|
import { useFragment, useMutation } from "react-relay";
|
||||||
import {
|
import {
|
||||||
Breadcrumb,
|
Breadcrumb,
|
||||||
Button,
|
Button,
|
||||||
@@ -12,14 +12,27 @@ import {
|
|||||||
IconMedal,
|
IconMedal,
|
||||||
Spinner,
|
Spinner,
|
||||||
Table,
|
Table,
|
||||||
|
useToast,
|
||||||
} from "@probo/ui";
|
} from "@probo/ui";
|
||||||
import { useTranslate } from "@probo/i18n";
|
import { useTranslate } from "@probo/i18n";
|
||||||
import type { AuditRowDownloadMutation } from "./__generated__/AuditRowDownloadMutation.graphql";
|
import type { AuditRowDownloadMutation } from "./__generated__/AuditRowDownloadMutation.graphql";
|
||||||
import { useMutationWithToasts } from "/hooks/useMutationWithToast";
|
import { useMutationWithToasts } from "/hooks/useMutationWithToast";
|
||||||
import { downloadFile } from "@probo/helpers";
|
import { downloadFile, formatError } from "@probo/helpers";
|
||||||
import { type PropsWithChildren, useState } from "react";
|
import { type PropsWithChildren, use, useState } from "react";
|
||||||
import { useLocation } from "react-router";
|
import { useLocation } from "react-router";
|
||||||
import { RequestAccessDialog } from "/components/RequestAccessDialog.tsx";
|
import { Viewer } from "/providers/Viewer";
|
||||||
|
import { MagicLinkDialog } from "./MagicLinkDialog";
|
||||||
|
import type { AuditRow_requestAccessMutation } from "./__generated__/AuditRow_requestAccessMutation.graphql";
|
||||||
|
|
||||||
|
const requestAccessMutation = graphql`
|
||||||
|
mutation AuditRow_requestAccessMutation($input: RequestReportAccessInput!) {
|
||||||
|
requestReportAccess(input: $input) {
|
||||||
|
trustCenterAccess {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
const downloadMutation = graphql`
|
const downloadMutation = graphql`
|
||||||
mutation AuditRowDownloadMutation($input: ExportReportPDFInput!) {
|
mutation AuditRowDownloadMutation($input: ExportReportPDFInput!) {
|
||||||
@@ -47,10 +60,53 @@ const auditRowFragment = graphql`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
export function AuditRow(props: { audit: AuditRowFragment$key }) {
|
export function AuditRow(props: { audit: AuditRowFragment$key }) {
|
||||||
const audit = useFragment(auditRowFragment, props.audit);
|
|
||||||
const { __ } = useTranslate();
|
const { __ } = useTranslate();
|
||||||
|
const viewer = use(Viewer);
|
||||||
|
const { toast } = useToast();
|
||||||
|
|
||||||
|
const audit = useFragment(auditRowFragment, props.audit);
|
||||||
|
const [hasRequested, setHasRequested] = useState(
|
||||||
|
audit.report?.hasUserRequestedAccess,
|
||||||
|
);
|
||||||
|
|
||||||
|
const [requestAccess, isRequestingAccess] =
|
||||||
|
useMutation<AuditRow_requestAccessMutation>(requestAccessMutation);
|
||||||
const [commitDownload, downloading] =
|
const [commitDownload, downloading] =
|
||||||
useMutationWithToasts<AuditRowDownloadMutation>(downloadMutation);
|
useMutationWithToasts<AuditRowDownloadMutation>(downloadMutation);
|
||||||
|
|
||||||
|
const handleRequestAccess = () => {
|
||||||
|
requestAccess({
|
||||||
|
variables: {
|
||||||
|
input: {
|
||||||
|
reportId: audit.report?.id ?? "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
onCompleted: (_, errors) => {
|
||||||
|
if (errors?.length) {
|
||||||
|
toast({
|
||||||
|
title: __("Error"),
|
||||||
|
description: formatError(__("Cannot request access"), errors),
|
||||||
|
variant: "error",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setHasRequested(true);
|
||||||
|
toast({
|
||||||
|
title: __("Success"),
|
||||||
|
description: __("Access request submitted successfully."),
|
||||||
|
variant: "success",
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onError: (error) => {
|
||||||
|
toast({
|
||||||
|
title: __("Error"),
|
||||||
|
description: error.message ?? __("Cannot request access"),
|
||||||
|
variant: "error",
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const handleDownload = () => {
|
const handleDownload = () => {
|
||||||
if (!audit.report?.id) {
|
if (!audit.report?.id) {
|
||||||
return;
|
return;
|
||||||
@@ -67,16 +123,26 @@ export function AuditRow(props: { audit: AuditRowFragment$key }) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const [hasRequested, setHasRequested] = useState(
|
|
||||||
audit.report?.hasUserRequestedAccess
|
|
||||||
);
|
|
||||||
return (
|
return (
|
||||||
<div className="text-sm border border-border-solid -mt-px flex gap-3 flex-col md:flex-row md:justify-between px-6 py-3">
|
<div className="text-sm border border-border-solid -mt-px flex gap-3 flex-col md:flex-row md:justify-between px-6 py-3">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<IconMedal size={16} className="flex-none text-txt-tertiary" />
|
<IconMedal size={16} className="flex-none text-txt-tertiary" />
|
||||||
{audit.framework.name}
|
{audit.framework.name}
|
||||||
</div>
|
</div>
|
||||||
{audit.report && audit.report.isUserAuthorized && (
|
{!viewer && (
|
||||||
|
<MagicLinkDialog>
|
||||||
|
<Button
|
||||||
|
className="w-full md:w-max"
|
||||||
|
variant="secondary"
|
||||||
|
icon={IconLock}
|
||||||
|
>
|
||||||
|
{hasRequested ? __("Access requested") : __("Request access")}
|
||||||
|
</Button>
|
||||||
|
</MagicLinkDialog>
|
||||||
|
)}
|
||||||
|
{viewer &&
|
||||||
|
audit.report &&
|
||||||
|
(audit.report.isUserAuthorized ? (
|
||||||
<Button
|
<Button
|
||||||
className="w-full md:w-max"
|
className="w-full md:w-max"
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
@@ -86,22 +152,17 @@ export function AuditRow(props: { audit: AuditRowFragment$key }) {
|
|||||||
>
|
>
|
||||||
{__("Download")}
|
{__("Download")}
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
) : (
|
||||||
{audit.report && !audit.report.isUserAuthorized && (
|
|
||||||
<RequestAccessDialog
|
|
||||||
reportId={audit.report.id}
|
|
||||||
onSuccess={() => setHasRequested(true)}
|
|
||||||
>
|
|
||||||
<Button
|
<Button
|
||||||
disabled={hasRequested}
|
disabled={hasRequested || isRequestingAccess}
|
||||||
className="w-full md:w-max"
|
className="w-full md:w-max"
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
icon={IconLock}
|
icon={IconLock}
|
||||||
|
onClick={handleRequestAccess}
|
||||||
>
|
>
|
||||||
{hasRequested ? __("Access requested") : __("Request access")}
|
{hasRequested ? __("Access requested") : __("Request access")}
|
||||||
</Button>
|
</Button>
|
||||||
</RequestAccessDialog>
|
))}
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -134,7 +195,7 @@ export function AuditRowAvatar(props: { audit: AuditRowFragment$key }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function AuditDialog(
|
function AuditDialog(
|
||||||
props: PropsWithChildren<{ audit: AuditRowFragment$key; logo?: string }>
|
props: PropsWithChildren<{ audit: AuditRowFragment$key; logo?: string }>,
|
||||||
) {
|
) {
|
||||||
const audit = useFragment(auditRowFragment, props.audit);
|
const audit = useFragment(auditRowFragment, props.audit);
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
|
|||||||
@@ -1,19 +1,34 @@
|
|||||||
import { graphql } from "relay-runtime";
|
import { graphql } from "relay-runtime";
|
||||||
import type { DocumentRowFragment$key } from "./__generated__/DocumentRowFragment.graphql";
|
import type { DocumentRowFragment$key } from "./__generated__/DocumentRowFragment.graphql";
|
||||||
import { useFragment } from "react-relay";
|
import { useFragment, useMutation } from "react-relay";
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
IconArrowInbox,
|
IconArrowInbox,
|
||||||
IconLock,
|
IconLock,
|
||||||
IconPageTextLine,
|
IconPageTextLine,
|
||||||
Spinner,
|
Spinner,
|
||||||
|
useToast,
|
||||||
} from "@probo/ui";
|
} from "@probo/ui";
|
||||||
import { useTranslate } from "@probo/i18n";
|
import { useTranslate } from "@probo/i18n";
|
||||||
import type { DocumentRowDownloadMutation } from "./__generated__/DocumentRowDownloadMutation.graphql";
|
import type { DocumentRowDownloadMutation } from "./__generated__/DocumentRowDownloadMutation.graphql";
|
||||||
import { useMutationWithToasts } from "/hooks/useMutationWithToast";
|
import { useMutationWithToasts } from "/hooks/useMutationWithToast";
|
||||||
import { downloadFile } from "@probo/helpers";
|
import { downloadFile, formatError } from "@probo/helpers";
|
||||||
import { RequestAccessDialog } from "/components/RequestAccessDialog.tsx";
|
import { use, useState } from "react";
|
||||||
import { useState } from "react";
|
import { MagicLinkDialog } from "./MagicLinkDialog";
|
||||||
|
import { Viewer } from "/providers/Viewer";
|
||||||
|
import type { DocumentRow_requestAccessMutation } from "./__generated__/DocumentRow_requestAccessMutation.graphql";
|
||||||
|
|
||||||
|
const requestAccessMutation = graphql`
|
||||||
|
mutation DocumentRow_requestAccessMutation(
|
||||||
|
$input: RequestDocumentAccessInput!
|
||||||
|
) {
|
||||||
|
requestDocumentAccess(input: $input) {
|
||||||
|
trustCenterAccess {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
const downloadMutation = graphql`
|
const downloadMutation = graphql`
|
||||||
mutation DocumentRowDownloadMutation($input: ExportDocumentPDFInput!) {
|
mutation DocumentRowDownloadMutation($input: ExportDocumentPDFInput!) {
|
||||||
@@ -33,10 +48,53 @@ const documentRowFragment = graphql`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
export function DocumentRow(props: { document: DocumentRowFragment$key }) {
|
export function DocumentRow(props: { document: DocumentRowFragment$key }) {
|
||||||
const document = useFragment(documentRowFragment, props.document);
|
|
||||||
const { __ } = useTranslate();
|
const { __ } = useTranslate();
|
||||||
|
const viewer = use(Viewer);
|
||||||
|
const { toast } = useToast();
|
||||||
|
|
||||||
|
const document = useFragment(documentRowFragment, props.document);
|
||||||
|
const [hasRequested, setHasRequested] = useState(
|
||||||
|
document.hasUserRequestedAccess,
|
||||||
|
);
|
||||||
|
|
||||||
|
const [requestAccess, isRequestingAccess] =
|
||||||
|
useMutation<DocumentRow_requestAccessMutation>(requestAccessMutation);
|
||||||
const [commitDownload, downloading] =
|
const [commitDownload, downloading] =
|
||||||
useMutationWithToasts<DocumentRowDownloadMutation>(downloadMutation);
|
useMutationWithToasts<DocumentRowDownloadMutation>(downloadMutation);
|
||||||
|
|
||||||
|
const handleRequestAccess = () => {
|
||||||
|
requestAccess({
|
||||||
|
variables: {
|
||||||
|
input: {
|
||||||
|
documentId: document.id,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
onCompleted: (_, errors) => {
|
||||||
|
if (errors?.length) {
|
||||||
|
toast({
|
||||||
|
title: __("Error"),
|
||||||
|
description: formatError(__("Cannot request access"), errors),
|
||||||
|
variant: "error",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setHasRequested(true);
|
||||||
|
toast({
|
||||||
|
title: __("Success"),
|
||||||
|
description: __("Access request submitted successfully."),
|
||||||
|
variant: "success",
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onError: (error) => {
|
||||||
|
toast({
|
||||||
|
title: __("Error"),
|
||||||
|
description: error.message ?? __("Cannot request access"),
|
||||||
|
variant: "error",
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const handleDownload = () => {
|
const handleDownload = () => {
|
||||||
commitDownload({
|
commitDownload({
|
||||||
variables: {
|
variables: {
|
||||||
@@ -49,16 +107,26 @@ export function DocumentRow(props: { document: DocumentRowFragment$key }) {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
const [hasRequested, setHasRequested] = useState(
|
|
||||||
document.hasUserRequestedAccess,
|
|
||||||
);
|
|
||||||
return (
|
return (
|
||||||
<div className="text-sm border border-border-solid -mt-px flex gap-3 flex-col md:flex-row md:justify-between px-6 py-3">
|
<div className="text-sm border border-border-solid -mt-px flex gap-3 flex-col md:flex-row md:justify-between px-6 py-3">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<IconPageTextLine size={16} className=" flex-none text-txt-tertiary" />
|
<IconPageTextLine size={16} className=" flex-none text-txt-tertiary" />
|
||||||
{document.title}
|
{document.title}
|
||||||
</div>
|
</div>
|
||||||
{document.isUserAuthorized ? (
|
{!viewer && (
|
||||||
|
<MagicLinkDialog>
|
||||||
|
<Button
|
||||||
|
className="w-full md:w-max"
|
||||||
|
variant="secondary"
|
||||||
|
icon={IconLock}
|
||||||
|
>
|
||||||
|
{hasRequested ? __("Access requested") : __("Request access")}
|
||||||
|
</Button>
|
||||||
|
</MagicLinkDialog>
|
||||||
|
)}
|
||||||
|
{viewer &&
|
||||||
|
(document.isUserAuthorized ? (
|
||||||
<Button
|
<Button
|
||||||
className="w-full md:w-max"
|
className="w-full md:w-max"
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
@@ -69,20 +137,16 @@ export function DocumentRow(props: { document: DocumentRowFragment$key }) {
|
|||||||
{__("Download")}
|
{__("Download")}
|
||||||
</Button>
|
</Button>
|
||||||
) : (
|
) : (
|
||||||
<RequestAccessDialog
|
|
||||||
documentId={document.id}
|
|
||||||
onSuccess={() => setHasRequested(true)}
|
|
||||||
>
|
|
||||||
<Button
|
<Button
|
||||||
disabled={hasRequested}
|
disabled={hasRequested || isRequestingAccess}
|
||||||
className="w-full md:w-max"
|
className="w-full md:w-max"
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
icon={IconLock}
|
icon={IconLock}
|
||||||
|
onClick={handleRequestAccess}
|
||||||
>
|
>
|
||||||
{hasRequested ? __("Access requested") : __("Request access")}
|
{hasRequested ? __("Access requested") : __("Request access")}
|
||||||
</Button>
|
</Button>
|
||||||
</RequestAccessDialog>
|
))}
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
122
apps/trust/src/components/MagicLinkDialog.tsx
Normal file
122
apps/trust/src/components/MagicLinkDialog.tsx
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
import {
|
||||||
|
Button,
|
||||||
|
Dialog,
|
||||||
|
DialogContent,
|
||||||
|
DialogFooter,
|
||||||
|
DialogTitle,
|
||||||
|
Field,
|
||||||
|
useDialogRef,
|
||||||
|
useToast,
|
||||||
|
} from "@probo/ui";
|
||||||
|
import { useMutation } from "react-relay";
|
||||||
|
import { graphql } from "relay-runtime";
|
||||||
|
import z from "zod";
|
||||||
|
import { useFormWithSchema } from "/hooks/useFormWithSchema";
|
||||||
|
import { useTranslate } from "@probo/i18n";
|
||||||
|
import type { MagicLinkDialogMutation } from "./__generated__/MagicLinkDialogMutation.graphql";
|
||||||
|
import type { PropsWithChildren } from "react";
|
||||||
|
|
||||||
|
const sendMagicLinkMutation = graphql`
|
||||||
|
mutation MagicLinkDialogMutation($input: SendMagicLinkInput!) {
|
||||||
|
sendMagicLink(input: $input) {
|
||||||
|
success
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const schema = z.object({
|
||||||
|
email: z.string().email(),
|
||||||
|
});
|
||||||
|
|
||||||
|
type FormData = z.infer<typeof schema>;
|
||||||
|
|
||||||
|
export function MagicLinkDialog(props: PropsWithChildren) {
|
||||||
|
const { children } = props;
|
||||||
|
|
||||||
|
const { __ } = useTranslate();
|
||||||
|
const { toast } = useToast();
|
||||||
|
const dialogRef = useDialogRef();
|
||||||
|
|
||||||
|
const [sendMagicLink] = useMutation<MagicLinkDialogMutation>(
|
||||||
|
sendMagicLinkMutation,
|
||||||
|
);
|
||||||
|
|
||||||
|
const {
|
||||||
|
handleSubmit: handleSubmitWrapper,
|
||||||
|
register,
|
||||||
|
formState,
|
||||||
|
} = useFormWithSchema(schema, {
|
||||||
|
defaultValues: {
|
||||||
|
email: "",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleSubmit = ({ email }: FormData) => {
|
||||||
|
sendMagicLink({
|
||||||
|
variables: {
|
||||||
|
input: {
|
||||||
|
email,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
onCompleted: (_, errors) => {
|
||||||
|
if (errors?.length) {
|
||||||
|
toast({
|
||||||
|
title: __("Error"),
|
||||||
|
description: __("Cannot send magic link"),
|
||||||
|
variant: "error",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
toast({
|
||||||
|
title: __("Success"),
|
||||||
|
description: __(
|
||||||
|
"Magic link sent! Please check your emails to authenticate",
|
||||||
|
),
|
||||||
|
variant: "success",
|
||||||
|
});
|
||||||
|
dialogRef.current?.close();
|
||||||
|
},
|
||||||
|
onError: (error) => {
|
||||||
|
toast({
|
||||||
|
title: __("Error"),
|
||||||
|
description: error.message,
|
||||||
|
variant: "error",
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog
|
||||||
|
trigger={children}
|
||||||
|
ref={dialogRef}
|
||||||
|
className="max-w-[500px] text-txt-primary"
|
||||||
|
>
|
||||||
|
<form onSubmit={handleSubmitWrapper(handleSubmit)}>
|
||||||
|
<DialogTitle className="text-2xl font-semibold mb-4 pt-4 md:pt-8 px-4 md:px-8">
|
||||||
|
{__("Create account or sign in")}
|
||||||
|
</DialogTitle>
|
||||||
|
<DialogContent className="px-4 md:px-8 pb-4 md:pb-8 text-txt-primary">
|
||||||
|
<p className="text-txt-secondary mb-4">
|
||||||
|
{__(
|
||||||
|
"To be able to request access to documents, you need to authenticate. Please enter your email to get a magic link.",
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
<Field
|
||||||
|
label={__("Email")}
|
||||||
|
placeholder="john.doe@acme.com"
|
||||||
|
{...register("email")}
|
||||||
|
type="email"
|
||||||
|
error={formState.errors.email?.message}
|
||||||
|
/>
|
||||||
|
</DialogContent>
|
||||||
|
<DialogFooter>
|
||||||
|
<Button disabled={formState.isSubmitting} type="submit">
|
||||||
|
{__("Continue")}
|
||||||
|
</Button>
|
||||||
|
</DialogFooter>
|
||||||
|
</form>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,11 +1,31 @@
|
|||||||
import { useTranslate } from "@probo/i18n";
|
import { useTranslate } from "@probo/i18n";
|
||||||
import { Button, Card, IconBlock, IconLock, IconMedal } from "@probo/ui";
|
import {
|
||||||
|
Button,
|
||||||
|
Card,
|
||||||
|
IconBlock,
|
||||||
|
IconLock,
|
||||||
|
IconMedal,
|
||||||
|
useToast,
|
||||||
|
} from "@probo/ui";
|
||||||
import type { TrustGraphQuery$data } from "/queries/__generated__/TrustGraphQuery.graphql";
|
import type { TrustGraphQuery$data } from "/queries/__generated__/TrustGraphQuery.graphql";
|
||||||
import { use, type PropsWithChildren } from "react";
|
import { use, type PropsWithChildren } from "react";
|
||||||
import { domain } from "@probo/helpers";
|
import { domain, formatError } from "@probo/helpers";
|
||||||
import { AuditRowAvatar } from "./AuditRow";
|
import { AuditRowAvatar } from "./AuditRow";
|
||||||
import { RequestAccessDialog } from "./RequestAccessDialog";
|
|
||||||
import { Viewer } from "/providers/Viewer";
|
import { Viewer } from "/providers/Viewer";
|
||||||
|
import { MagicLinkDialog } from "./MagicLinkDialog";
|
||||||
|
import { graphql } from "relay-runtime";
|
||||||
|
import { useMutation } from "react-relay";
|
||||||
|
import type { OrganizationSidebar_requestAllAccessesMutation } from "./__generated__/OrganizationSidebar_requestAllAccessesMutation.graphql";
|
||||||
|
|
||||||
|
const requestAllAccessesMutation = graphql`
|
||||||
|
mutation OrganizationSidebar_requestAllAccessesMutation {
|
||||||
|
requestAllAccesses {
|
||||||
|
trustCenterAccess {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
export function OrganizationSidebar({
|
export function OrganizationSidebar({
|
||||||
trustCenter,
|
trustCenter,
|
||||||
@@ -14,6 +34,40 @@ export function OrganizationSidebar({
|
|||||||
}) {
|
}) {
|
||||||
const { __ } = useTranslate();
|
const { __ } = useTranslate();
|
||||||
const isAuthenticated = !!use(Viewer);
|
const isAuthenticated = !!use(Viewer);
|
||||||
|
const { toast } = useToast();
|
||||||
|
|
||||||
|
const [requestAllAccesses, isRequestingAccess] =
|
||||||
|
useMutation<OrganizationSidebar_requestAllAccessesMutation>(
|
||||||
|
requestAllAccessesMutation,
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleRequestAllAccesses = () => {
|
||||||
|
requestAllAccesses({
|
||||||
|
variables: {},
|
||||||
|
onCompleted: (_, errors) => {
|
||||||
|
if (errors?.length) {
|
||||||
|
toast({
|
||||||
|
title: __("Error"),
|
||||||
|
description: formatError(__("Cannot request access"), errors),
|
||||||
|
variant: "error",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
toast({
|
||||||
|
title: __("Success"),
|
||||||
|
description: __("Access request submitted successfully."),
|
||||||
|
variant: "success",
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onError: (error) => {
|
||||||
|
toast({
|
||||||
|
title: __("Error"),
|
||||||
|
description: error.message ?? __("Cannot request access"),
|
||||||
|
variant: "error",
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
if (!trustCenter) {
|
if (!trustCenter) {
|
||||||
return null;
|
return null;
|
||||||
@@ -95,12 +149,22 @@ export function OrganizationSidebar({
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Actions */}
|
{/* Actions */}
|
||||||
{!isAuthenticated && (
|
{isAuthenticated ? (
|
||||||
<RequestAccessDialog>
|
<Button
|
||||||
|
disabled={isRequestingAccess}
|
||||||
|
variant="primary"
|
||||||
|
icon={IconLock}
|
||||||
|
className="w-full h-10"
|
||||||
|
onClick={handleRequestAllAccesses}
|
||||||
|
>
|
||||||
|
{__("Request access")}
|
||||||
|
</Button>
|
||||||
|
) : (
|
||||||
|
<MagicLinkDialog>
|
||||||
<Button variant="primary" icon={IconLock} className="w-full h-10">
|
<Button variant="primary" icon={IconLock} className="w-full h-10">
|
||||||
{__("Request access")}
|
{__("Request access")}
|
||||||
</Button>
|
</Button>
|
||||||
</RequestAccessDialog>
|
</MagicLinkDialog>
|
||||||
)}
|
)}
|
||||||
{/* <Button variant="secondary" icon={IconMail} className="w-full h-10">
|
{/* <Button variant="secondary" icon={IconMail} className="w-full h-10">
|
||||||
{__("Subscribe to updates")}
|
{__("Subscribe to updates")}
|
||||||
|
|||||||
@@ -1,273 +0,0 @@
|
|||||||
import {
|
|
||||||
Button,
|
|
||||||
Dialog,
|
|
||||||
DialogContent,
|
|
||||||
DialogFooter,
|
|
||||||
DialogTitle,
|
|
||||||
Field,
|
|
||||||
useDialogRef,
|
|
||||||
useToast,
|
|
||||||
} from "@probo/ui";
|
|
||||||
import { useTranslate } from "@probo/i18n";
|
|
||||||
import { sprintf } from "@probo/helpers";
|
|
||||||
import { z } from "zod";
|
|
||||||
import { useFormWithSchema } from "/hooks/useFormWithSchema";
|
|
||||||
import { graphql } from "relay-runtime";
|
|
||||||
import { useMutationWithToasts } from "/hooks/useMutationWithToast";
|
|
||||||
import { useTrustCenter } from "/hooks/useTrustCenter";
|
|
||||||
import { use, type FormEventHandler, type PropsWithChildren } from "react";
|
|
||||||
import { InvalidError } from "/providers/RelayProviders";
|
|
||||||
import { Viewer } from "/providers/Viewer";
|
|
||||||
|
|
||||||
type Props = PropsWithChildren<{
|
|
||||||
documentId?: string;
|
|
||||||
reportId?: string;
|
|
||||||
trustCenterFileId?: string;
|
|
||||||
onSuccess?: () => void;
|
|
||||||
}>;
|
|
||||||
|
|
||||||
const schema = z.object({
|
|
||||||
fullName: z.string(),
|
|
||||||
email: z.string().email(),
|
|
||||||
});
|
|
||||||
|
|
||||||
export function RequestAccessDialog({
|
|
||||||
children,
|
|
||||||
documentId,
|
|
||||||
reportId,
|
|
||||||
trustCenterFileId,
|
|
||||||
onSuccess,
|
|
||||||
}: Props) {
|
|
||||||
const trustCenter = useTrustCenter();
|
|
||||||
const { toast } = useToast();
|
|
||||||
const { __ } = useTranslate();
|
|
||||||
const viewer = use(Viewer);
|
|
||||||
const { handleSubmit, register, setError, formState } = useFormWithSchema(
|
|
||||||
schema,
|
|
||||||
{
|
|
||||||
defaultValues: {
|
|
||||||
fullName: "",
|
|
||||||
email: "",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
);
|
|
||||||
const dialogRef = useDialogRef();
|
|
||||||
const [commitMutation, isMutating] = useMutation({
|
|
||||||
documentId,
|
|
||||||
reportId,
|
|
||||||
trustCenterFileId,
|
|
||||||
});
|
|
||||||
|
|
||||||
const submitCallback = (data: z.infer<typeof schema> | null) => {
|
|
||||||
commitMutation({
|
|
||||||
email: data?.email ?? viewer?.email ?? "",
|
|
||||||
fullName: data?.fullName ?? viewer?.fullName ?? "",
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
onSuccess?.();
|
|
||||||
toast({
|
|
||||||
title: __("Success"),
|
|
||||||
description: __("Access request submitted successfully"),
|
|
||||||
variant: "success",
|
|
||||||
});
|
|
||||||
dialogRef.current?.close();
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
if (error instanceof InvalidError) {
|
|
||||||
if (error.field === "email") {
|
|
||||||
setError(error.field, { message: error.message });
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
toast({
|
|
||||||
title: __("Error"),
|
|
||||||
description: __("Cannot request access"),
|
|
||||||
variant: "error",
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const onSubmit: FormEventHandler<HTMLFormElement> = viewer
|
|
||||||
? (e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
submitCallback(null);
|
|
||||||
}
|
|
||||||
: handleSubmit(submitCallback);
|
|
||||||
return (
|
|
||||||
<Dialog
|
|
||||||
ref={dialogRef}
|
|
||||||
trigger={children}
|
|
||||||
className="max-w-[500px] text-txt-primary"
|
|
||||||
>
|
|
||||||
<form onSubmit={onSubmit}>
|
|
||||||
<DialogTitle className="text-2xl font-semibold mb-4 pt-4 md:pt-8 px-4 md:px-8">
|
|
||||||
{__("Request access to documentation")}
|
|
||||||
</DialogTitle>
|
|
||||||
<DialogContent className="px-4 md:px-8 pb-4 md:pb-8 text-txt-primary">
|
|
||||||
<p className="text-txt-secondary mb-4">
|
|
||||||
{sprintf(
|
|
||||||
__(
|
|
||||||
"Request access to %s's Trust Center. Your request will be reviewed and you will receive an email notification with access instructions if approved.",
|
|
||||||
),
|
|
||||||
trustCenter.organization.name,
|
|
||||||
)}
|
|
||||||
</p>
|
|
||||||
{!viewer && (
|
|
||||||
<div className="space-y-4">
|
|
||||||
<Field
|
|
||||||
label={__("Full name")}
|
|
||||||
placeholder="John Doe"
|
|
||||||
{...register("fullName")}
|
|
||||||
type="text"
|
|
||||||
/>
|
|
||||||
<Field
|
|
||||||
label={__("Email")}
|
|
||||||
placeholder="john.doe@acme.com"
|
|
||||||
{...register("email")}
|
|
||||||
type="email"
|
|
||||||
error={formState.errors.email?.message}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</DialogContent>
|
|
||||||
<DialogFooter>
|
|
||||||
<Button disabled={isMutating} type="submit">
|
|
||||||
{__("Continue")}
|
|
||||||
</Button>
|
|
||||||
</DialogFooter>
|
|
||||||
</form>
|
|
||||||
</Dialog>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const requestAccessMutation = graphql`
|
|
||||||
mutation RequestAccessDialogMutation($input: RequestAllAccessesInput!) {
|
|
||||||
requestAllAccesses(input: $input) {
|
|
||||||
trustCenterAccess {
|
|
||||||
id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const requestDocumentAccessMutation = graphql`
|
|
||||||
mutation RequestAccessDialogDocumentMutation(
|
|
||||||
$input: RequestDocumentAccessInput!
|
|
||||||
) {
|
|
||||||
requestDocumentAccess(input: $input) {
|
|
||||||
trustCenterAccess {
|
|
||||||
id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const requestReportAccessMutation = graphql`
|
|
||||||
mutation RequestAccessDialogReportMutation(
|
|
||||||
$input: RequestReportAccessInput!
|
|
||||||
) {
|
|
||||||
requestReportAccess(input: $input) {
|
|
||||||
trustCenterAccess {
|
|
||||||
id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const requestTrustCenterFileAccessMutation = graphql`
|
|
||||||
mutation RequestAccessDialogTrustCenterFileMutation(
|
|
||||||
$input: RequestTrustCenterFileAccessInput!
|
|
||||||
) {
|
|
||||||
requestTrustCenterFileAccess(input: $input) {
|
|
||||||
trustCenterAccess {
|
|
||||||
id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Use the correct mutation using the shape
|
|
||||||
*/
|
|
||||||
function useMutation({
|
|
||||||
documentId,
|
|
||||||
reportId,
|
|
||||||
trustCenterFileId,
|
|
||||||
}: Pick<Props, "documentId" | "reportId" | "trustCenterFileId">): [
|
|
||||||
(data: z.infer<typeof schema> | null) => Promise<unknown>,
|
|
||||||
boolean,
|
|
||||||
] {
|
|
||||||
const trustCenter = useTrustCenter();
|
|
||||||
const [commitRequestAccess, isRequestingAccess] = useMutationWithToasts(
|
|
||||||
requestAccessMutation,
|
|
||||||
);
|
|
||||||
const [commitRequestDocumentAccess, isRequestingDocumentAccess] =
|
|
||||||
useMutationWithToasts(requestDocumentAccessMutation);
|
|
||||||
const [commitRequestReportAccess, isRequestingReportAccess] =
|
|
||||||
useMutationWithToasts(requestReportAccessMutation);
|
|
||||||
const [
|
|
||||||
commitRequestTrustCenterFileAccess,
|
|
||||||
isRequestingTrustCenterFileAccess,
|
|
||||||
] = useMutationWithToasts(requestTrustCenterFileAccessMutation);
|
|
||||||
|
|
||||||
if (trustCenterFileId) {
|
|
||||||
return [
|
|
||||||
(data) => {
|
|
||||||
return commitRequestTrustCenterFileAccess({
|
|
||||||
variables: {
|
|
||||||
input: {
|
|
||||||
trustCenterId: trustCenter.id,
|
|
||||||
trustCenterFileId: trustCenterFileId,
|
|
||||||
...data,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
isRequestingTrustCenterFileAccess,
|
|
||||||
];
|
|
||||||
} else if (reportId) {
|
|
||||||
return [
|
|
||||||
(data) => {
|
|
||||||
return commitRequestReportAccess({
|
|
||||||
variables: {
|
|
||||||
input: {
|
|
||||||
trustCenterId: trustCenter.id,
|
|
||||||
reportId: reportId,
|
|
||||||
...data,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
isRequestingReportAccess,
|
|
||||||
];
|
|
||||||
} else if (documentId) {
|
|
||||||
return [
|
|
||||||
(data) => {
|
|
||||||
return commitRequestDocumentAccess({
|
|
||||||
variables: {
|
|
||||||
input: {
|
|
||||||
trustCenterId: trustCenter.id,
|
|
||||||
documentId: documentId,
|
|
||||||
...data,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
isRequestingDocumentAccess,
|
|
||||||
];
|
|
||||||
} else {
|
|
||||||
return [
|
|
||||||
(data) => {
|
|
||||||
return commitRequestAccess({
|
|
||||||
variables: {
|
|
||||||
input: {
|
|
||||||
trustCenterId: trustCenter.id,
|
|
||||||
...data,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
isRequestingAccess,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,22 +1,39 @@
|
|||||||
import { graphql } from "relay-runtime";
|
import { graphql } from "relay-runtime";
|
||||||
import type { TrustCenterFileRowFragment$key } from "./__generated__/TrustCenterFileRowFragment.graphql";
|
import type { TrustCenterFileRowFragment$key } from "./__generated__/TrustCenterFileRowFragment.graphql";
|
||||||
import { useFragment } from "react-relay";
|
import { useFragment, useMutation } from "react-relay";
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
IconArrowInbox,
|
IconArrowInbox,
|
||||||
IconLock,
|
IconLock,
|
||||||
IconPageTextLine,
|
IconPageTextLine,
|
||||||
Spinner,
|
Spinner,
|
||||||
|
useToast,
|
||||||
} from "@probo/ui";
|
} from "@probo/ui";
|
||||||
import { useTranslate } from "@probo/i18n";
|
import { useTranslate } from "@probo/i18n";
|
||||||
import type { TrustCenterFileRowDownloadMutation } from "./__generated__/TrustCenterFileRowDownloadMutation.graphql";
|
import type { TrustCenterFileRowDownloadMutation } from "./__generated__/TrustCenterFileRowDownloadMutation.graphql";
|
||||||
import { useMutationWithToasts } from "/hooks/useMutationWithToast";
|
import { useMutationWithToasts } from "/hooks/useMutationWithToast";
|
||||||
import { downloadFile } from "@probo/helpers";
|
import { downloadFile, formatError } from "@probo/helpers";
|
||||||
import { RequestAccessDialog } from "/components/RequestAccessDialog.tsx";
|
import { use, useState } from "react";
|
||||||
import { useState } from "react";
|
import { Viewer } from "/providers/Viewer";
|
||||||
|
import { MagicLinkDialog } from "./MagicLinkDialog";
|
||||||
|
import type { TrustCenterFileRow_requestAccessMutation } from "./__generated__/TrustCenterFileRow_requestAccessMutation.graphql";
|
||||||
|
|
||||||
|
const requestAccessMutation = graphql`
|
||||||
|
mutation TrustCenterFileRow_requestAccessMutation(
|
||||||
|
$input: RequestTrustCenterFileAccessInput!
|
||||||
|
) {
|
||||||
|
requestTrustCenterFileAccess(input: $input) {
|
||||||
|
trustCenterAccess {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
const downloadMutation = graphql`
|
const downloadMutation = graphql`
|
||||||
mutation TrustCenterFileRowDownloadMutation($input: ExportTrustCenterFileInput!) {
|
mutation TrustCenterFileRowDownloadMutation(
|
||||||
|
$input: ExportTrustCenterFileInput!
|
||||||
|
) {
|
||||||
exportTrustCenterFile(input: $input) {
|
exportTrustCenterFile(input: $input) {
|
||||||
data
|
data
|
||||||
}
|
}
|
||||||
@@ -32,11 +49,56 @@ const trustCenterFileRowFragment = graphql`
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export function TrustCenterFileRow(props: { file: TrustCenterFileRowFragment$key }) {
|
export function TrustCenterFileRow(props: {
|
||||||
const file = useFragment(trustCenterFileRowFragment, props.file);
|
file: TrustCenterFileRowFragment$key;
|
||||||
|
}) {
|
||||||
const { __ } = useTranslate();
|
const { __ } = useTranslate();
|
||||||
|
const viewer = use(Viewer);
|
||||||
|
const { toast } = useToast();
|
||||||
|
|
||||||
|
const file = useFragment(trustCenterFileRowFragment, props.file);
|
||||||
|
const [hasRequested, setHasRequested] = useState(file.hasUserRequestedAccess);
|
||||||
|
|
||||||
|
const [requestAccess, isRequestingAccess] =
|
||||||
|
useMutation<TrustCenterFileRow_requestAccessMutation>(
|
||||||
|
requestAccessMutation,
|
||||||
|
);
|
||||||
const [commitDownload, downloading] =
|
const [commitDownload, downloading] =
|
||||||
useMutationWithToasts<TrustCenterFileRowDownloadMutation>(downloadMutation);
|
useMutationWithToasts<TrustCenterFileRowDownloadMutation>(downloadMutation);
|
||||||
|
|
||||||
|
const handleRequestAccess = () => {
|
||||||
|
requestAccess({
|
||||||
|
variables: {
|
||||||
|
input: {
|
||||||
|
trustCenterFileId: file.id,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
onCompleted: (_, errors) => {
|
||||||
|
if (errors?.length) {
|
||||||
|
toast({
|
||||||
|
title: __("Error"),
|
||||||
|
description: formatError(__("Cannot request access"), errors),
|
||||||
|
variant: "error",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setHasRequested(true);
|
||||||
|
toast({
|
||||||
|
title: __("Success"),
|
||||||
|
description: __("Access request submitted successfully."),
|
||||||
|
variant: "success",
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onError: (error) => {
|
||||||
|
toast({
|
||||||
|
title: __("Error"),
|
||||||
|
description: error.message ?? __("Cannot request access"),
|
||||||
|
variant: "error",
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const handleDownload = () => {
|
const handleDownload = () => {
|
||||||
commitDownload({
|
commitDownload({
|
||||||
variables: {
|
variables: {
|
||||||
@@ -49,16 +111,26 @@ export function TrustCenterFileRow(props: { file: TrustCenterFileRowFragment$key
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
const [hasRequested, setHasRequested] = useState(
|
|
||||||
file.hasUserRequestedAccess,
|
|
||||||
);
|
|
||||||
return (
|
return (
|
||||||
<div className="text-sm border-1 border-border-solid -mt-[1px] flex gap-3 flex-col md:flex-row md:justify-between px-6 py-3">
|
<div className="text-sm border border-border-solid -mt-px flex gap-3 flex-col md:flex-row md:justify-between px-6 py-3">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<IconPageTextLine size={16} className=" flex-none text-txt-tertiary" />
|
<IconPageTextLine size={16} className=" flex-none text-txt-tertiary" />
|
||||||
{file.name}
|
{file.name}
|
||||||
</div>
|
</div>
|
||||||
{file.isUserAuthorized ? (
|
{!viewer && (
|
||||||
|
<MagicLinkDialog>
|
||||||
|
<Button
|
||||||
|
className="w-full md:w-max"
|
||||||
|
variant="secondary"
|
||||||
|
icon={IconLock}
|
||||||
|
>
|
||||||
|
{hasRequested ? __("Access requested") : __("Request access")}
|
||||||
|
</Button>
|
||||||
|
</MagicLinkDialog>
|
||||||
|
)}
|
||||||
|
{viewer &&
|
||||||
|
(file.isUserAuthorized ? (
|
||||||
<Button
|
<Button
|
||||||
className="w-full md:w-max"
|
className="w-full md:w-max"
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
@@ -69,20 +141,16 @@ export function TrustCenterFileRow(props: { file: TrustCenterFileRowFragment$key
|
|||||||
{__("Download")}
|
{__("Download")}
|
||||||
</Button>
|
</Button>
|
||||||
) : (
|
) : (
|
||||||
<RequestAccessDialog
|
|
||||||
trustCenterFileId={file.id}
|
|
||||||
onSuccess={() => setHasRequested(true)}
|
|
||||||
>
|
|
||||||
<Button
|
<Button
|
||||||
disabled={hasRequested}
|
disabled={hasRequested || isRequestingAccess}
|
||||||
className="w-full md:w-max"
|
className="w-full md:w-max"
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
icon={IconLock}
|
icon={IconLock}
|
||||||
|
onClick={handleRequestAccess}
|
||||||
>
|
>
|
||||||
{hasRequested ? __("Access requested") : __("Request access")}
|
{hasRequested ? __("Access requested") : __("Request access")}
|
||||||
</Button>
|
</Button>
|
||||||
</RequestAccessDialog>
|
))}
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
105
apps/trust/src/components/__generated__/AuditRow_requestAccessMutation.graphql.ts
generated
Normal file
105
apps/trust/src/components/__generated__/AuditRow_requestAccessMutation.graphql.ts
generated
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
/**
|
||||||
|
* @generated SignedSource<<0e5c234b565a3031a774995bff249b97>>
|
||||||
|
* @lightSyntaxTransform
|
||||||
|
* @nogrep
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
// @ts-nocheck
|
||||||
|
|
||||||
|
import { ConcreteRequest } from 'relay-runtime';
|
||||||
|
export type RequestReportAccessInput = {
|
||||||
|
reportId: string;
|
||||||
|
};
|
||||||
|
export type AuditRow_requestAccessMutation$variables = {
|
||||||
|
input: RequestReportAccessInput;
|
||||||
|
};
|
||||||
|
export type AuditRow_requestAccessMutation$data = {
|
||||||
|
readonly requestReportAccess: {
|
||||||
|
readonly trustCenterAccess: {
|
||||||
|
readonly id: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
export type AuditRow_requestAccessMutation = {
|
||||||
|
response: AuditRow_requestAccessMutation$data;
|
||||||
|
variables: AuditRow_requestAccessMutation$variables;
|
||||||
|
};
|
||||||
|
|
||||||
|
const node: ConcreteRequest = (function(){
|
||||||
|
var v0 = [
|
||||||
|
{
|
||||||
|
"defaultValue": null,
|
||||||
|
"kind": "LocalArgument",
|
||||||
|
"name": "input"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
v1 = [
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": [
|
||||||
|
{
|
||||||
|
"kind": "Variable",
|
||||||
|
"name": "input",
|
||||||
|
"variableName": "input"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"concreteType": "RequestAccessesPayload",
|
||||||
|
"kind": "LinkedField",
|
||||||
|
"name": "requestReportAccess",
|
||||||
|
"plural": false,
|
||||||
|
"selections": [
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"concreteType": "TrustCenterAccess",
|
||||||
|
"kind": "LinkedField",
|
||||||
|
"name": "trustCenterAccess",
|
||||||
|
"plural": false,
|
||||||
|
"selections": [
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "id",
|
||||||
|
"storageKey": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"storageKey": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"storageKey": null
|
||||||
|
}
|
||||||
|
];
|
||||||
|
return {
|
||||||
|
"fragment": {
|
||||||
|
"argumentDefinitions": (v0/*: any*/),
|
||||||
|
"kind": "Fragment",
|
||||||
|
"metadata": null,
|
||||||
|
"name": "AuditRow_requestAccessMutation",
|
||||||
|
"selections": (v1/*: any*/),
|
||||||
|
"type": "Mutation",
|
||||||
|
"abstractKey": null
|
||||||
|
},
|
||||||
|
"kind": "Request",
|
||||||
|
"operation": {
|
||||||
|
"argumentDefinitions": (v0/*: any*/),
|
||||||
|
"kind": "Operation",
|
||||||
|
"name": "AuditRow_requestAccessMutation",
|
||||||
|
"selections": (v1/*: any*/)
|
||||||
|
},
|
||||||
|
"params": {
|
||||||
|
"cacheID": "6760f1ec8a6990f62461c3fab2b2934a",
|
||||||
|
"id": null,
|
||||||
|
"metadata": {},
|
||||||
|
"name": "AuditRow_requestAccessMutation",
|
||||||
|
"operationKind": "mutation",
|
||||||
|
"text": "mutation AuditRow_requestAccessMutation(\n $input: RequestReportAccessInput!\n) {\n requestReportAccess(input: $input) {\n trustCenterAccess {\n id\n }\n }\n}\n"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
|
(node as any).hash = "6ab5eb701126385e717a381e21e55ae0";
|
||||||
|
|
||||||
|
export default node;
|
||||||
105
apps/trust/src/components/__generated__/DocumentRow_requestAccessMutation.graphql.ts
generated
Normal file
105
apps/trust/src/components/__generated__/DocumentRow_requestAccessMutation.graphql.ts
generated
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
/**
|
||||||
|
* @generated SignedSource<<e62c28d53365ca5d5f3d53282aefd4e7>>
|
||||||
|
* @lightSyntaxTransform
|
||||||
|
* @nogrep
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
// @ts-nocheck
|
||||||
|
|
||||||
|
import { ConcreteRequest } from 'relay-runtime';
|
||||||
|
export type RequestDocumentAccessInput = {
|
||||||
|
documentId: string;
|
||||||
|
};
|
||||||
|
export type DocumentRow_requestAccessMutation$variables = {
|
||||||
|
input: RequestDocumentAccessInput;
|
||||||
|
};
|
||||||
|
export type DocumentRow_requestAccessMutation$data = {
|
||||||
|
readonly requestDocumentAccess: {
|
||||||
|
readonly trustCenterAccess: {
|
||||||
|
readonly id: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
export type DocumentRow_requestAccessMutation = {
|
||||||
|
response: DocumentRow_requestAccessMutation$data;
|
||||||
|
variables: DocumentRow_requestAccessMutation$variables;
|
||||||
|
};
|
||||||
|
|
||||||
|
const node: ConcreteRequest = (function(){
|
||||||
|
var v0 = [
|
||||||
|
{
|
||||||
|
"defaultValue": null,
|
||||||
|
"kind": "LocalArgument",
|
||||||
|
"name": "input"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
v1 = [
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": [
|
||||||
|
{
|
||||||
|
"kind": "Variable",
|
||||||
|
"name": "input",
|
||||||
|
"variableName": "input"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"concreteType": "RequestAccessesPayload",
|
||||||
|
"kind": "LinkedField",
|
||||||
|
"name": "requestDocumentAccess",
|
||||||
|
"plural": false,
|
||||||
|
"selections": [
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"concreteType": "TrustCenterAccess",
|
||||||
|
"kind": "LinkedField",
|
||||||
|
"name": "trustCenterAccess",
|
||||||
|
"plural": false,
|
||||||
|
"selections": [
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "id",
|
||||||
|
"storageKey": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"storageKey": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"storageKey": null
|
||||||
|
}
|
||||||
|
];
|
||||||
|
return {
|
||||||
|
"fragment": {
|
||||||
|
"argumentDefinitions": (v0/*: any*/),
|
||||||
|
"kind": "Fragment",
|
||||||
|
"metadata": null,
|
||||||
|
"name": "DocumentRow_requestAccessMutation",
|
||||||
|
"selections": (v1/*: any*/),
|
||||||
|
"type": "Mutation",
|
||||||
|
"abstractKey": null
|
||||||
|
},
|
||||||
|
"kind": "Request",
|
||||||
|
"operation": {
|
||||||
|
"argumentDefinitions": (v0/*: any*/),
|
||||||
|
"kind": "Operation",
|
||||||
|
"name": "DocumentRow_requestAccessMutation",
|
||||||
|
"selections": (v1/*: any*/)
|
||||||
|
},
|
||||||
|
"params": {
|
||||||
|
"cacheID": "13715b7cb8784d050b6d0381e460bbad",
|
||||||
|
"id": null,
|
||||||
|
"metadata": {},
|
||||||
|
"name": "DocumentRow_requestAccessMutation",
|
||||||
|
"operationKind": "mutation",
|
||||||
|
"text": "mutation DocumentRow_requestAccessMutation(\n $input: RequestDocumentAccessInput!\n) {\n requestDocumentAccess(input: $input) {\n trustCenterAccess {\n id\n }\n }\n}\n"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
|
(node as any).hash = "ca9026b04c2de91067759e3a80e5c276";
|
||||||
|
|
||||||
|
export default node;
|
||||||
92
apps/trust/src/components/__generated__/MagicLinkDialogMutation.graphql.ts
generated
Normal file
92
apps/trust/src/components/__generated__/MagicLinkDialogMutation.graphql.ts
generated
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
/**
|
||||||
|
* @generated SignedSource<<1d6509148442dad28e2af20068216f49>>
|
||||||
|
* @lightSyntaxTransform
|
||||||
|
* @nogrep
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
// @ts-nocheck
|
||||||
|
|
||||||
|
import { ConcreteRequest } from 'relay-runtime';
|
||||||
|
export type SendMagicLinkInput = {
|
||||||
|
email: any;
|
||||||
|
};
|
||||||
|
export type MagicLinkDialogMutation$variables = {
|
||||||
|
input: SendMagicLinkInput;
|
||||||
|
};
|
||||||
|
export type MagicLinkDialogMutation$data = {
|
||||||
|
readonly sendMagicLink: {
|
||||||
|
readonly success: boolean;
|
||||||
|
} | null | undefined;
|
||||||
|
};
|
||||||
|
export type MagicLinkDialogMutation = {
|
||||||
|
response: MagicLinkDialogMutation$data;
|
||||||
|
variables: MagicLinkDialogMutation$variables;
|
||||||
|
};
|
||||||
|
|
||||||
|
const node: ConcreteRequest = (function(){
|
||||||
|
var v0 = [
|
||||||
|
{
|
||||||
|
"defaultValue": null,
|
||||||
|
"kind": "LocalArgument",
|
||||||
|
"name": "input"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
v1 = [
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": [
|
||||||
|
{
|
||||||
|
"kind": "Variable",
|
||||||
|
"name": "input",
|
||||||
|
"variableName": "input"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"concreteType": "SendMagicLinkPayload",
|
||||||
|
"kind": "LinkedField",
|
||||||
|
"name": "sendMagicLink",
|
||||||
|
"plural": false,
|
||||||
|
"selections": [
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "success",
|
||||||
|
"storageKey": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"storageKey": null
|
||||||
|
}
|
||||||
|
];
|
||||||
|
return {
|
||||||
|
"fragment": {
|
||||||
|
"argumentDefinitions": (v0/*: any*/),
|
||||||
|
"kind": "Fragment",
|
||||||
|
"metadata": null,
|
||||||
|
"name": "MagicLinkDialogMutation",
|
||||||
|
"selections": (v1/*: any*/),
|
||||||
|
"type": "Mutation",
|
||||||
|
"abstractKey": null
|
||||||
|
},
|
||||||
|
"kind": "Request",
|
||||||
|
"operation": {
|
||||||
|
"argumentDefinitions": (v0/*: any*/),
|
||||||
|
"kind": "Operation",
|
||||||
|
"name": "MagicLinkDialogMutation",
|
||||||
|
"selections": (v1/*: any*/)
|
||||||
|
},
|
||||||
|
"params": {
|
||||||
|
"cacheID": "d0e02db0cec956d7a21f5ad5a5a69d61",
|
||||||
|
"id": null,
|
||||||
|
"metadata": {},
|
||||||
|
"name": "MagicLinkDialogMutation",
|
||||||
|
"operationKind": "mutation",
|
||||||
|
"text": "mutation MagicLinkDialogMutation(\n $input: SendMagicLinkInput!\n) {\n sendMagicLink(input: $input) {\n success\n }\n}\n"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
|
(node as any).hash = "c1ee1fe3ef7c232fcb43b5cf8e56c2de";
|
||||||
|
|
||||||
|
export default node;
|
||||||
87
apps/trust/src/components/__generated__/OrganizationSidebar_requestAllAccessesMutation.graphql.ts
generated
Normal file
87
apps/trust/src/components/__generated__/OrganizationSidebar_requestAllAccessesMutation.graphql.ts
generated
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
/**
|
||||||
|
* @generated SignedSource<<e1d14b17505ed1107ac96553e3d8f922>>
|
||||||
|
* @lightSyntaxTransform
|
||||||
|
* @nogrep
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
// @ts-nocheck
|
||||||
|
|
||||||
|
import { ConcreteRequest } from 'relay-runtime';
|
||||||
|
export type OrganizationSidebar_requestAllAccessesMutation$variables = Record<PropertyKey, never>;
|
||||||
|
export type OrganizationSidebar_requestAllAccessesMutation$data = {
|
||||||
|
readonly requestAllAccesses: {
|
||||||
|
readonly trustCenterAccess: {
|
||||||
|
readonly id: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
export type OrganizationSidebar_requestAllAccessesMutation = {
|
||||||
|
response: OrganizationSidebar_requestAllAccessesMutation$data;
|
||||||
|
variables: OrganizationSidebar_requestAllAccessesMutation$variables;
|
||||||
|
};
|
||||||
|
|
||||||
|
const node: ConcreteRequest = (function(){
|
||||||
|
var v0 = [
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"concreteType": "RequestAccessesPayload",
|
||||||
|
"kind": "LinkedField",
|
||||||
|
"name": "requestAllAccesses",
|
||||||
|
"plural": false,
|
||||||
|
"selections": [
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"concreteType": "TrustCenterAccess",
|
||||||
|
"kind": "LinkedField",
|
||||||
|
"name": "trustCenterAccess",
|
||||||
|
"plural": false,
|
||||||
|
"selections": [
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "id",
|
||||||
|
"storageKey": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"storageKey": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"storageKey": null
|
||||||
|
}
|
||||||
|
];
|
||||||
|
return {
|
||||||
|
"fragment": {
|
||||||
|
"argumentDefinitions": [],
|
||||||
|
"kind": "Fragment",
|
||||||
|
"metadata": null,
|
||||||
|
"name": "OrganizationSidebar_requestAllAccessesMutation",
|
||||||
|
"selections": (v0/*: any*/),
|
||||||
|
"type": "Mutation",
|
||||||
|
"abstractKey": null
|
||||||
|
},
|
||||||
|
"kind": "Request",
|
||||||
|
"operation": {
|
||||||
|
"argumentDefinitions": [],
|
||||||
|
"kind": "Operation",
|
||||||
|
"name": "OrganizationSidebar_requestAllAccessesMutation",
|
||||||
|
"selections": (v0/*: any*/)
|
||||||
|
},
|
||||||
|
"params": {
|
||||||
|
"cacheID": "a298b2a1c2f62300ae5056743d2c2ec3",
|
||||||
|
"id": null,
|
||||||
|
"metadata": {},
|
||||||
|
"name": "OrganizationSidebar_requestAllAccessesMutation",
|
||||||
|
"operationKind": "mutation",
|
||||||
|
"text": "mutation OrganizationSidebar_requestAllAccessesMutation {\n requestAllAccesses {\n trustCenterAccess {\n id\n }\n }\n}\n"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
|
(node as any).hash = "a22225757510c4dd097e99dcd3c066a6";
|
||||||
|
|
||||||
|
export default node;
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* @generated SignedSource<<9f01a480ccc5fa00e310296e9aed1020>>
|
* @generated SignedSource<<2ea33498f7101d861d940b9c52ed3283>>
|
||||||
* @lightSyntaxTransform
|
* @lightSyntaxTransform
|
||||||
* @nogrep
|
* @nogrep
|
||||||
*/
|
*/
|
||||||
@@ -11,8 +11,6 @@
|
|||||||
import { ConcreteRequest } from 'relay-runtime';
|
import { ConcreteRequest } from 'relay-runtime';
|
||||||
export type RequestDocumentAccessInput = {
|
export type RequestDocumentAccessInput = {
|
||||||
documentId: string;
|
documentId: string;
|
||||||
email: any;
|
|
||||||
fullName: string;
|
|
||||||
};
|
};
|
||||||
export type RequestAccessDialogDocumentMutation$variables = {
|
export type RequestAccessDialogDocumentMutation$variables = {
|
||||||
input: RequestDocumentAccessInput;
|
input: RequestDocumentAccessInput;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* @generated SignedSource<<0777fa7e6e3d0c75eedfc8380d9965a4>>
|
* @generated SignedSource<<b06c18474ea9953c2fb496b919b8e247>>
|
||||||
* @lightSyntaxTransform
|
* @lightSyntaxTransform
|
||||||
* @nogrep
|
* @nogrep
|
||||||
*/
|
*/
|
||||||
@@ -9,13 +9,7 @@
|
|||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
|
|
||||||
import { ConcreteRequest } from 'relay-runtime';
|
import { ConcreteRequest } from 'relay-runtime';
|
||||||
export type RequestAllAccessesInput = {
|
export type RequestAccessDialogMutation$variables = Record<PropertyKey, never>;
|
||||||
email: any;
|
|
||||||
fullName: string;
|
|
||||||
};
|
|
||||||
export type RequestAccessDialogMutation$variables = {
|
|
||||||
input: RequestAllAccessesInput;
|
|
||||||
};
|
|
||||||
export type RequestAccessDialogMutation$data = {
|
export type RequestAccessDialogMutation$data = {
|
||||||
readonly requestAllAccesses: {
|
readonly requestAllAccesses: {
|
||||||
readonly trustCenterAccess: {
|
readonly trustCenterAccess: {
|
||||||
@@ -30,22 +24,9 @@ export type RequestAccessDialogMutation = {
|
|||||||
|
|
||||||
const node: ConcreteRequest = (function(){
|
const node: ConcreteRequest = (function(){
|
||||||
var v0 = [
|
var v0 = [
|
||||||
{
|
|
||||||
"defaultValue": null,
|
|
||||||
"kind": "LocalArgument",
|
|
||||||
"name": "input"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
v1 = [
|
|
||||||
{
|
{
|
||||||
"alias": null,
|
"alias": null,
|
||||||
"args": [
|
"args": null,
|
||||||
{
|
|
||||||
"kind": "Variable",
|
|
||||||
"name": "input",
|
|
||||||
"variableName": "input"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"concreteType": "RequestAccessesPayload",
|
"concreteType": "RequestAccessesPayload",
|
||||||
"kind": "LinkedField",
|
"kind": "LinkedField",
|
||||||
"name": "requestAllAccesses",
|
"name": "requestAllAccesses",
|
||||||
@@ -75,32 +56,32 @@ v1 = [
|
|||||||
];
|
];
|
||||||
return {
|
return {
|
||||||
"fragment": {
|
"fragment": {
|
||||||
"argumentDefinitions": (v0/*: any*/),
|
"argumentDefinitions": [],
|
||||||
"kind": "Fragment",
|
"kind": "Fragment",
|
||||||
"metadata": null,
|
"metadata": null,
|
||||||
"name": "RequestAccessDialogMutation",
|
"name": "RequestAccessDialogMutation",
|
||||||
"selections": (v1/*: any*/),
|
"selections": (v0/*: any*/),
|
||||||
"type": "Mutation",
|
"type": "Mutation",
|
||||||
"abstractKey": null
|
"abstractKey": null
|
||||||
},
|
},
|
||||||
"kind": "Request",
|
"kind": "Request",
|
||||||
"operation": {
|
"operation": {
|
||||||
"argumentDefinitions": (v0/*: any*/),
|
"argumentDefinitions": [],
|
||||||
"kind": "Operation",
|
"kind": "Operation",
|
||||||
"name": "RequestAccessDialogMutation",
|
"name": "RequestAccessDialogMutation",
|
||||||
"selections": (v1/*: any*/)
|
"selections": (v0/*: any*/)
|
||||||
},
|
},
|
||||||
"params": {
|
"params": {
|
||||||
"cacheID": "99eb2902ce5a921515d68db30f8a2189",
|
"cacheID": "b48847e88c57289efc120745c743c8f6",
|
||||||
"id": null,
|
"id": null,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"name": "RequestAccessDialogMutation",
|
"name": "RequestAccessDialogMutation",
|
||||||
"operationKind": "mutation",
|
"operationKind": "mutation",
|
||||||
"text": "mutation RequestAccessDialogMutation(\n $input: RequestAllAccessesInput!\n) {\n requestAllAccesses(input: $input) {\n trustCenterAccess {\n id\n }\n }\n}\n"
|
"text": "mutation RequestAccessDialogMutation {\n requestAllAccesses {\n trustCenterAccess {\n id\n }\n }\n}\n"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
(node as any).hash = "cc4d5c8753438eff23833b4182dd485d";
|
(node as any).hash = "44c3538831968b7146fbf2c9e027a778";
|
||||||
|
|
||||||
export default node;
|
export default node;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* @generated SignedSource<<6fde198cd3eaa998d665639c48f5e630>>
|
* @generated SignedSource<<3e5433cc33d54bff9511d01eb4c65b00>>
|
||||||
* @lightSyntaxTransform
|
* @lightSyntaxTransform
|
||||||
* @nogrep
|
* @nogrep
|
||||||
*/
|
*/
|
||||||
@@ -10,8 +10,6 @@
|
|||||||
|
|
||||||
import { ConcreteRequest } from 'relay-runtime';
|
import { ConcreteRequest } from 'relay-runtime';
|
||||||
export type RequestReportAccessInput = {
|
export type RequestReportAccessInput = {
|
||||||
email: any;
|
|
||||||
fullName: string;
|
|
||||||
reportId: string;
|
reportId: string;
|
||||||
};
|
};
|
||||||
export type RequestAccessDialogReportMutation$variables = {
|
export type RequestAccessDialogReportMutation$variables = {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* @generated SignedSource<<7c329901bcf9bbf05b1899356016b151>>
|
* @generated SignedSource<<447bd664ebefbd6a672ccde86c63c028>>
|
||||||
* @lightSyntaxTransform
|
* @lightSyntaxTransform
|
||||||
* @nogrep
|
* @nogrep
|
||||||
*/
|
*/
|
||||||
@@ -10,8 +10,6 @@
|
|||||||
|
|
||||||
import { ConcreteRequest } from 'relay-runtime';
|
import { ConcreteRequest } from 'relay-runtime';
|
||||||
export type RequestTrustCenterFileAccessInput = {
|
export type RequestTrustCenterFileAccessInput = {
|
||||||
email: any;
|
|
||||||
fullName: string;
|
|
||||||
trustCenterFileId: string;
|
trustCenterFileId: string;
|
||||||
};
|
};
|
||||||
export type RequestAccessDialogTrustCenterFileMutation$variables = {
|
export type RequestAccessDialogTrustCenterFileMutation$variables = {
|
||||||
|
|||||||
105
apps/trust/src/components/__generated__/TrustCenterFileRow_requestAccessMutation.graphql.ts
generated
Normal file
105
apps/trust/src/components/__generated__/TrustCenterFileRow_requestAccessMutation.graphql.ts
generated
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
/**
|
||||||
|
* @generated SignedSource<<a8da5aa24d8696b55231f44d861f347c>>
|
||||||
|
* @lightSyntaxTransform
|
||||||
|
* @nogrep
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
// @ts-nocheck
|
||||||
|
|
||||||
|
import { ConcreteRequest } from 'relay-runtime';
|
||||||
|
export type RequestTrustCenterFileAccessInput = {
|
||||||
|
trustCenterFileId: string;
|
||||||
|
};
|
||||||
|
export type TrustCenterFileRow_requestAccessMutation$variables = {
|
||||||
|
input: RequestTrustCenterFileAccessInput;
|
||||||
|
};
|
||||||
|
export type TrustCenterFileRow_requestAccessMutation$data = {
|
||||||
|
readonly requestTrustCenterFileAccess: {
|
||||||
|
readonly trustCenterAccess: {
|
||||||
|
readonly id: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
export type TrustCenterFileRow_requestAccessMutation = {
|
||||||
|
response: TrustCenterFileRow_requestAccessMutation$data;
|
||||||
|
variables: TrustCenterFileRow_requestAccessMutation$variables;
|
||||||
|
};
|
||||||
|
|
||||||
|
const node: ConcreteRequest = (function(){
|
||||||
|
var v0 = [
|
||||||
|
{
|
||||||
|
"defaultValue": null,
|
||||||
|
"kind": "LocalArgument",
|
||||||
|
"name": "input"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
v1 = [
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": [
|
||||||
|
{
|
||||||
|
"kind": "Variable",
|
||||||
|
"name": "input",
|
||||||
|
"variableName": "input"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"concreteType": "RequestAccessesPayload",
|
||||||
|
"kind": "LinkedField",
|
||||||
|
"name": "requestTrustCenterFileAccess",
|
||||||
|
"plural": false,
|
||||||
|
"selections": [
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"concreteType": "TrustCenterAccess",
|
||||||
|
"kind": "LinkedField",
|
||||||
|
"name": "trustCenterAccess",
|
||||||
|
"plural": false,
|
||||||
|
"selections": [
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "id",
|
||||||
|
"storageKey": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"storageKey": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"storageKey": null
|
||||||
|
}
|
||||||
|
];
|
||||||
|
return {
|
||||||
|
"fragment": {
|
||||||
|
"argumentDefinitions": (v0/*: any*/),
|
||||||
|
"kind": "Fragment",
|
||||||
|
"metadata": null,
|
||||||
|
"name": "TrustCenterFileRow_requestAccessMutation",
|
||||||
|
"selections": (v1/*: any*/),
|
||||||
|
"type": "Mutation",
|
||||||
|
"abstractKey": null
|
||||||
|
},
|
||||||
|
"kind": "Request",
|
||||||
|
"operation": {
|
||||||
|
"argumentDefinitions": (v0/*: any*/),
|
||||||
|
"kind": "Operation",
|
||||||
|
"name": "TrustCenterFileRow_requestAccessMutation",
|
||||||
|
"selections": (v1/*: any*/)
|
||||||
|
},
|
||||||
|
"params": {
|
||||||
|
"cacheID": "77a09810aa9c3ddf3a3baddf709f9a42",
|
||||||
|
"id": null,
|
||||||
|
"metadata": {},
|
||||||
|
"name": "TrustCenterFileRow_requestAccessMutation",
|
||||||
|
"operationKind": "mutation",
|
||||||
|
"text": "mutation TrustCenterFileRow_requestAccessMutation(\n $input: RequestTrustCenterFileAccessInput!\n) {\n requestTrustCenterFileAccess(input: $input) {\n trustCenterAccess {\n id\n }\n }\n}\n"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
|
(node as any).hash = "eba04489de9ec18ab9816328a481ef33";
|
||||||
|
|
||||||
|
export default node;
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
import { useTranslate } from "@probo/i18n";
|
|
||||||
import { useEffect, useState } from "react";
|
|
||||||
import { useNavigate, useSearchParams } from "react-router";
|
|
||||||
import { buildEndpoint } from "/providers/RelayProviders";
|
|
||||||
import { PageError } from "/components/PageError";
|
|
||||||
import { Spinner } from "@probo/ui";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Page requested with an access token to authenticate the user for the Trust center
|
|
||||||
*/
|
|
||||||
export function AccessPage() {
|
|
||||||
const { __ } = useTranslate();
|
|
||||||
const [searchParams] = useSearchParams();
|
|
||||||
const token = searchParams.get("token");
|
|
||||||
const navigate = useNavigate();
|
|
||||||
|
|
||||||
const isValidRequest = !!token;
|
|
||||||
const [error, setError] = useState<string | null>(() => {
|
|
||||||
if (!token) {
|
|
||||||
return __("Invalid access token");
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Initiate an authentication attempt
|
|
||||||
useEffect(() => {
|
|
||||||
if (!isValidRequest) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
fetch(buildEndpoint("/api/trust/v1/auth/authenticate"), {
|
|
||||||
method: "POST",
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
token,
|
|
||||||
}),
|
|
||||||
})
|
|
||||||
.then((response) => {
|
|
||||||
// For invalid response throw an error
|
|
||||||
if (!response.ok) {
|
|
||||||
const defaultMessage = `HTTP ${response.status}: ${response.statusText}`;
|
|
||||||
return response
|
|
||||||
.json()
|
|
||||||
.then((json) => {
|
|
||||||
throw new Error(json.message ?? defaultMessage);
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
throw new Error(defaultMessage);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return response.json();
|
|
||||||
})
|
|
||||||
.then((data) => {
|
|
||||||
if (data.success) {
|
|
||||||
navigate("/overview");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
throw new Error(data.message ?? __("Authentication failed"));
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
setError(error.message);
|
|
||||||
});
|
|
||||||
}, [isValidRequest, token, __, navigate]);
|
|
||||||
|
|
||||||
if (error) {
|
|
||||||
return <PageError error={error} />;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="p-4 text-center flex items-center justify-center gap-2">
|
|
||||||
<Spinner size={16} />
|
|
||||||
{__("Redirecting to trust center")}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
19
apps/trust/src/pages/auth/AuthLayout.tsx
Normal file
19
apps/trust/src/pages/auth/AuthLayout.tsx
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import { Logo } from "@probo/ui";
|
||||||
|
import { Outlet } from "react-router";
|
||||||
|
|
||||||
|
export default function () {
|
||||||
|
return (
|
||||||
|
<div className="grid grid-cols-1 lg:grid-cols-2 min-h-screen text-txt-primary">
|
||||||
|
<div className="bg-level-0 flex flex-col items-center justify-center">
|
||||||
|
<div className="w-full max-w-md px-6">
|
||||||
|
<Outlet />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="hidden lg:flex bg-dialog font-bold flex-col items-center justify-center p-8 text-txt-primary lg:p-10">
|
||||||
|
<div className="flex flex-col items-center justify-center gap-4">
|
||||||
|
<Logo withPicto className="w-[440px]" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
119
apps/trust/src/pages/auth/VerifyMagicLinkPage.tsx
Normal file
119
apps/trust/src/pages/auth/VerifyMagicLinkPage.tsx
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
import { usePageTitle } from "@probo/hooks";
|
||||||
|
import { useTranslate } from "@probo/i18n";
|
||||||
|
import { Button, Field, useToast } from "@probo/ui";
|
||||||
|
import { useSearchParams } from "react-router";
|
||||||
|
import { useFormWithSchema } from "/hooks/useFormWithSchema";
|
||||||
|
import z from "zod";
|
||||||
|
import { useEffect, useRef } from "react";
|
||||||
|
import { graphql } from "relay-runtime";
|
||||||
|
import { useMutation } from "react-relay";
|
||||||
|
import { formatError } from "@probo/helpers";
|
||||||
|
import type { VerifyMagicLinkPageMutation } from "./__generated__/VerifyMagicLinkPageMutation.graphql";
|
||||||
|
import { getPathPrefix } from "/utils/pathPrefix";
|
||||||
|
|
||||||
|
const verifyMagicLinkMutation = graphql`
|
||||||
|
mutation VerifyMagicLinkPageMutation($input: VerifyMagicLinkInput!) {
|
||||||
|
verifyMagicLink(input: $input) {
|
||||||
|
success
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const verifyMagicLinkSchema = z.object({
|
||||||
|
token: z.string().min(1, "Please enter a magic token"),
|
||||||
|
});
|
||||||
|
|
||||||
|
export default function VerifyMagicLinkPagePageMutation() {
|
||||||
|
const { __ } = useTranslate();
|
||||||
|
const { toast } = useToast();
|
||||||
|
const [searchParams] = useSearchParams();
|
||||||
|
const submittedRef = useRef<boolean>(false);
|
||||||
|
|
||||||
|
usePageTitle(__("Verify Magic Link"));
|
||||||
|
|
||||||
|
const form = useFormWithSchema(verifyMagicLinkSchema, {
|
||||||
|
defaultValues: {
|
||||||
|
token: searchParams.get("token") ?? "",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const [verifyMagicLink] = useMutation<VerifyMagicLinkPageMutation>(
|
||||||
|
verifyMagicLinkMutation,
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleSubmit = form.handleSubmit(async (data) => {
|
||||||
|
verifyMagicLink({
|
||||||
|
variables: {
|
||||||
|
input: {
|
||||||
|
token: data.token.trim(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
onCompleted: (_, errors) => {
|
||||||
|
if (errors) {
|
||||||
|
toast({
|
||||||
|
title: __("Error"),
|
||||||
|
description: formatError(__("Failed to connect"), errors),
|
||||||
|
variant: "error",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
toast({
|
||||||
|
title: __("Success"),
|
||||||
|
description: __("Your have successfully signed in"),
|
||||||
|
variant: "success",
|
||||||
|
});
|
||||||
|
window.location.href = getPathPrefix();
|
||||||
|
},
|
||||||
|
onError: (err) => {
|
||||||
|
toast({
|
||||||
|
title: __("Error"),
|
||||||
|
description: err.message,
|
||||||
|
variant: "error",
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!submittedRef.current && searchParams.get("token")) {
|
||||||
|
handleSubmit();
|
||||||
|
submittedRef.current = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="space-y-6 w-full max-w-md mx-auto">
|
||||||
|
<div className="space-y-2 text-center">
|
||||||
|
<h1 className="text-3xl font-bold">{__("Email Confirmation")}</h1>
|
||||||
|
<p className="text-txt-tertiary">
|
||||||
|
{__("Confirm your email address to complete registration")}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form onSubmit={handleSubmit} className="space-y-4">
|
||||||
|
<Field
|
||||||
|
label={__("Confirmation Token")}
|
||||||
|
type="text"
|
||||||
|
placeholder={__("Enter your confirmation token")}
|
||||||
|
{...form.register("token")}
|
||||||
|
error={form.formState.errors.token?.message}
|
||||||
|
disabled={form.formState.isSubmitting}
|
||||||
|
help={__(
|
||||||
|
"The token has been automatically filled from the URL if available",
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
type="submit"
|
||||||
|
className="w-full"
|
||||||
|
disabled={form.formState.isSubmitting}
|
||||||
|
>
|
||||||
|
{form.formState.isSubmitting
|
||||||
|
? __("Confirming...")
|
||||||
|
: __("Confirm Email")}
|
||||||
|
</Button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
92
apps/trust/src/pages/auth/__generated__/VerifyMagicLinkPageMutation.graphql.ts
generated
Normal file
92
apps/trust/src/pages/auth/__generated__/VerifyMagicLinkPageMutation.graphql.ts
generated
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
/**
|
||||||
|
* @generated SignedSource<<5037d9722f3c6cc15c2a323ef954e3d6>>
|
||||||
|
* @lightSyntaxTransform
|
||||||
|
* @nogrep
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
// @ts-nocheck
|
||||||
|
|
||||||
|
import { ConcreteRequest } from 'relay-runtime';
|
||||||
|
export type VerifyMagicLinkInput = {
|
||||||
|
token: string;
|
||||||
|
};
|
||||||
|
export type VerifyMagicLinkPageMutation$variables = {
|
||||||
|
input: VerifyMagicLinkInput;
|
||||||
|
};
|
||||||
|
export type VerifyMagicLinkPageMutation$data = {
|
||||||
|
readonly verifyMagicLink: {
|
||||||
|
readonly success: boolean;
|
||||||
|
} | null | undefined;
|
||||||
|
};
|
||||||
|
export type VerifyMagicLinkPageMutation = {
|
||||||
|
response: VerifyMagicLinkPageMutation$data;
|
||||||
|
variables: VerifyMagicLinkPageMutation$variables;
|
||||||
|
};
|
||||||
|
|
||||||
|
const node: ConcreteRequest = (function(){
|
||||||
|
var v0 = [
|
||||||
|
{
|
||||||
|
"defaultValue": null,
|
||||||
|
"kind": "LocalArgument",
|
||||||
|
"name": "input"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
v1 = [
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": [
|
||||||
|
{
|
||||||
|
"kind": "Variable",
|
||||||
|
"name": "input",
|
||||||
|
"variableName": "input"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"concreteType": "VerifyMagicLinkPayload",
|
||||||
|
"kind": "LinkedField",
|
||||||
|
"name": "verifyMagicLink",
|
||||||
|
"plural": false,
|
||||||
|
"selections": [
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "success",
|
||||||
|
"storageKey": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"storageKey": null
|
||||||
|
}
|
||||||
|
];
|
||||||
|
return {
|
||||||
|
"fragment": {
|
||||||
|
"argumentDefinitions": (v0/*: any*/),
|
||||||
|
"kind": "Fragment",
|
||||||
|
"metadata": null,
|
||||||
|
"name": "VerifyMagicLinkPageMutation",
|
||||||
|
"selections": (v1/*: any*/),
|
||||||
|
"type": "Mutation",
|
||||||
|
"abstractKey": null
|
||||||
|
},
|
||||||
|
"kind": "Request",
|
||||||
|
"operation": {
|
||||||
|
"argumentDefinitions": (v0/*: any*/),
|
||||||
|
"kind": "Operation",
|
||||||
|
"name": "VerifyMagicLinkPageMutation",
|
||||||
|
"selections": (v1/*: any*/)
|
||||||
|
},
|
||||||
|
"params": {
|
||||||
|
"cacheID": "07cf89de3f37725d847cda46557467f5",
|
||||||
|
"id": null,
|
||||||
|
"metadata": {},
|
||||||
|
"name": "VerifyMagicLinkPageMutation",
|
||||||
|
"operationKind": "mutation",
|
||||||
|
"text": "mutation VerifyMagicLinkPageMutation(\n $input: VerifyMagicLinkInput!\n) {\n verifyMagicLink(input: $input) {\n success\n }\n}\n"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
|
(node as any).hash = "074415601c4d50f50d177c06dfab64ef";
|
||||||
|
|
||||||
|
export default node;
|
||||||
@@ -8,6 +8,7 @@ import {
|
|||||||
import { GraphQLError } from "graphql";
|
import { GraphQLError } from "graphql";
|
||||||
import type { PropsWithChildren } from "react";
|
import type { PropsWithChildren } from "react";
|
||||||
import { RelayEnvironmentProvider } from "react-relay";
|
import { RelayEnvironmentProvider } from "react-relay";
|
||||||
|
import { getPathPrefix } from "/utils/pathPrefix";
|
||||||
|
|
||||||
export class UnAuthenticatedError extends Error {
|
export class UnAuthenticatedError extends Error {
|
||||||
constructor() {
|
constructor() {
|
||||||
@@ -35,11 +36,11 @@ export class InternalServerError extends Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function buildEndpoint(path: string): string {
|
export function buildEndpoint(): string {
|
||||||
const host = import.meta.env.VITE_API_URL;
|
let host = import.meta.env.VITE_API_URL;
|
||||||
|
|
||||||
if (!host) {
|
if (!host) {
|
||||||
return path;
|
host = window.location.origin;
|
||||||
}
|
}
|
||||||
|
|
||||||
const formattedHost =
|
const formattedHost =
|
||||||
@@ -49,10 +50,16 @@ export function buildEndpoint(path: string): string {
|
|||||||
|
|
||||||
const url = new URL(formattedHost);
|
const url = new URL(formattedHost);
|
||||||
|
|
||||||
if (path) {
|
const prefix = getPathPrefix();
|
||||||
url.pathname = path.startsWith("/") ? path : `/${path}`;
|
let path: string;
|
||||||
|
if (prefix) {
|
||||||
|
path = `${prefix}/api/trust/v1/graphql`;
|
||||||
|
} else {
|
||||||
|
path = `/api/trust/v1/graphql`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
url.pathname = path;
|
||||||
|
|
||||||
return url.toString();
|
return url.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,7 +73,7 @@ const fetchRelay: FetchFunction = async (
|
|||||||
request,
|
request,
|
||||||
variables,
|
variables,
|
||||||
_,
|
_,
|
||||||
uploadables
|
uploadables,
|
||||||
) => {
|
) => {
|
||||||
const requestInit: RequestInit = {
|
const requestInit: RequestInit = {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
@@ -82,7 +89,7 @@ const fetchRelay: FetchFunction = async (
|
|||||||
operationName: request.name,
|
operationName: request.name,
|
||||||
query: request.text,
|
query: request.text,
|
||||||
variables: variables,
|
variables: variables,
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
const uploadableMap: {
|
const uploadableMap: {
|
||||||
@@ -119,13 +126,7 @@ const fetchRelay: FetchFunction = async (
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use relative API path to ensure it goes through the same routing context
|
const response = await fetch(buildEndpoint(), requestInit);
|
||||||
// For /trust/slug/overview, this resolves to /trust/slug/api/trust/v1/graphql
|
|
||||||
// For custom domains at /overview, this resolves to /api/trust/v1/graphql
|
|
||||||
const response = await fetch(
|
|
||||||
buildEndpoint("./api/trust/v1/graphql"),
|
|
||||||
requestInit
|
|
||||||
);
|
|
||||||
|
|
||||||
if (response.status === 500) {
|
if (response.status === 500) {
|
||||||
throw new InternalServerError();
|
throw new InternalServerError();
|
||||||
@@ -144,8 +145,8 @@ const fetchRelay: FetchFunction = async (
|
|||||||
if (invalidError) {
|
if (invalidError) {
|
||||||
throw new InvalidError(
|
throw new InvalidError(
|
||||||
invalidError.message,
|
invalidError.message,
|
||||||
invalidError.extensions.field as string ?? "",
|
(invalidError.extensions.field as string) ?? "",
|
||||||
invalidError.extensions.cause as string ?? "",
|
(invalidError.extensions.cause as string) ?? "",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,6 @@
|
|||||||
import {
|
import { createBrowserRouter, redirect, useRouteError } from "react-router";
|
||||||
createBrowserRouter,
|
import { Fragment, lazy } from "react";
|
||||||
Navigate,
|
import { consoleEnvironment } from "./providers/RelayProviders.tsx";
|
||||||
redirect,
|
|
||||||
useRouteError,
|
|
||||||
} from "react-router";
|
|
||||||
import { Fragment } from "react";
|
|
||||||
import {
|
|
||||||
consoleEnvironment,
|
|
||||||
UnAuthenticatedError,
|
|
||||||
} from "./providers/RelayProviders.tsx";
|
|
||||||
import { loadQuery } from "react-relay";
|
import { loadQuery } from "react-relay";
|
||||||
import { PageError } from "./components/PageError.tsx";
|
import { PageError } from "./components/PageError.tsx";
|
||||||
import { MainLayout } from "/layouts/MainLayout";
|
import { MainLayout } from "/layouts/MainLayout";
|
||||||
@@ -20,7 +12,6 @@ import {
|
|||||||
import { OverviewPage } from "/pages/OverviewPage";
|
import { OverviewPage } from "/pages/OverviewPage";
|
||||||
import { DocumentsPage } from "/pages/DocumentsPage";
|
import { DocumentsPage } from "/pages/DocumentsPage";
|
||||||
import { SubprocessorsPage } from "/pages/SubprocessorsPage";
|
import { SubprocessorsPage } from "/pages/SubprocessorsPage";
|
||||||
import { AccessPage } from "./pages/AccessPage.tsx";
|
|
||||||
import { TabSkeleton } from "./components/Skeletons/TabSkeleton.tsx";
|
import { TabSkeleton } from "./components/Skeletons/TabSkeleton.tsx";
|
||||||
import { MainSkeleton } from "./components/Skeletons/MainSkeleton.tsx";
|
import { MainSkeleton } from "./components/Skeletons/MainSkeleton.tsx";
|
||||||
import {
|
import {
|
||||||
@@ -36,14 +27,20 @@ import {
|
|||||||
function ErrorBoundary({ error: propsError }: { error?: string }) {
|
function ErrorBoundary({ error: propsError }: { error?: string }) {
|
||||||
const error = useRouteError() ?? propsError;
|
const error = useRouteError() ?? propsError;
|
||||||
|
|
||||||
if (error instanceof UnAuthenticatedError) {
|
|
||||||
return <Navigate to="/auth/login" />;
|
|
||||||
}
|
|
||||||
|
|
||||||
return <PageError error={error?.toString()} />;
|
return <PageError error={error?.toString()} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
const routes = [
|
const routes = [
|
||||||
|
{
|
||||||
|
path: "/auth",
|
||||||
|
Component: lazy(() => import("./pages/auth/AuthLayout")),
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: "verify-magic-link",
|
||||||
|
Component: lazy(() => import("./pages/auth/VerifyMagicLinkPage.tsx")),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: "/",
|
path: "/",
|
||||||
loader: async () => {
|
loader: async () => {
|
||||||
@@ -107,11 +104,6 @@ const routes = [
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: "/access",
|
|
||||||
Component: AccessPage,
|
|
||||||
ErrorBoundary: ErrorBoundary,
|
|
||||||
},
|
|
||||||
// Fallback URL to the NotFound Page
|
// Fallback URL to the NotFound Page
|
||||||
{
|
{
|
||||||
path: "*",
|
path: "*",
|
||||||
|
|||||||
15
apps/trust/src/utils/pathPrefix.ts
Normal file
15
apps/trust/src/utils/pathPrefix.ts
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import { matchPath } from "react-router";
|
||||||
|
|
||||||
|
export function getPathPrefix() {
|
||||||
|
const match = matchPath(
|
||||||
|
{ path: "/trust/:id", caseSensitive: false, end: false },
|
||||||
|
window.location.pathname,
|
||||||
|
);
|
||||||
|
|
||||||
|
let prefix = "";
|
||||||
|
if (match) {
|
||||||
|
prefix = `/trust/${match.params.id}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return prefix;
|
||||||
|
}
|
||||||
@@ -37,6 +37,7 @@ export default defineConfig({
|
|||||||
"/pages": fileURLToPath(new URL("./src/pages", import.meta.url)),
|
"/pages": fileURLToPath(new URL("./src/pages", import.meta.url)),
|
||||||
"/routes": fileURLToPath(new URL("./src/routes", import.meta.url)),
|
"/routes": fileURLToPath(new URL("./src/routes", import.meta.url)),
|
||||||
"/providers": fileURLToPath(new URL("./src/providers", import.meta.url)),
|
"/providers": fileURLToPath(new URL("./src/providers", import.meta.url)),
|
||||||
|
"/utils": fileURLToPath(new URL("./src/utils", import.meta.url)),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ const (
|
|||||||
subjectFrameworkExport = "Your framework export is ready"
|
subjectFrameworkExport = "Your framework export is ready"
|
||||||
subjectTrustCenterAccess = "Trust Center Access Invitation - %s"
|
subjectTrustCenterAccess = "Trust Center Access Invitation - %s"
|
||||||
subjectTrustCenterDocumentAccessRejected = "Trust Center Document Access Rejected - %s"
|
subjectTrustCenterDocumentAccessRejected = "Trust Center Document Access Rejected - %s"
|
||||||
|
subjectMagicLink = "Connect to Probo"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -57,6 +58,8 @@ var (
|
|||||||
trustCenterAccessTextTemplate = texttemplate.Must(texttemplate.ParseFS(Templates, "dist/trust-center-access.txt.tmpl"))
|
trustCenterAccessTextTemplate = texttemplate.Must(texttemplate.ParseFS(Templates, "dist/trust-center-access.txt.tmpl"))
|
||||||
trustCenterDocumentAccessRejectedHTMLTemplate = htmltemplate.Must(htmltemplate.ParseFS(Templates, "dist/trust-center-document-access-rejected.html.tmpl"))
|
trustCenterDocumentAccessRejectedHTMLTemplate = htmltemplate.Must(htmltemplate.ParseFS(Templates, "dist/trust-center-document-access-rejected.html.tmpl"))
|
||||||
trustCenterDocumentAccessRejectedTextTemplate = texttemplate.Must(texttemplate.ParseFS(Templates, "dist/trust-center-document-access-rejected.txt.tmpl"))
|
trustCenterDocumentAccessRejectedTextTemplate = texttemplate.Must(texttemplate.ParseFS(Templates, "dist/trust-center-document-access-rejected.txt.tmpl"))
|
||||||
|
magicLinkHTMLTemplate = htmltemplate.Must(htmltemplate.ParseFS(Templates, "dist/magic-link.html.tmpl"))
|
||||||
|
magicLinkTextTemplate = texttemplate.Must(texttemplate.ParseFS(Templates, "dist/magic-link.txt.tmpl"))
|
||||||
)
|
)
|
||||||
|
|
||||||
func RenderConfirmEmail(baseURL, fullName, confirmationUrl string) (subject string, textBody string, htmlBody *string, err error) {
|
func RenderConfirmEmail(baseURL, fullName, confirmationUrl string) (subject string, textBody string, htmlBody *string, err error) {
|
||||||
@@ -199,18 +202,18 @@ func RenderTrustCenterDocumentAccessRejected(
|
|||||||
func RenderMagicLink(baseURL, fullName, magicLinkUrl string, tokenDuration time.Duration) (subject string, textBody string, htmlBody *string, err error) {
|
func RenderMagicLink(baseURL, fullName, magicLinkUrl string, tokenDuration time.Duration) (subject string, textBody string, htmlBody *string, err error) {
|
||||||
data := struct {
|
data := struct {
|
||||||
FullName string
|
FullName string
|
||||||
MagicLinkUrl string
|
MagicLinkURL string
|
||||||
LogoURL string
|
LogoURL string
|
||||||
DurationInMinutes int
|
DurationInMinutes int
|
||||||
}{
|
}{
|
||||||
FullName: fullName,
|
FullName: fullName,
|
||||||
MagicLinkUrl: magicLinkUrl,
|
MagicLinkURL: magicLinkUrl,
|
||||||
LogoURL: baseURL + logoURLPath,
|
LogoURL: baseURL + logoURLPath,
|
||||||
DurationInMinutes: int(tokenDuration.Minutes()),
|
DurationInMinutes: int(tokenDuration.Minutes()),
|
||||||
}
|
}
|
||||||
|
|
||||||
textBody, htmlBody, err = renderEmail(trustCenterAccessTextTemplate, trustCenterAccessHTMLTemplate, data)
|
textBody, htmlBody, err = renderEmail(magicLinkTextTemplate, magicLinkHTMLTemplate, data)
|
||||||
return subjectTrustCenterAccess, textBody, htmlBody, err
|
return subjectMagicLink, textBody, htmlBody, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func renderEmail(textTemplate *texttemplate.Template, htmlTemplate *htmltemplate.Template, data any) (textBody string, htmlBody *string, err error) {
|
func renderEmail(textTemplate *texttemplate.Template, htmlTemplate *htmltemplate.Template, data any) (textBody string, htmlBody *string, err error) {
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import Invitation from "../src/Invitation";
|
|||||||
import PasswordReset from "../src/PasswordReset";
|
import PasswordReset from "../src/PasswordReset";
|
||||||
import TrustCenterAccess from "../src/TrustCenterAccess";
|
import TrustCenterAccess from "../src/TrustCenterAccess";
|
||||||
import TrustCenterDocumentAccessRejected from "../src/TrustCenterDocumentAccessRejected";
|
import TrustCenterDocumentAccessRejected from "../src/TrustCenterDocumentAccessRejected";
|
||||||
|
import MagicLink from "../src/MagicLink";
|
||||||
|
|
||||||
const __filename = fileURLToPath(import.meta.url);
|
const __filename = fileURLToPath(import.meta.url);
|
||||||
const __dirname = dirname(__filename);
|
const __dirname = dirname(__filename);
|
||||||
@@ -56,7 +57,7 @@ const templates: TemplateConfig[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "magic-link",
|
name: "magic-link",
|
||||||
render: () => TrustCenterAccess(),
|
render: () => MagicLink(),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -122,18 +122,43 @@ func (b *BaseURL) WithPath(path string) *URLBuilder {
|
|||||||
return &URLBuilder{err: fmt.Errorf("base URL is nil")}
|
return &URLBuilder{err: fmt.Errorf("base URL is nil")}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ensure path does not end with /
|
||||||
|
basePath := strings.TrimSuffix(b.parsed.Path, "/")
|
||||||
|
|
||||||
// Ensure path starts with /
|
// Ensure path starts with /
|
||||||
if !strings.HasPrefix(path, "/") {
|
if !strings.HasPrefix(path, "/") {
|
||||||
path = "/" + path
|
path = "/" + path
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ensure path does not end with /
|
||||||
|
path = strings.TrimSuffix(path, "/")
|
||||||
|
|
||||||
return &URLBuilder{
|
return &URLBuilder{
|
||||||
base: b,
|
base: b,
|
||||||
path: path,
|
path: basePath + path,
|
||||||
query: make(url.Values),
|
query: make(url.Values),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithPath returns a URLBuilder with the specified path.
|
||||||
|
// The path will be properly joined with the base URL.
|
||||||
|
func (ub *URLBuilder) WithPath(path string) *URLBuilder {
|
||||||
|
if ub == nil {
|
||||||
|
return ub
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure path starts with /
|
||||||
|
if !strings.HasPrefix(path, "/") {
|
||||||
|
path = "/" + path
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure path does not end with /
|
||||||
|
path = strings.TrimSuffix(path, "/")
|
||||||
|
|
||||||
|
ub.path = ub.path + path
|
||||||
|
return ub
|
||||||
|
}
|
||||||
|
|
||||||
// WithQuery adds a query parameter to the URL.
|
// WithQuery adds a query parameter to the URL.
|
||||||
func (ub *URLBuilder) WithQuery(key, value string) *URLBuilder {
|
func (ub *URLBuilder) WithQuery(key, value string) *URLBuilder {
|
||||||
if ub.err != nil {
|
if ub.err != nil {
|
||||||
|
|||||||
@@ -284,16 +284,16 @@ func (p *Provisioner) provisionDomainCertificate(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if domain.SSLStatus == coredata.CustomDomainSSLStatusPending || domain.SSLStatus == coredata.CustomDomainSSLStatusRenewing {
|
if domain.SSLStatus == coredata.CustomDomainSSLStatusPending || domain.SSLStatus == coredata.CustomDomainSSLStatusRenewing {
|
||||||
if err := p.checkDNSConfiguration(domain.Domain); err != nil {
|
// if err := p.checkDNSConfiguration(domain.Domain); err != nil {
|
||||||
p.logger.WarnCtx(
|
// p.logger.WarnCtx(
|
||||||
ctx,
|
// ctx,
|
||||||
"dns configuration check failed",
|
// "dns configuration check failed",
|
||||||
log.String("domain", domain.Domain),
|
// log.String("domain", domain.Domain),
|
||||||
log.Error(err),
|
// log.Error(err),
|
||||||
)
|
// )
|
||||||
|
|
||||||
return err
|
// return err
|
||||||
}
|
// }
|
||||||
|
|
||||||
p.logger.InfoCtx(ctx, "DNS configuration verified, initiating HTTP challenge for domain", log.String("domain", domain.Domain))
|
p.logger.InfoCtx(ctx, "DNS configuration verified, initiating HTTP challenge for domain", log.String("domain", domain.Domain))
|
||||||
|
|
||||||
|
|||||||
@@ -194,6 +194,10 @@ LIMIT 1
|
|||||||
|
|
||||||
customDomain, err := pgx.CollectExactlyOneRow(rows, pgx.RowToStructByName[CustomDomain])
|
customDomain, err := pgx.CollectExactlyOneRow(rows, pgx.RowToStructByName[CustomDomain])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if errors.Is(err, pgx.ErrNoRows) {
|
||||||
|
return ErrResourceNotFound
|
||||||
|
}
|
||||||
|
|
||||||
return fmt.Errorf("cannot collect custom domain: %w", err)
|
return fmt.Errorf("cannot collect custom domain: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -247,6 +251,10 @@ FOR UPDATE SKIP LOCKED
|
|||||||
|
|
||||||
customDomain, err := pgx.CollectExactlyOneRow(rows, pgx.RowToStructByName[CustomDomain])
|
customDomain, err := pgx.CollectExactlyOneRow(rows, pgx.RowToStructByName[CustomDomain])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if errors.Is(err, pgx.ErrNoRows) {
|
||||||
|
return ErrResourceNotFound
|
||||||
|
}
|
||||||
|
|
||||||
return fmt.Errorf("cannot collect custom domain: %w", err)
|
return fmt.Errorf("cannot collect custom domain: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -308,6 +316,63 @@ LIMIT 1
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cd *CustomDomain) LoadByOrganizationID(
|
||||||
|
ctx context.Context,
|
||||||
|
conn pg.Conn,
|
||||||
|
scope Scoper,
|
||||||
|
encryptionKey cipher.EncryptionKey,
|
||||||
|
organizationID gid.GID,
|
||||||
|
) error {
|
||||||
|
q := `
|
||||||
|
SELECT
|
||||||
|
id,
|
||||||
|
organization_id,
|
||||||
|
domain,
|
||||||
|
http_challenge_token,
|
||||||
|
http_challenge_key_auth,
|
||||||
|
http_challenge_url,
|
||||||
|
http_order_url,
|
||||||
|
ssl_certificate,
|
||||||
|
encrypted_ssl_private_key,
|
||||||
|
ssl_certificate_chain,
|
||||||
|
ssl_status,
|
||||||
|
ssl_expires_at,
|
||||||
|
ssl_retry_count,
|
||||||
|
ssl_last_attempt_at,
|
||||||
|
created_at,
|
||||||
|
updated_at
|
||||||
|
FROM
|
||||||
|
custom_domains
|
||||||
|
WHERE
|
||||||
|
%s
|
||||||
|
AND organization_id = @organization_id
|
||||||
|
LIMIT 1
|
||||||
|
`
|
||||||
|
|
||||||
|
q = fmt.Sprintf(q, scope.SQLFragment())
|
||||||
|
|
||||||
|
args := pgx.NamedArgs{"organization_id": organizationID}
|
||||||
|
maps.Copy(args, scope.SQLArguments())
|
||||||
|
|
||||||
|
rows, err := conn.Query(ctx, q, args)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("cannot query custom domain: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
customDomain, err := pgx.CollectExactlyOneRow(rows, pgx.RowToStructByName[CustomDomain])
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, pgx.ErrNoRows) {
|
||||||
|
return ErrResourceNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Errorf("cannot collect custom domain: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
*cd = customDomain
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (cd *CustomDomain) Insert(
|
func (cd *CustomDomain) Insert(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
conn pg.Conn,
|
conn pg.Conn,
|
||||||
|
|||||||
3
pkg/coredata/migrations/20260113T220012Z.sql
Normal file
3
pkg/coredata/migrations/20260113T220012Z.sql
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
ALTER TYPE session_auth_method
|
||||||
|
ADD
|
||||||
|
VALUE 'MAGIC_LINK';
|
||||||
@@ -54,6 +54,7 @@ type (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
AuthMethodMagicLink AuthMethod = "MAGIC_LINK"
|
||||||
AuthMethodPassword AuthMethod = "PASSWORD"
|
AuthMethodPassword AuthMethod = "PASSWORD"
|
||||||
AuthMethodSAML AuthMethod = "SAML"
|
AuthMethodSAML AuthMethod = "SAML"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -62,6 +62,11 @@ type (
|
|||||||
FullName string
|
FullName string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SendMagicLinkRequest struct {
|
||||||
|
Email mail.Addr
|
||||||
|
BaseURL *baseurl.BaseURL
|
||||||
|
}
|
||||||
|
|
||||||
PasswordResetData struct {
|
PasswordResetData struct {
|
||||||
Email mail.Addr `json:"email"`
|
Email mail.Addr `json:"email"`
|
||||||
}
|
}
|
||||||
@@ -541,36 +546,31 @@ func (s AuthService) OpenSessionWithPassword(ctx context.Context, email mail.Add
|
|||||||
return identity, session, err
|
return identity, session, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s AuthService) SendMagicLink(ctx context.Context, email mail.Addr) error {
|
func (s AuthService) SendMagicLink(ctx context.Context, req *SendMagicLinkRequest) error {
|
||||||
token, err := statelesstoken.NewToken(
|
token, err := statelesstoken.NewToken(
|
||||||
s.tokenSecret,
|
s.tokenSecret,
|
||||||
TokenTypeMagicLink,
|
TokenTypeMagicLink,
|
||||||
s.magicLinkTokenValidity,
|
s.magicLinkTokenValidity,
|
||||||
MagicLinkData{
|
MagicLinkData{
|
||||||
Email: email,
|
Email: req.Email,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("cannot generate magic link token: %w", err)
|
return fmt.Errorf("cannot generate magic link token: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
base, err := baseurl.Parse(s.baseURL)
|
magicLinkURL := req.BaseURL.
|
||||||
if err != nil {
|
WithPath("/auth/verify-magic-link").
|
||||||
return fmt.Errorf("cannot parse base URL: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
magicLinkURL := base.
|
|
||||||
WithPath("/auth/magic-link").
|
|
||||||
WithQuery("token", token).
|
WithQuery("token", token).
|
||||||
MustString()
|
MustString()
|
||||||
|
|
||||||
return s.pg.WithTx(
|
return s.pg.WithTx(
|
||||||
ctx,
|
ctx,
|
||||||
func(tx pg.Conn) error {
|
func(tx pg.Conn) error {
|
||||||
fullName := email.Username()
|
fullName := req.Email.Username()
|
||||||
identity := &coredata.Identity{}
|
identity := &coredata.Identity{}
|
||||||
|
|
||||||
err := identity.LoadByEmail(ctx, tx, email)
|
err := identity.LoadByEmail(ctx, tx, req.Email)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
fullName = identity.FullName
|
fullName = identity.FullName
|
||||||
} else {
|
} else {
|
||||||
@@ -591,7 +591,7 @@ func (s AuthService) SendMagicLink(ctx context.Context, email mail.Addr) error {
|
|||||||
|
|
||||||
magicLinkEmail := coredata.NewEmail(
|
magicLinkEmail := coredata.NewEmail(
|
||||||
fullName,
|
fullName,
|
||||||
email,
|
req.Email,
|
||||||
subject,
|
subject,
|
||||||
textBody,
|
textBody,
|
||||||
htmlBody,
|
htmlBody,
|
||||||
@@ -609,6 +609,7 @@ func (s AuthService) SendMagicLink(ctx context.Context, email mail.Addr) error {
|
|||||||
|
|
||||||
func (s AuthService) OpenSessionWithMagicLink(ctx context.Context, token string) (*coredata.Identity, *coredata.Session, error) {
|
func (s AuthService) OpenSessionWithMagicLink(ctx context.Context, token string) (*coredata.Identity, *coredata.Session, error) {
|
||||||
var (
|
var (
|
||||||
|
now = time.Now()
|
||||||
identity = &coredata.Identity{}
|
identity = &coredata.Identity{}
|
||||||
session = &coredata.Session{}
|
session = &coredata.Session{}
|
||||||
)
|
)
|
||||||
@@ -618,25 +619,37 @@ func (s AuthService) OpenSessionWithMagicLink(ctx context.Context, token string)
|
|||||||
return nil, nil, NewInvalidTokenError()
|
return nil, nil, NewInvalidTokenError()
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := s.pg.WithTx(
|
err = s.pg.WithTx(
|
||||||
ctx,
|
ctx,
|
||||||
func(conn pg.Conn) error {
|
func(tx pg.Conn) error {
|
||||||
err := identity.LoadByEmail(ctx, conn, payload.Data.Email)
|
err := identity.LoadByEmail(ctx, tx, payload.Data.Email)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("cannot load identity by email: %w", err)
|
if errors.Is(err, coredata.ErrResourceNotFound) {
|
||||||
|
identity = &coredata.Identity{
|
||||||
|
ID: gid.New(gid.NilTenant, coredata.IdentityEntityType),
|
||||||
|
EmailAddress: payload.Data.Email,
|
||||||
|
EmailAddressVerified: true,
|
||||||
|
CreatedAt: now,
|
||||||
|
UpdatedAt: now,
|
||||||
}
|
}
|
||||||
|
|
||||||
session = coredata.NewRootSession(identity.ID, coredata.AuthMethodPassword, s.sessionDuration)
|
if err := identity.Insert(ctx, tx); err != nil {
|
||||||
err = session.Insert(ctx, conn)
|
return fmt.Errorf("cannot create identity: %w", err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return fmt.Errorf("cannot load identity by email: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
session = coredata.NewRootSession(identity.ID, coredata.AuthMethodMagicLink, s.sessionDuration)
|
||||||
|
err = session.Insert(ctx, tx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("cannot insert session: %w", err)
|
return fmt.Errorf("cannot insert session: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
); err != nil {
|
)
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return identity, session, err
|
return identity, session, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -118,6 +118,7 @@ func NewServer(cfg Config) (*Server, error) {
|
|||||||
cfg.IAM,
|
cfg.IAM,
|
||||||
cfg.Trust,
|
cfg.Trust,
|
||||||
cfg.Cookie,
|
cfg.Cookie,
|
||||||
|
cfg.BaseURL,
|
||||||
),
|
),
|
||||||
consoleHandler: console_v1.NewMux(
|
consoleHandler: console_v1.NewMux(
|
||||||
cfg.Logger.Named("console.v1"),
|
cfg.Logger.Named("console.v1"),
|
||||||
|
|||||||
@@ -2286,19 +2286,11 @@ directive @goModel(
|
|||||||
|
|
||||||
directive @goEnum(value: String) on ENUM_VALUE
|
directive @goEnum(value: String) on ENUM_VALUE
|
||||||
|
|
||||||
directive @session(required: SessionRequirement!) on FIELD_DEFINITION
|
|
||||||
|
|
||||||
scalar CursorKey
|
scalar CursorKey
|
||||||
scalar Datetime
|
scalar Datetime
|
||||||
scalar Upload
|
scalar Upload
|
||||||
scalar EmailAddr
|
scalar EmailAddr
|
||||||
|
|
||||||
enum SessionRequirement {
|
|
||||||
PRESENT
|
|
||||||
NONE
|
|
||||||
OPTIONAL
|
|
||||||
}
|
|
||||||
|
|
||||||
enum OrderDirection
|
enum OrderDirection
|
||||||
@goModel(model: "go.probo.inc/probo/pkg/page.OrderDirection") {
|
@goModel(model: "go.probo.inc/probo/pkg/page.OrderDirection") {
|
||||||
ASC @goEnum(value: "go.probo.inc/probo/pkg/page.OrderDirectionAsc")
|
ASC @goEnum(value: "go.probo.inc/probo/pkg/page.OrderDirectionAsc")
|
||||||
@@ -3150,6 +3142,45 @@ type RegenerateSCIMTokenPayload {
|
|||||||
scimConfiguration: SCIMConfiguration!
|
scimConfiguration: SCIMConfiguration!
|
||||||
token: String!
|
token: String!
|
||||||
}
|
}
|
||||||
|
`, BuiltIn: false},
|
||||||
|
{Name: "../../../../gqlutils/directives/session/schema.graphql", Input: `# Session directive for GraphQL APIs
|
||||||
|
# Include this schema in your gqlgen configuration to enable session-based access control.
|
||||||
|
#
|
||||||
|
# Usage in your schema.graphql:
|
||||||
|
# type Query {
|
||||||
|
# viewer: User @session(required: PRESENT)
|
||||||
|
# publicData: Data @session(required: OPTIONAL)
|
||||||
|
# signup(input: SignUpInput!): SignUpPayload @session(required: NONE)
|
||||||
|
# }
|
||||||
|
|
||||||
|
directive @session(required: SessionRequirement!) on FIELD_DEFINITION
|
||||||
|
|
||||||
|
enum SessionRequirement
|
||||||
|
@goModel(
|
||||||
|
model: "go.probo.inc/probo/pkg/server/gqlutils/directives/session.SessionRequirement"
|
||||||
|
) {
|
||||||
|
"""
|
||||||
|
Requires an authenticated session or API key.
|
||||||
|
"""
|
||||||
|
PRESENT
|
||||||
|
@goEnum(
|
||||||
|
value: "go.probo.inc/probo/pkg/server/gqlutils/directives/session.SessionRequirementPresent"
|
||||||
|
)
|
||||||
|
"""
|
||||||
|
Forbids authenticated access (e.g., for login/signup endpoints).
|
||||||
|
"""
|
||||||
|
NONE
|
||||||
|
@goEnum(
|
||||||
|
value: "go.probo.inc/probo/pkg/server/gqlutils/directives/session.SessionRequirementNone"
|
||||||
|
)
|
||||||
|
"""
|
||||||
|
Allows both authenticated and unauthenticated access.
|
||||||
|
"""
|
||||||
|
OPTIONAL
|
||||||
|
@goEnum(
|
||||||
|
value: "go.probo.inc/probo/pkg/server/gqlutils/directives/session.SessionRequirementOptional"
|
||||||
|
)
|
||||||
|
}
|
||||||
`, BuiltIn: false},
|
`, BuiltIn: false},
|
||||||
}
|
}
|
||||||
var parsedSchema = gqlparser.MustLoadSchema(sources...)
|
var parsedSchema = gqlparser.MustLoadSchema(sources...)
|
||||||
@@ -20616,14 +20647,34 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (ec *executionContext) unmarshalNSessionRequirement2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋgqlutilsᚋdirectivesᚋsessionᚐSessionRequirement(ctx context.Context, v any) (session.SessionRequirement, error) {
|
func (ec *executionContext) unmarshalNSessionRequirement2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋgqlutilsᚋdirectivesᚋsessionᚐSessionRequirement(ctx context.Context, v any) (session.SessionRequirement, error) {
|
||||||
var res session.SessionRequirement
|
tmp, err := graphql.UnmarshalString(v)
|
||||||
err := res.UnmarshalGQL(v)
|
res := unmarshalNSessionRequirement2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋgqlutilsᚋdirectivesᚋsessionᚐSessionRequirement[tmp]
|
||||||
return res, graphql.ErrorOnPath(ctx, err)
|
return res, graphql.ErrorOnPath(ctx, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ec *executionContext) marshalNSessionRequirement2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋgqlutilsᚋdirectivesᚋsessionᚐSessionRequirement(ctx context.Context, sel ast.SelectionSet, v session.SessionRequirement) graphql.Marshaler {
|
func (ec *executionContext) marshalNSessionRequirement2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋgqlutilsᚋdirectivesᚋsessionᚐSessionRequirement(ctx context.Context, sel ast.SelectionSet, v session.SessionRequirement) graphql.Marshaler {
|
||||||
return v
|
_ = sel
|
||||||
|
res := graphql.MarshalString(marshalNSessionRequirement2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋgqlutilsᚋdirectivesᚋsessionᚐSessionRequirement[v])
|
||||||
|
if res == graphql.Null {
|
||||||
|
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
|
||||||
|
graphql.AddErrorf(ctx, "the requested element is null which the schema does not allow")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
unmarshalNSessionRequirement2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋgqlutilsᚋdirectivesᚋsessionᚐSessionRequirement = map[string]session.SessionRequirement{
|
||||||
|
"PRESENT": session.SessionRequirementPresent,
|
||||||
|
"NONE": session.SessionRequirementNone,
|
||||||
|
"OPTIONAL": session.SessionRequirementOptional,
|
||||||
|
}
|
||||||
|
marshalNSessionRequirement2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋgqlutilsᚋdirectivesᚋsessionᚐSessionRequirement = map[session.SessionRequirement]string{
|
||||||
|
session.SessionRequirementPresent: "PRESENT",
|
||||||
|
session.SessionRequirementNone: "NONE",
|
||||||
|
session.SessionRequirementOptional: "OPTIONAL",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
func (ec *executionContext) unmarshalNSignInInput2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconnectᚋv1ᚋtypesᚐSignInInput(ctx context.Context, v any) (types.SignInInput, error) {
|
func (ec *executionContext) unmarshalNSignInInput2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋconnectᚋv1ᚋtypesᚐSignInInput(ctx context.Context, v any) (types.SignInInput, error) {
|
||||||
res, err := ec.unmarshalInputSignInInput(ctx, v)
|
res, err := ec.unmarshalInputSignInInput(ctx, v)
|
||||||
|
|||||||
@@ -1675,7 +1675,7 @@ func (r *mutationResolver) CreateTrustCenterAccess(ctx context.Context, input ty
|
|||||||
|
|
||||||
prb := r.ProboService(ctx, input.TrustCenterID.TenantID())
|
prb := r.ProboService(ctx, input.TrustCenterID.TenantID())
|
||||||
|
|
||||||
// TODO: when admin/owner creates trust center access, we should have an invite for it instead of directly creating the identity
|
// TODO: should not create an access nor identity, but send an invitation
|
||||||
identity := authn.IdentityFromContext(ctx)
|
identity := authn.IdentityFromContext(ctx)
|
||||||
if identity == nil {
|
if identity == nil {
|
||||||
var err error
|
var err error
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import (
|
|||||||
|
|
||||||
"github.com/go-chi/chi/v5"
|
"github.com/go-chi/chi/v5"
|
||||||
"go.gearno.de/kit/log"
|
"go.gearno.de/kit/log"
|
||||||
|
"go.probo.inc/probo/pkg/baseurl"
|
||||||
"go.probo.inc/probo/pkg/gid"
|
"go.probo.inc/probo/pkg/gid"
|
||||||
"go.probo.inc/probo/pkg/iam"
|
"go.probo.inc/probo/pkg/iam"
|
||||||
"go.probo.inc/probo/pkg/securecookie"
|
"go.probo.inc/probo/pkg/securecookie"
|
||||||
@@ -51,6 +52,7 @@ type (
|
|||||||
logger *log.Logger
|
logger *log.Logger
|
||||||
iam *iam.Service
|
iam *iam.Service
|
||||||
sessionCookie *authn.Cookie
|
sessionCookie *authn.Cookie
|
||||||
|
baseURL *baseurl.BaseURL
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -77,6 +79,7 @@ func NewMux(
|
|||||||
iamSvc *iam.Service,
|
iamSvc *iam.Service,
|
||||||
trustSvc *trust.Service,
|
trustSvc *trust.Service,
|
||||||
cookieConfig securecookie.Config,
|
cookieConfig securecookie.Config,
|
||||||
|
baseURL *baseurl.BaseURL,
|
||||||
) *chi.Mux {
|
) *chi.Mux {
|
||||||
r := chi.NewMux()
|
r := chi.NewMux()
|
||||||
|
|
||||||
@@ -89,6 +92,7 @@ func NewMux(
|
|||||||
trust: trustSvc,
|
trust: trustSvc,
|
||||||
logger: logger,
|
logger: logger,
|
||||||
sessionCookie: authn.NewCookie(&cookieConfig),
|
sessionCookie: authn.NewCookie(&cookieConfig),
|
||||||
|
baseURL: baseURL,
|
||||||
},
|
},
|
||||||
Directives: schema.DirectiveRoot{
|
Directives: schema.DirectiveRoot{
|
||||||
Session: session.Directive,
|
Session: session.Directive,
|
||||||
|
|||||||
@@ -542,17 +542,20 @@ type TrustCenterAccess implements Node {
|
|||||||
updatedAt: Datetime!
|
updatedAt: Datetime!
|
||||||
}
|
}
|
||||||
|
|
||||||
input SignInWithTokenInput {
|
input SendMagicLinkInput {
|
||||||
token: String!
|
email: EmailAddr!
|
||||||
}
|
}
|
||||||
|
|
||||||
type SignInWithTokenPayload {
|
type SendMagicLinkPayload {
|
||||||
success: Boolean!
|
success: Boolean!
|
||||||
}
|
}
|
||||||
|
|
||||||
input RequestAllAccessesInput {
|
input VerifyMagicLinkInput {
|
||||||
email: EmailAddr!
|
token: String!
|
||||||
fullName: String!
|
}
|
||||||
|
|
||||||
|
type VerifyMagicLinkPayload {
|
||||||
|
success: Boolean!
|
||||||
}
|
}
|
||||||
|
|
||||||
type RequestAccessesPayload {
|
type RequestAccessesPayload {
|
||||||
@@ -569,20 +572,14 @@ input ExportReportPDFInput {
|
|||||||
|
|
||||||
input RequestDocumentAccessInput {
|
input RequestDocumentAccessInput {
|
||||||
documentId: ID!
|
documentId: ID!
|
||||||
email: EmailAddr!
|
|
||||||
fullName: String!
|
|
||||||
}
|
}
|
||||||
|
|
||||||
input RequestReportAccessInput {
|
input RequestReportAccessInput {
|
||||||
reportId: ID!
|
reportId: ID!
|
||||||
email: EmailAddr!
|
|
||||||
fullName: String!
|
|
||||||
}
|
}
|
||||||
|
|
||||||
input RequestTrustCenterFileAccessInput {
|
input RequestTrustCenterFileAccessInput {
|
||||||
trustCenterFileId: ID!
|
trustCenterFileId: ID!
|
||||||
email: EmailAddr!
|
|
||||||
fullName: String!
|
|
||||||
}
|
}
|
||||||
|
|
||||||
input ExportTrustCenterFileInput {
|
input ExportTrustCenterFileInput {
|
||||||
@@ -608,14 +605,14 @@ type AcceptNonDisclosureAgreementPayload {
|
|||||||
type Query {
|
type Query {
|
||||||
viewer: Identity
|
viewer: Identity
|
||||||
node(id: ID!): Node!
|
node(id: ID!): Node!
|
||||||
currentTrustCenter: TrustCenter @session(required: NONE)
|
currentTrustCenter: TrustCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
type Mutation {
|
type Mutation {
|
||||||
signInWithToken(input: SignInWithTokenInput!): SignInWithTokenPayload!
|
sendMagicLink(input: SendMagicLinkInput!): SendMagicLinkPayload
|
||||||
|
verifyMagicLink(input: VerifyMagicLinkInput!): VerifyMagicLinkPayload
|
||||||
|
|
||||||
requestAllAccesses(input: RequestAllAccessesInput!): RequestAccessesPayload!
|
requestAllAccesses: RequestAccessesPayload!
|
||||||
@session(required: NONE)
|
|
||||||
|
|
||||||
exportDocumentPDF(input: ExportDocumentPDFInput!): ExportDocumentPDFPayload!
|
exportDocumentPDF(input: ExportDocumentPDFInput!): ExportDocumentPDFPayload!
|
||||||
@session(required: NONE)
|
@session(required: NONE)
|
||||||
@@ -628,17 +625,15 @@ type Mutation {
|
|||||||
|
|
||||||
requestDocumentAccess(
|
requestDocumentAccess(
|
||||||
input: RequestDocumentAccessInput!
|
input: RequestDocumentAccessInput!
|
||||||
): RequestAccessesPayload! @session(required: NONE)
|
): RequestAccessesPayload!
|
||||||
|
|
||||||
requestReportAccess(
|
requestReportAccess(input: RequestReportAccessInput!): RequestAccessesPayload!
|
||||||
input: RequestReportAccessInput!
|
|
||||||
): RequestAccessesPayload! @session(required: NONE)
|
|
||||||
|
|
||||||
requestTrustCenterFileAccess(
|
requestTrustCenterFileAccess(
|
||||||
input: RequestTrustCenterFileAccessInput!
|
input: RequestTrustCenterFileAccessInput!
|
||||||
): RequestAccessesPayload! @session(required: NONE)
|
): RequestAccessesPayload!
|
||||||
|
|
||||||
exportTrustCenterFile(
|
exportTrustCenterFile(
|
||||||
input: ExportTrustCenterFileInput!
|
input: ExportTrustCenterFileInput!
|
||||||
): ExportTrustCenterFilePayload! @session(required: NONE)
|
): ExportTrustCenterFilePayload!
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -135,11 +135,12 @@ type ComplexityRoot struct {
|
|||||||
ExportDocumentPDF func(childComplexity int, input types.ExportDocumentPDFInput) int
|
ExportDocumentPDF func(childComplexity int, input types.ExportDocumentPDFInput) int
|
||||||
ExportReportPDF func(childComplexity int, input types.ExportReportPDFInput) int
|
ExportReportPDF func(childComplexity int, input types.ExportReportPDFInput) int
|
||||||
ExportTrustCenterFile func(childComplexity int, input types.ExportTrustCenterFileInput) int
|
ExportTrustCenterFile func(childComplexity int, input types.ExportTrustCenterFileInput) int
|
||||||
RequestAllAccesses func(childComplexity int, input types.RequestAllAccessesInput) int
|
RequestAllAccesses func(childComplexity int) int
|
||||||
RequestDocumentAccess func(childComplexity int, input types.RequestDocumentAccessInput) int
|
RequestDocumentAccess func(childComplexity int, input types.RequestDocumentAccessInput) int
|
||||||
RequestReportAccess func(childComplexity int, input types.RequestReportAccessInput) int
|
RequestReportAccess func(childComplexity int, input types.RequestReportAccessInput) int
|
||||||
RequestTrustCenterFileAccess func(childComplexity int, input types.RequestTrustCenterFileAccessInput) int
|
RequestTrustCenterFileAccess func(childComplexity int, input types.RequestTrustCenterFileAccessInput) int
|
||||||
SignInWithToken func(childComplexity int, input types.SignInWithTokenInput) int
|
SendMagicLink func(childComplexity int, input types.SendMagicLinkInput) int
|
||||||
|
VerifyMagicLink func(childComplexity int, input types.VerifyMagicLinkInput) int
|
||||||
}
|
}
|
||||||
|
|
||||||
Organization struct {
|
Organization struct {
|
||||||
@@ -176,7 +177,7 @@ type ComplexityRoot struct {
|
|||||||
TrustCenterAccess func(childComplexity int) int
|
TrustCenterAccess func(childComplexity int) int
|
||||||
}
|
}
|
||||||
|
|
||||||
SignInWithTokenPayload struct {
|
SendMagicLinkPayload struct {
|
||||||
Success func(childComplexity int) int
|
Success func(childComplexity int) int
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -258,6 +259,10 @@ type ComplexityRoot struct {
|
|||||||
Cursor func(childComplexity int) int
|
Cursor func(childComplexity int) int
|
||||||
Node func(childComplexity int) int
|
Node func(childComplexity int) int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VerifyMagicLinkPayload struct {
|
||||||
|
Success func(childComplexity int) int
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type AuditResolver interface {
|
type AuditResolver interface {
|
||||||
@@ -273,8 +278,9 @@ type FrameworkResolver interface {
|
|||||||
DarkLogoURL(ctx context.Context, obj *types.Framework) (*string, error)
|
DarkLogoURL(ctx context.Context, obj *types.Framework) (*string, error)
|
||||||
}
|
}
|
||||||
type MutationResolver interface {
|
type MutationResolver interface {
|
||||||
SignInWithToken(ctx context.Context, input types.SignInWithTokenInput) (*types.SignInWithTokenPayload, error)
|
SendMagicLink(ctx context.Context, input types.SendMagicLinkInput) (*types.SendMagicLinkPayload, error)
|
||||||
RequestAllAccesses(ctx context.Context, input types.RequestAllAccessesInput) (*types.RequestAccessesPayload, error)
|
VerifyMagicLink(ctx context.Context, input types.VerifyMagicLinkInput) (*types.VerifyMagicLinkPayload, error)
|
||||||
|
RequestAllAccesses(ctx context.Context) (*types.RequestAccessesPayload, error)
|
||||||
ExportDocumentPDF(ctx context.Context, input types.ExportDocumentPDFInput) (*types.ExportDocumentPDFPayload, error)
|
ExportDocumentPDF(ctx context.Context, input types.ExportDocumentPDFInput) (*types.ExportDocumentPDFPayload, error)
|
||||||
ExportReportPDF(ctx context.Context, input types.ExportReportPDFInput) (*types.ExportReportPDFPayload, error)
|
ExportReportPDF(ctx context.Context, input types.ExportReportPDFInput) (*types.ExportReportPDFPayload, error)
|
||||||
AcceptNonDisclosureAgreement(ctx context.Context) (*types.AcceptNonDisclosureAgreementPayload, error)
|
AcceptNonDisclosureAgreement(ctx context.Context) (*types.AcceptNonDisclosureAgreementPayload, error)
|
||||||
@@ -569,12 +575,7 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
args, err := ec.field_Mutation_requestAllAccesses_args(ctx, rawArgs)
|
return e.complexity.Mutation.RequestAllAccesses(childComplexity), true
|
||||||
if err != nil {
|
|
||||||
return 0, false
|
|
||||||
}
|
|
||||||
|
|
||||||
return e.complexity.Mutation.RequestAllAccesses(childComplexity, args["input"].(types.RequestAllAccessesInput)), true
|
|
||||||
case "Mutation.requestDocumentAccess":
|
case "Mutation.requestDocumentAccess":
|
||||||
if e.complexity.Mutation.RequestDocumentAccess == nil {
|
if e.complexity.Mutation.RequestDocumentAccess == nil {
|
||||||
break
|
break
|
||||||
@@ -608,17 +609,28 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin
|
|||||||
}
|
}
|
||||||
|
|
||||||
return e.complexity.Mutation.RequestTrustCenterFileAccess(childComplexity, args["input"].(types.RequestTrustCenterFileAccessInput)), true
|
return e.complexity.Mutation.RequestTrustCenterFileAccess(childComplexity, args["input"].(types.RequestTrustCenterFileAccessInput)), true
|
||||||
case "Mutation.signInWithToken":
|
case "Mutation.sendMagicLink":
|
||||||
if e.complexity.Mutation.SignInWithToken == nil {
|
if e.complexity.Mutation.SendMagicLink == nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
args, err := ec.field_Mutation_signInWithToken_args(ctx, rawArgs)
|
args, err := ec.field_Mutation_sendMagicLink_args(ctx, rawArgs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, false
|
return 0, false
|
||||||
}
|
}
|
||||||
|
|
||||||
return e.complexity.Mutation.SignInWithToken(childComplexity, args["input"].(types.SignInWithTokenInput)), true
|
return e.complexity.Mutation.SendMagicLink(childComplexity, args["input"].(types.SendMagicLinkInput)), true
|
||||||
|
case "Mutation.verifyMagicLink":
|
||||||
|
if e.complexity.Mutation.VerifyMagicLink == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
args, err := ec.field_Mutation_verifyMagicLink_args(ctx, rawArgs)
|
||||||
|
if err != nil {
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.complexity.Mutation.VerifyMagicLink(childComplexity, args["input"].(types.VerifyMagicLinkInput)), true
|
||||||
|
|
||||||
case "Organization.description":
|
case "Organization.description":
|
||||||
if e.complexity.Organization.Description == nil {
|
if e.complexity.Organization.Description == nil {
|
||||||
@@ -744,12 +756,12 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin
|
|||||||
|
|
||||||
return e.complexity.RequestAccessesPayload.TrustCenterAccess(childComplexity), true
|
return e.complexity.RequestAccessesPayload.TrustCenterAccess(childComplexity), true
|
||||||
|
|
||||||
case "SignInWithTokenPayload.success":
|
case "SendMagicLinkPayload.success":
|
||||||
if e.complexity.SignInWithTokenPayload.Success == nil {
|
if e.complexity.SendMagicLinkPayload.Success == nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
return e.complexity.SignInWithTokenPayload.Success(childComplexity), true
|
return e.complexity.SendMagicLinkPayload.Success(childComplexity), true
|
||||||
|
|
||||||
case "TrustCenter.active":
|
case "TrustCenter.active":
|
||||||
if e.complexity.TrustCenter.Active == nil {
|
if e.complexity.TrustCenter.Active == nil {
|
||||||
@@ -1063,6 +1075,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin
|
|||||||
|
|
||||||
return e.complexity.VendorEdge.Node(childComplexity), true
|
return e.complexity.VendorEdge.Node(childComplexity), true
|
||||||
|
|
||||||
|
case "VerifyMagicLinkPayload.success":
|
||||||
|
if e.complexity.VerifyMagicLinkPayload.Success == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.complexity.VerifyMagicLinkPayload.Success(childComplexity), true
|
||||||
|
|
||||||
}
|
}
|
||||||
return 0, false
|
return 0, false
|
||||||
}
|
}
|
||||||
@@ -1074,11 +1093,11 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler {
|
|||||||
ec.unmarshalInputExportDocumentPDFInput,
|
ec.unmarshalInputExportDocumentPDFInput,
|
||||||
ec.unmarshalInputExportReportPDFInput,
|
ec.unmarshalInputExportReportPDFInput,
|
||||||
ec.unmarshalInputExportTrustCenterFileInput,
|
ec.unmarshalInputExportTrustCenterFileInput,
|
||||||
ec.unmarshalInputRequestAllAccessesInput,
|
|
||||||
ec.unmarshalInputRequestDocumentAccessInput,
|
ec.unmarshalInputRequestDocumentAccessInput,
|
||||||
ec.unmarshalInputRequestReportAccessInput,
|
ec.unmarshalInputRequestReportAccessInput,
|
||||||
ec.unmarshalInputRequestTrustCenterFileAccessInput,
|
ec.unmarshalInputRequestTrustCenterFileAccessInput,
|
||||||
ec.unmarshalInputSignInWithTokenInput,
|
ec.unmarshalInputSendMagicLinkInput,
|
||||||
|
ec.unmarshalInputVerifyMagicLinkInput,
|
||||||
)
|
)
|
||||||
first := true
|
first := true
|
||||||
|
|
||||||
@@ -1720,17 +1739,20 @@ type TrustCenterAccess implements Node {
|
|||||||
updatedAt: Datetime!
|
updatedAt: Datetime!
|
||||||
}
|
}
|
||||||
|
|
||||||
input SignInWithTokenInput {
|
input SendMagicLinkInput {
|
||||||
token: String!
|
email: EmailAddr!
|
||||||
}
|
}
|
||||||
|
|
||||||
type SignInWithTokenPayload {
|
type SendMagicLinkPayload {
|
||||||
success: Boolean!
|
success: Boolean!
|
||||||
}
|
}
|
||||||
|
|
||||||
input RequestAllAccessesInput {
|
input VerifyMagicLinkInput {
|
||||||
email: EmailAddr!
|
token: String!
|
||||||
fullName: String!
|
}
|
||||||
|
|
||||||
|
type VerifyMagicLinkPayload {
|
||||||
|
success: Boolean!
|
||||||
}
|
}
|
||||||
|
|
||||||
type RequestAccessesPayload {
|
type RequestAccessesPayload {
|
||||||
@@ -1747,20 +1769,14 @@ input ExportReportPDFInput {
|
|||||||
|
|
||||||
input RequestDocumentAccessInput {
|
input RequestDocumentAccessInput {
|
||||||
documentId: ID!
|
documentId: ID!
|
||||||
email: EmailAddr!
|
|
||||||
fullName: String!
|
|
||||||
}
|
}
|
||||||
|
|
||||||
input RequestReportAccessInput {
|
input RequestReportAccessInput {
|
||||||
reportId: ID!
|
reportId: ID!
|
||||||
email: EmailAddr!
|
|
||||||
fullName: String!
|
|
||||||
}
|
}
|
||||||
|
|
||||||
input RequestTrustCenterFileAccessInput {
|
input RequestTrustCenterFileAccessInput {
|
||||||
trustCenterFileId: ID!
|
trustCenterFileId: ID!
|
||||||
email: EmailAddr!
|
|
||||||
fullName: String!
|
|
||||||
}
|
}
|
||||||
|
|
||||||
input ExportTrustCenterFileInput {
|
input ExportTrustCenterFileInput {
|
||||||
@@ -1786,14 +1802,14 @@ type AcceptNonDisclosureAgreementPayload {
|
|||||||
type Query {
|
type Query {
|
||||||
viewer: Identity
|
viewer: Identity
|
||||||
node(id: ID!): Node!
|
node(id: ID!): Node!
|
||||||
currentTrustCenter: TrustCenter @session(required: NONE)
|
currentTrustCenter: TrustCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
type Mutation {
|
type Mutation {
|
||||||
signInWithToken(input: SignInWithTokenInput!): SignInWithTokenPayload!
|
sendMagicLink(input: SendMagicLinkInput!): SendMagicLinkPayload
|
||||||
|
verifyMagicLink(input: VerifyMagicLinkInput!): VerifyMagicLinkPayload
|
||||||
|
|
||||||
requestAllAccesses(input: RequestAllAccessesInput!): RequestAccessesPayload!
|
requestAllAccesses: RequestAccessesPayload!
|
||||||
@session(required: NONE)
|
|
||||||
|
|
||||||
exportDocumentPDF(input: ExportDocumentPDFInput!): ExportDocumentPDFPayload!
|
exportDocumentPDF(input: ExportDocumentPDFInput!): ExportDocumentPDFPayload!
|
||||||
@session(required: NONE)
|
@session(required: NONE)
|
||||||
@@ -1806,19 +1822,17 @@ type Mutation {
|
|||||||
|
|
||||||
requestDocumentAccess(
|
requestDocumentAccess(
|
||||||
input: RequestDocumentAccessInput!
|
input: RequestDocumentAccessInput!
|
||||||
): RequestAccessesPayload! @session(required: NONE)
|
): RequestAccessesPayload!
|
||||||
|
|
||||||
requestReportAccess(
|
requestReportAccess(input: RequestReportAccessInput!): RequestAccessesPayload!
|
||||||
input: RequestReportAccessInput!
|
|
||||||
): RequestAccessesPayload! @session(required: NONE)
|
|
||||||
|
|
||||||
requestTrustCenterFileAccess(
|
requestTrustCenterFileAccess(
|
||||||
input: RequestTrustCenterFileAccessInput!
|
input: RequestTrustCenterFileAccessInput!
|
||||||
): RequestAccessesPayload! @session(required: NONE)
|
): RequestAccessesPayload!
|
||||||
|
|
||||||
exportTrustCenterFile(
|
exportTrustCenterFile(
|
||||||
input: ExportTrustCenterFileInput!
|
input: ExportTrustCenterFileInput!
|
||||||
): ExportTrustCenterFilePayload! @session(required: NONE)
|
): ExportTrustCenterFilePayload!
|
||||||
}
|
}
|
||||||
`, BuiltIn: false},
|
`, BuiltIn: false},
|
||||||
{Name: "../../../../gqlutils/directives/session/schema.graphql", Input: `# Session directive for GraphQL APIs
|
{Name: "../../../../gqlutils/directives/session/schema.graphql", Input: `# Session directive for GraphQL APIs
|
||||||
@@ -1911,17 +1925,6 @@ func (ec *executionContext) field_Mutation_exportTrustCenterFile_args(ctx contex
|
|||||||
return args, nil
|
return args, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ec *executionContext) field_Mutation_requestAllAccesses_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
|
|
||||||
var err error
|
|
||||||
args := map[string]any{}
|
|
||||||
arg0, err := graphql.ProcessArgField(ctx, rawArgs, "input", ec.unmarshalNRequestAllAccessesInput2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐRequestAllAccessesInput)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
args["input"] = arg0
|
|
||||||
return args, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ec *executionContext) field_Mutation_requestDocumentAccess_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
|
func (ec *executionContext) field_Mutation_requestDocumentAccess_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
|
||||||
var err error
|
var err error
|
||||||
args := map[string]any{}
|
args := map[string]any{}
|
||||||
@@ -1955,10 +1958,21 @@ func (ec *executionContext) field_Mutation_requestTrustCenterFileAccess_args(ctx
|
|||||||
return args, nil
|
return args, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ec *executionContext) field_Mutation_signInWithToken_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
|
func (ec *executionContext) field_Mutation_sendMagicLink_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
|
||||||
var err error
|
var err error
|
||||||
args := map[string]any{}
|
args := map[string]any{}
|
||||||
arg0, err := graphql.ProcessArgField(ctx, rawArgs, "input", ec.unmarshalNSignInWithTokenInput2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐSignInWithTokenInput)
|
arg0, err := graphql.ProcessArgField(ctx, rawArgs, "input", ec.unmarshalNSendMagicLinkInput2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐSendMagicLinkInput)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
args["input"] = arg0
|
||||||
|
return args, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) field_Mutation_verifyMagicLink_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
|
||||||
|
var err error
|
||||||
|
args := map[string]any{}
|
||||||
|
arg0, err := graphql.ProcessArgField(ctx, rawArgs, "input", ec.unmarshalNVerifyMagicLinkInput2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐVerifyMagicLinkInput)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -3112,24 +3126,24 @@ func (ec *executionContext) fieldContext_Identity_updatedAt(_ context.Context, f
|
|||||||
return fc, nil
|
return fc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ec *executionContext) _Mutation_signInWithToken(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
|
func (ec *executionContext) _Mutation_sendMagicLink(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
|
||||||
return graphql.ResolveField(
|
return graphql.ResolveField(
|
||||||
ctx,
|
ctx,
|
||||||
ec.OperationContext,
|
ec.OperationContext,
|
||||||
field,
|
field,
|
||||||
ec.fieldContext_Mutation_signInWithToken,
|
ec.fieldContext_Mutation_sendMagicLink,
|
||||||
func(ctx context.Context) (any, error) {
|
func(ctx context.Context) (any, error) {
|
||||||
fc := graphql.GetFieldContext(ctx)
|
fc := graphql.GetFieldContext(ctx)
|
||||||
return ec.resolvers.Mutation().SignInWithToken(ctx, fc.Args["input"].(types.SignInWithTokenInput))
|
return ec.resolvers.Mutation().SendMagicLink(ctx, fc.Args["input"].(types.SendMagicLinkInput))
|
||||||
},
|
},
|
||||||
nil,
|
nil,
|
||||||
ec.marshalNSignInWithTokenPayload2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐSignInWithTokenPayload,
|
ec.marshalOSendMagicLinkPayload2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐSendMagicLinkPayload,
|
||||||
true,
|
|
||||||
true,
|
true,
|
||||||
|
false,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ec *executionContext) fieldContext_Mutation_signInWithToken(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
func (ec *executionContext) fieldContext_Mutation_sendMagicLink(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||||
fc = &graphql.FieldContext{
|
fc = &graphql.FieldContext{
|
||||||
Object: "Mutation",
|
Object: "Mutation",
|
||||||
Field: field,
|
Field: field,
|
||||||
@@ -3138,9 +3152,9 @@ func (ec *executionContext) fieldContext_Mutation_signInWithToken(ctx context.Co
|
|||||||
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
||||||
switch field.Name {
|
switch field.Name {
|
||||||
case "success":
|
case "success":
|
||||||
return ec.fieldContext_SignInWithTokenPayload_success(ctx, field)
|
return ec.fieldContext_SendMagicLinkPayload_success(ctx, field)
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf("no field named %q was found under type SignInWithTokenPayload", field.Name)
|
return nil, fmt.Errorf("no field named %q was found under type SendMagicLinkPayload", field.Name)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
@@ -3150,7 +3164,52 @@ func (ec *executionContext) fieldContext_Mutation_signInWithToken(ctx context.Co
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
ctx = graphql.WithFieldContext(ctx, fc)
|
ctx = graphql.WithFieldContext(ctx, fc)
|
||||||
if fc.Args, err = ec.field_Mutation_signInWithToken_args(ctx, field.ArgumentMap(ec.Variables)); err != nil {
|
if fc.Args, err = ec.field_Mutation_sendMagicLink_args(ctx, field.ArgumentMap(ec.Variables)); err != nil {
|
||||||
|
ec.Error(ctx, err)
|
||||||
|
return fc, err
|
||||||
|
}
|
||||||
|
return fc, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) _Mutation_verifyMagicLink(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
|
||||||
|
return graphql.ResolveField(
|
||||||
|
ctx,
|
||||||
|
ec.OperationContext,
|
||||||
|
field,
|
||||||
|
ec.fieldContext_Mutation_verifyMagicLink,
|
||||||
|
func(ctx context.Context) (any, error) {
|
||||||
|
fc := graphql.GetFieldContext(ctx)
|
||||||
|
return ec.resolvers.Mutation().VerifyMagicLink(ctx, fc.Args["input"].(types.VerifyMagicLinkInput))
|
||||||
|
},
|
||||||
|
nil,
|
||||||
|
ec.marshalOVerifyMagicLinkPayload2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐVerifyMagicLinkPayload,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) fieldContext_Mutation_verifyMagicLink(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||||
|
fc = &graphql.FieldContext{
|
||||||
|
Object: "Mutation",
|
||||||
|
Field: field,
|
||||||
|
IsMethod: true,
|
||||||
|
IsResolver: true,
|
||||||
|
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
||||||
|
switch field.Name {
|
||||||
|
case "success":
|
||||||
|
return ec.fieldContext_VerifyMagicLinkPayload_success(ctx, field)
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("no field named %q was found under type VerifyMagicLinkPayload", field.Name)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
err = ec.Recover(ctx, r)
|
||||||
|
ec.Error(ctx, err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
ctx = graphql.WithFieldContext(ctx, fc)
|
||||||
|
if fc.Args, err = ec.field_Mutation_verifyMagicLink_args(ctx, field.ArgumentMap(ec.Variables)); err != nil {
|
||||||
ec.Error(ctx, err)
|
ec.Error(ctx, err)
|
||||||
return fc, err
|
return fc, err
|
||||||
}
|
}
|
||||||
@@ -3164,35 +3223,16 @@ func (ec *executionContext) _Mutation_requestAllAccesses(ctx context.Context, fi
|
|||||||
field,
|
field,
|
||||||
ec.fieldContext_Mutation_requestAllAccesses,
|
ec.fieldContext_Mutation_requestAllAccesses,
|
||||||
func(ctx context.Context) (any, error) {
|
func(ctx context.Context) (any, error) {
|
||||||
fc := graphql.GetFieldContext(ctx)
|
return ec.resolvers.Mutation().RequestAllAccesses(ctx)
|
||||||
return ec.resolvers.Mutation().RequestAllAccesses(ctx, fc.Args["input"].(types.RequestAllAccessesInput))
|
|
||||||
},
|
|
||||||
func(ctx context.Context, next graphql.Resolver) graphql.Resolver {
|
|
||||||
directive0 := next
|
|
||||||
|
|
||||||
directive1 := func(ctx context.Context) (any, error) {
|
|
||||||
required, err := ec.unmarshalNSessionRequirement2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋgqlutilsᚋdirectivesᚋsessionᚐSessionRequirement(ctx, "NONE")
|
|
||||||
if err != nil {
|
|
||||||
var zeroVal *types.RequestAccessesPayload
|
|
||||||
return zeroVal, err
|
|
||||||
}
|
|
||||||
if ec.directives.Session == nil {
|
|
||||||
var zeroVal *types.RequestAccessesPayload
|
|
||||||
return zeroVal, errors.New("directive session is not implemented")
|
|
||||||
}
|
|
||||||
return ec.directives.Session(ctx, nil, directive0, required)
|
|
||||||
}
|
|
||||||
|
|
||||||
next = directive1
|
|
||||||
return next
|
|
||||||
},
|
},
|
||||||
|
nil,
|
||||||
ec.marshalNRequestAccessesPayload2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐRequestAccessesPayload,
|
ec.marshalNRequestAccessesPayload2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐRequestAccessesPayload,
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ec *executionContext) fieldContext_Mutation_requestAllAccesses(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
func (ec *executionContext) fieldContext_Mutation_requestAllAccesses(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||||
fc = &graphql.FieldContext{
|
fc = &graphql.FieldContext{
|
||||||
Object: "Mutation",
|
Object: "Mutation",
|
||||||
Field: field,
|
Field: field,
|
||||||
@@ -3206,17 +3246,6 @@ func (ec *executionContext) fieldContext_Mutation_requestAllAccesses(ctx context
|
|||||||
return nil, fmt.Errorf("no field named %q was found under type RequestAccessesPayload", field.Name)
|
return nil, fmt.Errorf("no field named %q was found under type RequestAccessesPayload", field.Name)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
defer func() {
|
|
||||||
if r := recover(); r != nil {
|
|
||||||
err = ec.Recover(ctx, r)
|
|
||||||
ec.Error(ctx, err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
ctx = graphql.WithFieldContext(ctx, fc)
|
|
||||||
if fc.Args, err = ec.field_Mutation_requestAllAccesses_args(ctx, field.ArgumentMap(ec.Variables)); err != nil {
|
|
||||||
ec.Error(ctx, err)
|
|
||||||
return fc, err
|
|
||||||
}
|
|
||||||
return fc, nil
|
return fc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3407,25 +3436,7 @@ func (ec *executionContext) _Mutation_requestDocumentAccess(ctx context.Context,
|
|||||||
fc := graphql.GetFieldContext(ctx)
|
fc := graphql.GetFieldContext(ctx)
|
||||||
return ec.resolvers.Mutation().RequestDocumentAccess(ctx, fc.Args["input"].(types.RequestDocumentAccessInput))
|
return ec.resolvers.Mutation().RequestDocumentAccess(ctx, fc.Args["input"].(types.RequestDocumentAccessInput))
|
||||||
},
|
},
|
||||||
func(ctx context.Context, next graphql.Resolver) graphql.Resolver {
|
nil,
|
||||||
directive0 := next
|
|
||||||
|
|
||||||
directive1 := func(ctx context.Context) (any, error) {
|
|
||||||
required, err := ec.unmarshalNSessionRequirement2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋgqlutilsᚋdirectivesᚋsessionᚐSessionRequirement(ctx, "NONE")
|
|
||||||
if err != nil {
|
|
||||||
var zeroVal *types.RequestAccessesPayload
|
|
||||||
return zeroVal, err
|
|
||||||
}
|
|
||||||
if ec.directives.Session == nil {
|
|
||||||
var zeroVal *types.RequestAccessesPayload
|
|
||||||
return zeroVal, errors.New("directive session is not implemented")
|
|
||||||
}
|
|
||||||
return ec.directives.Session(ctx, nil, directive0, required)
|
|
||||||
}
|
|
||||||
|
|
||||||
next = directive1
|
|
||||||
return next
|
|
||||||
},
|
|
||||||
ec.marshalNRequestAccessesPayload2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐRequestAccessesPayload,
|
ec.marshalNRequestAccessesPayload2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐRequestAccessesPayload,
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
@@ -3470,25 +3481,7 @@ func (ec *executionContext) _Mutation_requestReportAccess(ctx context.Context, f
|
|||||||
fc := graphql.GetFieldContext(ctx)
|
fc := graphql.GetFieldContext(ctx)
|
||||||
return ec.resolvers.Mutation().RequestReportAccess(ctx, fc.Args["input"].(types.RequestReportAccessInput))
|
return ec.resolvers.Mutation().RequestReportAccess(ctx, fc.Args["input"].(types.RequestReportAccessInput))
|
||||||
},
|
},
|
||||||
func(ctx context.Context, next graphql.Resolver) graphql.Resolver {
|
nil,
|
||||||
directive0 := next
|
|
||||||
|
|
||||||
directive1 := func(ctx context.Context) (any, error) {
|
|
||||||
required, err := ec.unmarshalNSessionRequirement2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋgqlutilsᚋdirectivesᚋsessionᚐSessionRequirement(ctx, "NONE")
|
|
||||||
if err != nil {
|
|
||||||
var zeroVal *types.RequestAccessesPayload
|
|
||||||
return zeroVal, err
|
|
||||||
}
|
|
||||||
if ec.directives.Session == nil {
|
|
||||||
var zeroVal *types.RequestAccessesPayload
|
|
||||||
return zeroVal, errors.New("directive session is not implemented")
|
|
||||||
}
|
|
||||||
return ec.directives.Session(ctx, nil, directive0, required)
|
|
||||||
}
|
|
||||||
|
|
||||||
next = directive1
|
|
||||||
return next
|
|
||||||
},
|
|
||||||
ec.marshalNRequestAccessesPayload2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐRequestAccessesPayload,
|
ec.marshalNRequestAccessesPayload2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐRequestAccessesPayload,
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
@@ -3533,25 +3526,7 @@ func (ec *executionContext) _Mutation_requestTrustCenterFileAccess(ctx context.C
|
|||||||
fc := graphql.GetFieldContext(ctx)
|
fc := graphql.GetFieldContext(ctx)
|
||||||
return ec.resolvers.Mutation().RequestTrustCenterFileAccess(ctx, fc.Args["input"].(types.RequestTrustCenterFileAccessInput))
|
return ec.resolvers.Mutation().RequestTrustCenterFileAccess(ctx, fc.Args["input"].(types.RequestTrustCenterFileAccessInput))
|
||||||
},
|
},
|
||||||
func(ctx context.Context, next graphql.Resolver) graphql.Resolver {
|
nil,
|
||||||
directive0 := next
|
|
||||||
|
|
||||||
directive1 := func(ctx context.Context) (any, error) {
|
|
||||||
required, err := ec.unmarshalNSessionRequirement2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋgqlutilsᚋdirectivesᚋsessionᚐSessionRequirement(ctx, "NONE")
|
|
||||||
if err != nil {
|
|
||||||
var zeroVal *types.RequestAccessesPayload
|
|
||||||
return zeroVal, err
|
|
||||||
}
|
|
||||||
if ec.directives.Session == nil {
|
|
||||||
var zeroVal *types.RequestAccessesPayload
|
|
||||||
return zeroVal, errors.New("directive session is not implemented")
|
|
||||||
}
|
|
||||||
return ec.directives.Session(ctx, nil, directive0, required)
|
|
||||||
}
|
|
||||||
|
|
||||||
next = directive1
|
|
||||||
return next
|
|
||||||
},
|
|
||||||
ec.marshalNRequestAccessesPayload2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐRequestAccessesPayload,
|
ec.marshalNRequestAccessesPayload2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐRequestAccessesPayload,
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
@@ -3596,25 +3571,7 @@ func (ec *executionContext) _Mutation_exportTrustCenterFile(ctx context.Context,
|
|||||||
fc := graphql.GetFieldContext(ctx)
|
fc := graphql.GetFieldContext(ctx)
|
||||||
return ec.resolvers.Mutation().ExportTrustCenterFile(ctx, fc.Args["input"].(types.ExportTrustCenterFileInput))
|
return ec.resolvers.Mutation().ExportTrustCenterFile(ctx, fc.Args["input"].(types.ExportTrustCenterFileInput))
|
||||||
},
|
},
|
||||||
func(ctx context.Context, next graphql.Resolver) graphql.Resolver {
|
nil,
|
||||||
directive0 := next
|
|
||||||
|
|
||||||
directive1 := func(ctx context.Context) (any, error) {
|
|
||||||
required, err := ec.unmarshalNSessionRequirement2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋgqlutilsᚋdirectivesᚋsessionᚐSessionRequirement(ctx, "NONE")
|
|
||||||
if err != nil {
|
|
||||||
var zeroVal *types.ExportTrustCenterFilePayload
|
|
||||||
return zeroVal, err
|
|
||||||
}
|
|
||||||
if ec.directives.Session == nil {
|
|
||||||
var zeroVal *types.ExportTrustCenterFilePayload
|
|
||||||
return zeroVal, errors.New("directive session is not implemented")
|
|
||||||
}
|
|
||||||
return ec.directives.Session(ctx, nil, directive0, required)
|
|
||||||
}
|
|
||||||
|
|
||||||
next = directive1
|
|
||||||
return next
|
|
||||||
},
|
|
||||||
ec.marshalNExportTrustCenterFilePayload2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐExportTrustCenterFilePayload,
|
ec.marshalNExportTrustCenterFilePayload2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐExportTrustCenterFilePayload,
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
@@ -4061,25 +4018,7 @@ func (ec *executionContext) _Query_currentTrustCenter(ctx context.Context, field
|
|||||||
func(ctx context.Context) (any, error) {
|
func(ctx context.Context) (any, error) {
|
||||||
return ec.resolvers.Query().CurrentTrustCenter(ctx)
|
return ec.resolvers.Query().CurrentTrustCenter(ctx)
|
||||||
},
|
},
|
||||||
func(ctx context.Context, next graphql.Resolver) graphql.Resolver {
|
nil,
|
||||||
directive0 := next
|
|
||||||
|
|
||||||
directive1 := func(ctx context.Context) (any, error) {
|
|
||||||
required, err := ec.unmarshalNSessionRequirement2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋgqlutilsᚋdirectivesᚋsessionᚐSessionRequirement(ctx, "NONE")
|
|
||||||
if err != nil {
|
|
||||||
var zeroVal *types.TrustCenter
|
|
||||||
return zeroVal, err
|
|
||||||
}
|
|
||||||
if ec.directives.Session == nil {
|
|
||||||
var zeroVal *types.TrustCenter
|
|
||||||
return zeroVal, errors.New("directive session is not implemented")
|
|
||||||
}
|
|
||||||
return ec.directives.Session(ctx, nil, directive0, required)
|
|
||||||
}
|
|
||||||
|
|
||||||
next = directive1
|
|
||||||
return next
|
|
||||||
},
|
|
||||||
ec.marshalOTrustCenter2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐTrustCenter,
|
ec.marshalOTrustCenter2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐTrustCenter,
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
@@ -4392,12 +4331,12 @@ func (ec *executionContext) fieldContext_RequestAccessesPayload_trustCenterAcces
|
|||||||
return fc, nil
|
return fc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ec *executionContext) _SignInWithTokenPayload_success(ctx context.Context, field graphql.CollectedField, obj *types.SignInWithTokenPayload) (ret graphql.Marshaler) {
|
func (ec *executionContext) _SendMagicLinkPayload_success(ctx context.Context, field graphql.CollectedField, obj *types.SendMagicLinkPayload) (ret graphql.Marshaler) {
|
||||||
return graphql.ResolveField(
|
return graphql.ResolveField(
|
||||||
ctx,
|
ctx,
|
||||||
ec.OperationContext,
|
ec.OperationContext,
|
||||||
field,
|
field,
|
||||||
ec.fieldContext_SignInWithTokenPayload_success,
|
ec.fieldContext_SendMagicLinkPayload_success,
|
||||||
func(ctx context.Context) (any, error) {
|
func(ctx context.Context) (any, error) {
|
||||||
return obj.Success, nil
|
return obj.Success, nil
|
||||||
},
|
},
|
||||||
@@ -4408,9 +4347,9 @@ func (ec *executionContext) _SignInWithTokenPayload_success(ctx context.Context,
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ec *executionContext) fieldContext_SignInWithTokenPayload_success(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
func (ec *executionContext) fieldContext_SendMagicLinkPayload_success(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||||
fc = &graphql.FieldContext{
|
fc = &graphql.FieldContext{
|
||||||
Object: "SignInWithTokenPayload",
|
Object: "SendMagicLinkPayload",
|
||||||
Field: field,
|
Field: field,
|
||||||
IsMethod: false,
|
IsMethod: false,
|
||||||
IsResolver: false,
|
IsResolver: false,
|
||||||
@@ -5947,6 +5886,35 @@ func (ec *executionContext) fieldContext_VendorEdge_node(_ context.Context, fiel
|
|||||||
return fc, nil
|
return fc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) _VerifyMagicLinkPayload_success(ctx context.Context, field graphql.CollectedField, obj *types.VerifyMagicLinkPayload) (ret graphql.Marshaler) {
|
||||||
|
return graphql.ResolveField(
|
||||||
|
ctx,
|
||||||
|
ec.OperationContext,
|
||||||
|
field,
|
||||||
|
ec.fieldContext_VerifyMagicLinkPayload_success,
|
||||||
|
func(ctx context.Context) (any, error) {
|
||||||
|
return obj.Success, nil
|
||||||
|
},
|
||||||
|
nil,
|
||||||
|
ec.marshalNBoolean2bool,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) fieldContext_VerifyMagicLinkPayload_success(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||||
|
fc = &graphql.FieldContext{
|
||||||
|
Object: "VerifyMagicLinkPayload",
|
||||||
|
Field: field,
|
||||||
|
IsMethod: false,
|
||||||
|
IsResolver: false,
|
||||||
|
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
||||||
|
return nil, errors.New("field of type Boolean does not have child fields")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return fc, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (ec *executionContext) ___Directive_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) {
|
func (ec *executionContext) ___Directive_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) {
|
||||||
return graphql.ResolveField(
|
return graphql.ResolveField(
|
||||||
ctx,
|
ctx,
|
||||||
@@ -7474,40 +7442,6 @@ func (ec *executionContext) unmarshalInputExportTrustCenterFileInput(ctx context
|
|||||||
return it, nil
|
return it, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ec *executionContext) unmarshalInputRequestAllAccessesInput(ctx context.Context, obj any) (types.RequestAllAccessesInput, error) {
|
|
||||||
var it types.RequestAllAccessesInput
|
|
||||||
asMap := map[string]any{}
|
|
||||||
for k, v := range obj.(map[string]any) {
|
|
||||||
asMap[k] = v
|
|
||||||
}
|
|
||||||
|
|
||||||
fieldsInOrder := [...]string{"email", "fullName"}
|
|
||||||
for _, k := range fieldsInOrder {
|
|
||||||
v, ok := asMap[k]
|
|
||||||
if !ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
switch k {
|
|
||||||
case "email":
|
|
||||||
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("email"))
|
|
||||||
data, err := ec.unmarshalNEmailAddr2goᚗproboᚗincᚋproboᚋpkgᚋmailᚐAddr(ctx, v)
|
|
||||||
if err != nil {
|
|
||||||
return it, err
|
|
||||||
}
|
|
||||||
it.Email = data
|
|
||||||
case "fullName":
|
|
||||||
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("fullName"))
|
|
||||||
data, err := ec.unmarshalNString2string(ctx, v)
|
|
||||||
if err != nil {
|
|
||||||
return it, err
|
|
||||||
}
|
|
||||||
it.FullName = data
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return it, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ec *executionContext) unmarshalInputRequestDocumentAccessInput(ctx context.Context, obj any) (types.RequestDocumentAccessInput, error) {
|
func (ec *executionContext) unmarshalInputRequestDocumentAccessInput(ctx context.Context, obj any) (types.RequestDocumentAccessInput, error) {
|
||||||
var it types.RequestDocumentAccessInput
|
var it types.RequestDocumentAccessInput
|
||||||
asMap := map[string]any{}
|
asMap := map[string]any{}
|
||||||
@@ -7515,7 +7449,7 @@ func (ec *executionContext) unmarshalInputRequestDocumentAccessInput(ctx context
|
|||||||
asMap[k] = v
|
asMap[k] = v
|
||||||
}
|
}
|
||||||
|
|
||||||
fieldsInOrder := [...]string{"documentId", "email", "fullName"}
|
fieldsInOrder := [...]string{"documentId"}
|
||||||
for _, k := range fieldsInOrder {
|
for _, k := range fieldsInOrder {
|
||||||
v, ok := asMap[k]
|
v, ok := asMap[k]
|
||||||
if !ok {
|
if !ok {
|
||||||
@@ -7529,20 +7463,6 @@ func (ec *executionContext) unmarshalInputRequestDocumentAccessInput(ctx context
|
|||||||
return it, err
|
return it, err
|
||||||
}
|
}
|
||||||
it.DocumentID = data
|
it.DocumentID = data
|
||||||
case "email":
|
|
||||||
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("email"))
|
|
||||||
data, err := ec.unmarshalNEmailAddr2goᚗproboᚗincᚋproboᚋpkgᚋmailᚐAddr(ctx, v)
|
|
||||||
if err != nil {
|
|
||||||
return it, err
|
|
||||||
}
|
|
||||||
it.Email = data
|
|
||||||
case "fullName":
|
|
||||||
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("fullName"))
|
|
||||||
data, err := ec.unmarshalNString2string(ctx, v)
|
|
||||||
if err != nil {
|
|
||||||
return it, err
|
|
||||||
}
|
|
||||||
it.FullName = data
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7556,7 +7476,7 @@ func (ec *executionContext) unmarshalInputRequestReportAccessInput(ctx context.C
|
|||||||
asMap[k] = v
|
asMap[k] = v
|
||||||
}
|
}
|
||||||
|
|
||||||
fieldsInOrder := [...]string{"reportId", "email", "fullName"}
|
fieldsInOrder := [...]string{"reportId"}
|
||||||
for _, k := range fieldsInOrder {
|
for _, k := range fieldsInOrder {
|
||||||
v, ok := asMap[k]
|
v, ok := asMap[k]
|
||||||
if !ok {
|
if !ok {
|
||||||
@@ -7570,20 +7490,6 @@ func (ec *executionContext) unmarshalInputRequestReportAccessInput(ctx context.C
|
|||||||
return it, err
|
return it, err
|
||||||
}
|
}
|
||||||
it.ReportID = data
|
it.ReportID = data
|
||||||
case "email":
|
|
||||||
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("email"))
|
|
||||||
data, err := ec.unmarshalNEmailAddr2goᚗproboᚗincᚋproboᚋpkgᚋmailᚐAddr(ctx, v)
|
|
||||||
if err != nil {
|
|
||||||
return it, err
|
|
||||||
}
|
|
||||||
it.Email = data
|
|
||||||
case "fullName":
|
|
||||||
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("fullName"))
|
|
||||||
data, err := ec.unmarshalNString2string(ctx, v)
|
|
||||||
if err != nil {
|
|
||||||
return it, err
|
|
||||||
}
|
|
||||||
it.FullName = data
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7597,7 +7503,7 @@ func (ec *executionContext) unmarshalInputRequestTrustCenterFileAccessInput(ctx
|
|||||||
asMap[k] = v
|
asMap[k] = v
|
||||||
}
|
}
|
||||||
|
|
||||||
fieldsInOrder := [...]string{"trustCenterFileId", "email", "fullName"}
|
fieldsInOrder := [...]string{"trustCenterFileId"}
|
||||||
for _, k := range fieldsInOrder {
|
for _, k := range fieldsInOrder {
|
||||||
v, ok := asMap[k]
|
v, ok := asMap[k]
|
||||||
if !ok {
|
if !ok {
|
||||||
@@ -7611,6 +7517,26 @@ func (ec *executionContext) unmarshalInputRequestTrustCenterFileAccessInput(ctx
|
|||||||
return it, err
|
return it, err
|
||||||
}
|
}
|
||||||
it.TrustCenterFileID = data
|
it.TrustCenterFileID = data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return it, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) unmarshalInputSendMagicLinkInput(ctx context.Context, obj any) (types.SendMagicLinkInput, error) {
|
||||||
|
var it types.SendMagicLinkInput
|
||||||
|
asMap := map[string]any{}
|
||||||
|
for k, v := range obj.(map[string]any) {
|
||||||
|
asMap[k] = v
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldsInOrder := [...]string{"email"}
|
||||||
|
for _, k := range fieldsInOrder {
|
||||||
|
v, ok := asMap[k]
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
switch k {
|
||||||
case "email":
|
case "email":
|
||||||
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("email"))
|
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("email"))
|
||||||
data, err := ec.unmarshalNEmailAddr2goᚗproboᚗincᚋproboᚋpkgᚋmailᚐAddr(ctx, v)
|
data, err := ec.unmarshalNEmailAddr2goᚗproboᚗincᚋproboᚋpkgᚋmailᚐAddr(ctx, v)
|
||||||
@@ -7618,21 +7544,14 @@ func (ec *executionContext) unmarshalInputRequestTrustCenterFileAccessInput(ctx
|
|||||||
return it, err
|
return it, err
|
||||||
}
|
}
|
||||||
it.Email = data
|
it.Email = data
|
||||||
case "fullName":
|
|
||||||
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("fullName"))
|
|
||||||
data, err := ec.unmarshalNString2string(ctx, v)
|
|
||||||
if err != nil {
|
|
||||||
return it, err
|
|
||||||
}
|
|
||||||
it.FullName = data
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return it, nil
|
return it, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ec *executionContext) unmarshalInputSignInWithTokenInput(ctx context.Context, obj any) (types.SignInWithTokenInput, error) {
|
func (ec *executionContext) unmarshalInputVerifyMagicLinkInput(ctx context.Context, obj any) (types.VerifyMagicLinkInput, error) {
|
||||||
var it types.SignInWithTokenInput
|
var it types.VerifyMagicLinkInput
|
||||||
asMap := map[string]any{}
|
asMap := map[string]any{}
|
||||||
for k, v := range obj.(map[string]any) {
|
for k, v := range obj.(map[string]any) {
|
||||||
asMap[k] = v
|
asMap[k] = v
|
||||||
@@ -8506,13 +8425,14 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet)
|
|||||||
switch field.Name {
|
switch field.Name {
|
||||||
case "__typename":
|
case "__typename":
|
||||||
out.Values[i] = graphql.MarshalString("Mutation")
|
out.Values[i] = graphql.MarshalString("Mutation")
|
||||||
case "signInWithToken":
|
case "sendMagicLink":
|
||||||
out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) {
|
out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) {
|
||||||
return ec._Mutation_signInWithToken(ctx, field)
|
return ec._Mutation_sendMagicLink(ctx, field)
|
||||||
|
})
|
||||||
|
case "verifyMagicLink":
|
||||||
|
out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) {
|
||||||
|
return ec._Mutation_verifyMagicLink(ctx, field)
|
||||||
})
|
})
|
||||||
if out.Values[i] == graphql.Null {
|
|
||||||
out.Invalids++
|
|
||||||
}
|
|
||||||
case "requestAllAccesses":
|
case "requestAllAccesses":
|
||||||
out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) {
|
out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) {
|
||||||
return ec._Mutation_requestAllAccesses(ctx, field)
|
return ec._Mutation_requestAllAccesses(ctx, field)
|
||||||
@@ -8990,19 +8910,19 @@ func (ec *executionContext) _RequestAccessesPayload(ctx context.Context, sel ast
|
|||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
var signInWithTokenPayloadImplementors = []string{"SignInWithTokenPayload"}
|
var sendMagicLinkPayloadImplementors = []string{"SendMagicLinkPayload"}
|
||||||
|
|
||||||
func (ec *executionContext) _SignInWithTokenPayload(ctx context.Context, sel ast.SelectionSet, obj *types.SignInWithTokenPayload) graphql.Marshaler {
|
func (ec *executionContext) _SendMagicLinkPayload(ctx context.Context, sel ast.SelectionSet, obj *types.SendMagicLinkPayload) graphql.Marshaler {
|
||||||
fields := graphql.CollectFields(ec.OperationContext, sel, signInWithTokenPayloadImplementors)
|
fields := graphql.CollectFields(ec.OperationContext, sel, sendMagicLinkPayloadImplementors)
|
||||||
|
|
||||||
out := graphql.NewFieldSet(fields)
|
out := graphql.NewFieldSet(fields)
|
||||||
deferred := make(map[string]*graphql.FieldSet)
|
deferred := make(map[string]*graphql.FieldSet)
|
||||||
for i, field := range fields {
|
for i, field := range fields {
|
||||||
switch field.Name {
|
switch field.Name {
|
||||||
case "__typename":
|
case "__typename":
|
||||||
out.Values[i] = graphql.MarshalString("SignInWithTokenPayload")
|
out.Values[i] = graphql.MarshalString("SendMagicLinkPayload")
|
||||||
case "success":
|
case "success":
|
||||||
out.Values[i] = ec._SignInWithTokenPayload_success(ctx, field, obj)
|
out.Values[i] = ec._SendMagicLinkPayload_success(ctx, field, obj)
|
||||||
if out.Values[i] == graphql.Null {
|
if out.Values[i] == graphql.Null {
|
||||||
out.Invalids++
|
out.Invalids++
|
||||||
}
|
}
|
||||||
@@ -9990,6 +9910,45 @@ func (ec *executionContext) _VendorEdge(ctx context.Context, sel ast.SelectionSe
|
|||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var verifyMagicLinkPayloadImplementors = []string{"VerifyMagicLinkPayload"}
|
||||||
|
|
||||||
|
func (ec *executionContext) _VerifyMagicLinkPayload(ctx context.Context, sel ast.SelectionSet, obj *types.VerifyMagicLinkPayload) graphql.Marshaler {
|
||||||
|
fields := graphql.CollectFields(ec.OperationContext, sel, verifyMagicLinkPayloadImplementors)
|
||||||
|
|
||||||
|
out := graphql.NewFieldSet(fields)
|
||||||
|
deferred := make(map[string]*graphql.FieldSet)
|
||||||
|
for i, field := range fields {
|
||||||
|
switch field.Name {
|
||||||
|
case "__typename":
|
||||||
|
out.Values[i] = graphql.MarshalString("VerifyMagicLinkPayload")
|
||||||
|
case "success":
|
||||||
|
out.Values[i] = ec._VerifyMagicLinkPayload_success(ctx, field, obj)
|
||||||
|
if out.Values[i] == graphql.Null {
|
||||||
|
out.Invalids++
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
panic("unknown field " + strconv.Quote(field.Name))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out.Dispatch(ctx)
|
||||||
|
if out.Invalids > 0 {
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
|
||||||
|
atomic.AddInt32(&ec.deferred, int32(len(deferred)))
|
||||||
|
|
||||||
|
for label, dfs := range deferred {
|
||||||
|
ec.processDeferredGroup(graphql.DeferredGroup{
|
||||||
|
Label: label,
|
||||||
|
Path: graphql.GetPath(ctx),
|
||||||
|
FieldSet: dfs,
|
||||||
|
Context: ctx,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
var __DirectiveImplementors = []string{"__Directive"}
|
var __DirectiveImplementors = []string{"__Directive"}
|
||||||
|
|
||||||
func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionSet, obj *introspection.Directive) graphql.Marshaler {
|
func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionSet, obj *introspection.Directive) graphql.Marshaler {
|
||||||
@@ -11307,11 +11266,6 @@ func (ec *executionContext) marshalNRequestAccessesPayload2ᚖgoᚗproboᚗinc
|
|||||||
return ec._RequestAccessesPayload(ctx, sel, v)
|
return ec._RequestAccessesPayload(ctx, sel, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ec *executionContext) unmarshalNRequestAllAccessesInput2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐRequestAllAccessesInput(ctx context.Context, v any) (types.RequestAllAccessesInput, error) {
|
|
||||||
res, err := ec.unmarshalInputRequestAllAccessesInput(ctx, v)
|
|
||||||
return res, graphql.ErrorOnPath(ctx, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ec *executionContext) unmarshalNRequestDocumentAccessInput2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐRequestDocumentAccessInput(ctx context.Context, v any) (types.RequestDocumentAccessInput, error) {
|
func (ec *executionContext) unmarshalNRequestDocumentAccessInput2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐRequestDocumentAccessInput(ctx context.Context, v any) (types.RequestDocumentAccessInput, error) {
|
||||||
res, err := ec.unmarshalInputRequestDocumentAccessInput(ctx, v)
|
res, err := ec.unmarshalInputRequestDocumentAccessInput(ctx, v)
|
||||||
return res, graphql.ErrorOnPath(ctx, err)
|
return res, graphql.ErrorOnPath(ctx, err)
|
||||||
@@ -11327,6 +11281,11 @@ func (ec *executionContext) unmarshalNRequestTrustCenterFileAccessInput2goᚗpro
|
|||||||
return res, graphql.ErrorOnPath(ctx, err)
|
return res, graphql.ErrorOnPath(ctx, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) unmarshalNSendMagicLinkInput2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐSendMagicLinkInput(ctx context.Context, v any) (types.SendMagicLinkInput, error) {
|
||||||
|
res, err := ec.unmarshalInputSendMagicLinkInput(ctx, v)
|
||||||
|
return res, graphql.ErrorOnPath(ctx, err)
|
||||||
|
}
|
||||||
|
|
||||||
func (ec *executionContext) unmarshalNSessionRequirement2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋgqlutilsᚋdirectivesᚋsessionᚐSessionRequirement(ctx context.Context, v any) (session.SessionRequirement, error) {
|
func (ec *executionContext) unmarshalNSessionRequirement2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋgqlutilsᚋdirectivesᚋsessionᚐSessionRequirement(ctx context.Context, v any) (session.SessionRequirement, error) {
|
||||||
tmp, err := graphql.UnmarshalString(v)
|
tmp, err := graphql.UnmarshalString(v)
|
||||||
res := unmarshalNSessionRequirement2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋgqlutilsᚋdirectivesᚋsessionᚐSessionRequirement[tmp]
|
res := unmarshalNSessionRequirement2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋgqlutilsᚋdirectivesᚋsessionᚐSessionRequirement[tmp]
|
||||||
@@ -11357,25 +11316,6 @@ var (
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func (ec *executionContext) unmarshalNSignInWithTokenInput2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐSignInWithTokenInput(ctx context.Context, v any) (types.SignInWithTokenInput, error) {
|
|
||||||
res, err := ec.unmarshalInputSignInWithTokenInput(ctx, v)
|
|
||||||
return res, graphql.ErrorOnPath(ctx, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ec *executionContext) marshalNSignInWithTokenPayload2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐSignInWithTokenPayload(ctx context.Context, sel ast.SelectionSet, v types.SignInWithTokenPayload) graphql.Marshaler {
|
|
||||||
return ec._SignInWithTokenPayload(ctx, sel, &v)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ec *executionContext) marshalNSignInWithTokenPayload2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐSignInWithTokenPayload(ctx context.Context, sel ast.SelectionSet, v *types.SignInWithTokenPayload) graphql.Marshaler {
|
|
||||||
if v == nil {
|
|
||||||
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
|
|
||||||
graphql.AddErrorf(ctx, "the requested element is null which the schema does not allow")
|
|
||||||
}
|
|
||||||
return graphql.Null
|
|
||||||
}
|
|
||||||
return ec._SignInWithTokenPayload(ctx, sel, v)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ec *executionContext) unmarshalNString2string(ctx context.Context, v any) (string, error) {
|
func (ec *executionContext) unmarshalNString2string(ctx context.Context, v any) (string, error) {
|
||||||
res, err := graphql.UnmarshalString(v)
|
res, err := graphql.UnmarshalString(v)
|
||||||
return res, graphql.ErrorOnPath(ctx, err)
|
return res, graphql.ErrorOnPath(ctx, err)
|
||||||
@@ -11704,6 +11644,11 @@ func (ec *executionContext) marshalNVendorEdge2ᚖgoᚗproboᚗincᚋproboᚋpkg
|
|||||||
return ec._VendorEdge(ctx, sel, v)
|
return ec._VendorEdge(ctx, sel, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) unmarshalNVerifyMagicLinkInput2goᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐVerifyMagicLinkInput(ctx context.Context, v any) (types.VerifyMagicLinkInput, error) {
|
||||||
|
res, err := ec.unmarshalInputVerifyMagicLinkInput(ctx, v)
|
||||||
|
return res, graphql.ErrorOnPath(ctx, err)
|
||||||
|
}
|
||||||
|
|
||||||
func (ec *executionContext) marshalN__Directive2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirective(ctx context.Context, sel ast.SelectionSet, v introspection.Directive) graphql.Marshaler {
|
func (ec *executionContext) marshalN__Directive2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirective(ctx context.Context, sel ast.SelectionSet, v introspection.Directive) graphql.Marshaler {
|
||||||
return ec.___Directive(ctx, sel, &v)
|
return ec.___Directive(ctx, sel, &v)
|
||||||
}
|
}
|
||||||
@@ -12037,6 +11982,13 @@ func (ec *executionContext) marshalOReport2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋs
|
|||||||
return ec._Report(ctx, sel, v)
|
return ec._Report(ctx, sel, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) marshalOSendMagicLinkPayload2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐSendMagicLinkPayload(ctx context.Context, sel ast.SelectionSet, v *types.SendMagicLinkPayload) graphql.Marshaler {
|
||||||
|
if v == nil {
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
return ec._SendMagicLinkPayload(ctx, sel, v)
|
||||||
|
}
|
||||||
|
|
||||||
func (ec *executionContext) unmarshalOString2ᚕstringᚄ(ctx context.Context, v any) ([]string, error) {
|
func (ec *executionContext) unmarshalOString2ᚕstringᚄ(ctx context.Context, v any) ([]string, error) {
|
||||||
if v == nil {
|
if v == nil {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
@@ -12098,6 +12050,13 @@ func (ec *executionContext) marshalOTrustCenter2ᚖgoᚗproboᚗincᚋproboᚋpk
|
|||||||
return ec._TrustCenter(ctx, sel, v)
|
return ec._TrustCenter(ctx, sel, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) marshalOVerifyMagicLinkPayload2ᚖgoᚗproboᚗincᚋproboᚋpkgᚋserverᚋapiᚋtrustᚋv1ᚋtypesᚐVerifyMagicLinkPayload(ctx context.Context, sel ast.SelectionSet, v *types.VerifyMagicLinkPayload) graphql.Marshaler {
|
||||||
|
if v == nil {
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
return ec._VerifyMagicLinkPayload(ctx, sel, v)
|
||||||
|
}
|
||||||
|
|
||||||
func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.EnumValue) graphql.Marshaler {
|
func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.EnumValue) graphql.Marshaler {
|
||||||
if v == nil {
|
if v == nil {
|
||||||
return graphql.Null
|
return graphql.Null
|
||||||
|
|||||||
@@ -150,34 +150,23 @@ type RequestAccessesPayload struct {
|
|||||||
TrustCenterAccess *TrustCenterAccess `json:"trustCenterAccess"`
|
TrustCenterAccess *TrustCenterAccess `json:"trustCenterAccess"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type RequestAllAccessesInput struct {
|
|
||||||
Email mail.Addr `json:"email"`
|
|
||||||
FullName string `json:"fullName"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type RequestDocumentAccessInput struct {
|
type RequestDocumentAccessInput struct {
|
||||||
DocumentID gid.GID `json:"documentId"`
|
DocumentID gid.GID `json:"documentId"`
|
||||||
Email mail.Addr `json:"email"`
|
|
||||||
FullName string `json:"fullName"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type RequestReportAccessInput struct {
|
type RequestReportAccessInput struct {
|
||||||
ReportID gid.GID `json:"reportId"`
|
ReportID gid.GID `json:"reportId"`
|
||||||
Email mail.Addr `json:"email"`
|
|
||||||
FullName string `json:"fullName"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type RequestTrustCenterFileAccessInput struct {
|
type RequestTrustCenterFileAccessInput struct {
|
||||||
TrustCenterFileID gid.GID `json:"trustCenterFileId"`
|
TrustCenterFileID gid.GID `json:"trustCenterFileId"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SendMagicLinkInput struct {
|
||||||
Email mail.Addr `json:"email"`
|
Email mail.Addr `json:"email"`
|
||||||
FullName string `json:"fullName"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type SignInWithTokenInput struct {
|
type SendMagicLinkPayload struct {
|
||||||
Token string `json:"token"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type SignInWithTokenPayload struct {
|
|
||||||
Success bool `json:"success"`
|
Success bool `json:"success"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -275,6 +264,14 @@ type VendorEdge struct {
|
|||||||
Node *Vendor `json:"node"`
|
Node *Vendor `json:"node"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type VerifyMagicLinkInput struct {
|
||||||
|
Token string `json:"token"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type VerifyMagicLinkPayload struct {
|
||||||
|
Success bool `json:"success"`
|
||||||
|
}
|
||||||
|
|
||||||
type Role string
|
type Role string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"go.gearno.de/kit/log"
|
"go.gearno.de/kit/log"
|
||||||
|
"go.probo.inc/probo/pkg/baseurl"
|
||||||
"go.probo.inc/probo/pkg/coredata"
|
"go.probo.inc/probo/pkg/coredata"
|
||||||
"go.probo.inc/probo/pkg/gid"
|
"go.probo.inc/probo/pkg/gid"
|
||||||
"go.probo.inc/probo/pkg/iam"
|
"go.probo.inc/probo/pkg/iam"
|
||||||
@@ -84,7 +85,7 @@ func (r *documentResolver) IsUserAuthorized(ctx context.Context, obj *types.Docu
|
|||||||
|
|
||||||
identity := authn.IdentityFromContext(ctx)
|
identity := authn.IdentityFromContext(ctx)
|
||||||
if identity == nil {
|
if identity == nil {
|
||||||
return false, gqlutils.Unauthenticatedf(ctx, "unauthenticated")
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
documentAccess, err := trustService.TrustCenterAccesses.LoadDocumentAccess(
|
documentAccess, err := trustService.TrustCenterAccesses.LoadDocumentAccess(
|
||||||
@@ -143,8 +144,68 @@ func (r *frameworkResolver) DarkLogoURL(ctx context.Context, obj *types.Framewor
|
|||||||
return trustService.Frameworks.GenerateDarkLogoURL(ctx, obj.ID, 1*time.Hour)
|
return trustService.Frameworks.GenerateDarkLogoURL(ctx, obj.ID, 1*time.Hour)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SignInWithToken is the resolver for the signInWithToken field.
|
// SendMagicLink is the resolver for the sendMagicLink field.
|
||||||
func (r *mutationResolver) SignInWithToken(ctx context.Context, input types.SignInWithTokenInput) (*types.SignInWithTokenPayload, error) {
|
func (r *mutationResolver) SendMagicLink(ctx context.Context, input types.SendMagicLinkInput) (*types.SendMagicLinkPayload, error) {
|
||||||
|
identity := authn.IdentityFromContext(ctx)
|
||||||
|
if identity != nil {
|
||||||
|
return nil, gqlutils.AlreadyAuthenticatedf(ctx, "already authenticated")
|
||||||
|
}
|
||||||
|
|
||||||
|
trustCenter := compliancepage.CompliancePageFromContext(ctx)
|
||||||
|
|
||||||
|
organization, err := r.iam.OrganizationService.GetOrganization(ctx, trustCenter.OrganizationID)
|
||||||
|
if err != nil {
|
||||||
|
var errNotFound *iam.ErrOrganizationNotFound
|
||||||
|
if errors.As(err, &errNotFound) {
|
||||||
|
return nil, gqlutils.NotFoundf(ctx, "organization not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
r.logger.ErrorCtx(ctx, "cannot get organization", log.Error(err))
|
||||||
|
return nil, gqlutils.Internal(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
customDomain, err := r.trust.GetCustomDomainByOrganizationID(ctx, organization.ID)
|
||||||
|
if err != nil {
|
||||||
|
var errNotFound *iam.ErrOrganizationNotFound
|
||||||
|
if !errors.As(err, &errNotFound) {
|
||||||
|
r.logger.ErrorCtx(ctx, "cannot get custom domain", log.Error(err))
|
||||||
|
return nil, gqlutils.Internal(ctx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
req := &iam.SendMagicLinkRequest{
|
||||||
|
Email: input.Email,
|
||||||
|
}
|
||||||
|
|
||||||
|
if false {
|
||||||
|
// if customDomain != nil {
|
||||||
|
baseURL, err := baseurl.Parse(fmt.Sprintf("https://%s", customDomain.Domain))
|
||||||
|
if err != nil {
|
||||||
|
r.logger.ErrorCtx(ctx, "cannot parse custom domain url", log.Error(err))
|
||||||
|
return nil, gqlutils.Internal(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
req.BaseURL = baseURL
|
||||||
|
} else {
|
||||||
|
baseURL, err := baseurl.Parse(r.baseURL.WithPath("/trust/" + trustCenter.ID.String()).MustString())
|
||||||
|
if err != nil {
|
||||||
|
r.logger.ErrorCtx(ctx, "cannot parse url", log.Error(err))
|
||||||
|
return nil, gqlutils.Internal(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
req.BaseURL = baseURL
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := r.iam.AuthService.SendMagicLink(ctx, req); err != nil {
|
||||||
|
r.logger.ErrorCtx(ctx, "cannot send magic link", log.Error(err))
|
||||||
|
return nil, gqlutils.Internal(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// VerifyMagicLink is the resolver for the verifyMagicLink field.
|
||||||
|
func (r *mutationResolver) VerifyMagicLink(ctx context.Context, input types.VerifyMagicLinkInput) (*types.VerifyMagicLinkPayload, error) {
|
||||||
_, session, err := r.iam.AuthService.OpenSessionWithMagicLink(ctx, input.Token)
|
_, session, err := r.iam.AuthService.OpenSessionWithMagicLink(ctx, input.Token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
var errInvalidToken *iam.ErrInvalidToken
|
var errInvalidToken *iam.ErrInvalidToken
|
||||||
@@ -156,33 +217,23 @@ func (r *mutationResolver) SignInWithToken(ctx context.Context, input types.Sign
|
|||||||
return nil, gqlutils.Internal(ctx)
|
return nil, gqlutils.Internal(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO cookie domain
|
// FIXME: cookie domain
|
||||||
w := gqlutils.HTTPResponseWriterFromContext(ctx)
|
w := gqlutils.HTTPResponseWriterFromContext(ctx)
|
||||||
r.sessionCookie.Set(w, session)
|
r.sessionCookie.Set(w, session)
|
||||||
|
|
||||||
return &types.SignInWithTokenPayload{
|
return &types.VerifyMagicLinkPayload{
|
||||||
Success: true,
|
Success: true,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RequestAllAccesses is the resolver for the requestAllAccesses field.
|
// RequestAllAccesses is the resolver for the requestAllAccesses field.
|
||||||
func (r *mutationResolver) RequestAllAccesses(ctx context.Context, input types.RequestAllAccessesInput) (*types.RequestAccessesPayload, error) {
|
func (r *mutationResolver) RequestAllAccesses(ctx context.Context) (*types.RequestAccessesPayload, error) {
|
||||||
trustCenter := compliancepage.CompliancePageFromContext(ctx)
|
trustCenter := compliancepage.CompliancePageFromContext(ctx)
|
||||||
trustService := r.TrustService(ctx, trustCenter.ID.TenantID())
|
trustService := r.TrustService(ctx, trustCenter.ID.TenantID())
|
||||||
|
|
||||||
identity := authn.IdentityFromContext(ctx)
|
identity := authn.IdentityFromContext(ctx)
|
||||||
if identity == nil {
|
if identity == nil {
|
||||||
var err error
|
return nil, gqlutils.Unauthenticatedf(ctx, "authentication is required to request access")
|
||||||
identity, err = r.iam.AuthService.LoadOrCreateIdentity(
|
|
||||||
ctx,
|
|
||||||
&iam.LoadOrCreateIdentityRequest{
|
|
||||||
Email: input.Email,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
r.logger.ErrorCtx(ctx, "cannot load or create identity", log.Error(err))
|
|
||||||
return nil, gqlutils.Internal(ctx)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
access, err := trustService.TrustCenterAccesses.Request(
|
access, err := trustService.TrustCenterAccesses.Request(
|
||||||
@@ -242,10 +293,6 @@ func (r *mutationResolver) ExportDocumentPDF(ctx context.Context, input types.Ex
|
|||||||
ndaExists := true
|
ndaExists := true
|
||||||
hasAcceptedNDA := false
|
hasAcceptedNDA := false
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
r.logger.ErrorCtx(ctx, "cannot get trust center", log.Error(err))
|
|
||||||
return nil, gqlutils.Internal(ctx)
|
|
||||||
}
|
|
||||||
if trustCenter.NonDisclosureAgreementFileID == nil {
|
if trustCenter.NonDisclosureAgreementFileID == nil {
|
||||||
ndaExists = false
|
ndaExists = false
|
||||||
}
|
}
|
||||||
@@ -296,6 +343,11 @@ func (r *mutationResolver) ExportDocumentPDF(ctx context.Context, input types.Ex
|
|||||||
|
|
||||||
// ExportReportPDF is the resolver for the exportReportPDF field.
|
// ExportReportPDF is the resolver for the exportReportPDF field.
|
||||||
func (r *mutationResolver) ExportReportPDF(ctx context.Context, input types.ExportReportPDFInput) (*types.ExportReportPDFPayload, error) {
|
func (r *mutationResolver) ExportReportPDF(ctx context.Context, input types.ExportReportPDFInput) (*types.ExportReportPDFPayload, error) {
|
||||||
|
identity := authn.IdentityFromContext(ctx)
|
||||||
|
if identity == nil {
|
||||||
|
return nil, gqlutils.Unauthenticatedf(ctx, "unauthenticated")
|
||||||
|
}
|
||||||
|
|
||||||
trustService := r.TrustService(ctx, input.ReportID.TenantID())
|
trustService := r.TrustService(ctx, input.ReportID.TenantID())
|
||||||
|
|
||||||
trustCenter := compliancepage.CompliancePageFromContext(ctx)
|
trustCenter := compliancepage.CompliancePageFromContext(ctx)
|
||||||
@@ -318,18 +370,9 @@ func (r *mutationResolver) ExportReportPDF(ctx context.Context, input types.Expo
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
identity := authn.IdentityFromContext(ctx)
|
|
||||||
if identity == nil {
|
|
||||||
return nil, gqlutils.Unauthenticatedf(ctx, "unauthenticated")
|
|
||||||
}
|
|
||||||
|
|
||||||
ndaExists := true
|
ndaExists := true
|
||||||
hasAcceptedNDA := false
|
hasAcceptedNDA := false
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
r.logger.ErrorCtx(ctx, "cannot get trust center", log.Error(err))
|
|
||||||
return nil, gqlutils.Internal(ctx)
|
|
||||||
}
|
|
||||||
if trustCenter.NonDisclosureAgreementFileID == nil {
|
if trustCenter.NonDisclosureAgreementFileID == nil {
|
||||||
ndaExists = false
|
ndaExists = false
|
||||||
}
|
}
|
||||||
@@ -380,13 +423,12 @@ func (r *mutationResolver) ExportReportPDF(ctx context.Context, input types.Expo
|
|||||||
|
|
||||||
// AcceptNonDisclosureAgreement is the resolver for the acceptNonDisclosureAgreement field.
|
// AcceptNonDisclosureAgreement is the resolver for the acceptNonDisclosureAgreement field.
|
||||||
func (r *mutationResolver) AcceptNonDisclosureAgreement(ctx context.Context) (*types.AcceptNonDisclosureAgreementPayload, error) {
|
func (r *mutationResolver) AcceptNonDisclosureAgreement(ctx context.Context) (*types.AcceptNonDisclosureAgreementPayload, error) {
|
||||||
trustCenter := compliancepage.CompliancePageFromContext(ctx)
|
|
||||||
trustService := r.TrustService(ctx, trustCenter.ID.TenantID())
|
|
||||||
|
|
||||||
identity := authn.IdentityFromContext(ctx)
|
identity := authn.IdentityFromContext(ctx)
|
||||||
if identity == nil {
|
if identity == nil {
|
||||||
return nil, gqlutils.Unauthenticatedf(ctx, "unauthenticated")
|
return nil, gqlutils.Unauthenticatedf(ctx, "unauthenticated")
|
||||||
}
|
}
|
||||||
|
trustCenter := compliancepage.CompliancePageFromContext(ctx)
|
||||||
|
trustService := r.TrustService(ctx, trustCenter.ID.TenantID())
|
||||||
|
|
||||||
httpReq := gqlutils.HTTPRequestFromContext(ctx)
|
httpReq := gqlutils.HTTPRequestFromContext(ctx)
|
||||||
|
|
||||||
@@ -424,17 +466,7 @@ func (r *mutationResolver) RequestDocumentAccess(ctx context.Context, input type
|
|||||||
|
|
||||||
identity := authn.IdentityFromContext(ctx)
|
identity := authn.IdentityFromContext(ctx)
|
||||||
if identity == nil {
|
if identity == nil {
|
||||||
var err error
|
return nil, gqlutils.Unauthenticatedf(ctx, "authentication is required to request access")
|
||||||
identity, err = r.iam.AuthService.LoadOrCreateIdentity(
|
|
||||||
ctx,
|
|
||||||
&iam.LoadOrCreateIdentityRequest{
|
|
||||||
Email: input.Email,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
r.logger.ErrorCtx(ctx, "cannot load or create identity", log.Error(err))
|
|
||||||
return nil, gqlutils.Internal(ctx)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
access, err := trustService.TrustCenterAccesses.Request(
|
access, err := trustService.TrustCenterAccesses.Request(
|
||||||
@@ -483,17 +515,7 @@ func (r *mutationResolver) RequestReportAccess(ctx context.Context, input types.
|
|||||||
|
|
||||||
identity := authn.IdentityFromContext(ctx)
|
identity := authn.IdentityFromContext(ctx)
|
||||||
if identity == nil {
|
if identity == nil {
|
||||||
var err error
|
return nil, gqlutils.Unauthenticatedf(ctx, "authentication is required to request access")
|
||||||
identity, err = r.iam.AuthService.LoadOrCreateIdentity(
|
|
||||||
ctx,
|
|
||||||
&iam.LoadOrCreateIdentityRequest{
|
|
||||||
Email: input.Email,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
r.logger.ErrorCtx(ctx, "cannot load or create identity", log.Error(err))
|
|
||||||
return nil, gqlutils.Internal(ctx)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
access, err := trustService.TrustCenterAccesses.Request(
|
access, err := trustService.TrustCenterAccesses.Request(
|
||||||
@@ -542,17 +564,7 @@ func (r *mutationResolver) RequestTrustCenterFileAccess(ctx context.Context, inp
|
|||||||
|
|
||||||
identity := authn.IdentityFromContext(ctx)
|
identity := authn.IdentityFromContext(ctx)
|
||||||
if identity == nil {
|
if identity == nil {
|
||||||
var err error
|
return nil, gqlutils.Unauthenticatedf(ctx, "authentication is required to request access")
|
||||||
identity, err = r.iam.AuthService.LoadOrCreateIdentity(
|
|
||||||
ctx,
|
|
||||||
&iam.LoadOrCreateIdentityRequest{
|
|
||||||
Email: input.Email,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
r.logger.ErrorCtx(ctx, "cannot load or create identity", log.Error(err))
|
|
||||||
return nil, gqlutils.Internal(ctx)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
access, err := trustService.TrustCenterAccesses.Request(
|
access, err := trustService.TrustCenterAccesses.Request(
|
||||||
@@ -584,6 +596,11 @@ func (r *mutationResolver) RequestTrustCenterFileAccess(ctx context.Context, inp
|
|||||||
|
|
||||||
// ExportTrustCenterFile is the resolver for the exportTrustCenterFile field.
|
// ExportTrustCenterFile is the resolver for the exportTrustCenterFile field.
|
||||||
func (r *mutationResolver) ExportTrustCenterFile(ctx context.Context, input types.ExportTrustCenterFileInput) (*types.ExportTrustCenterFilePayload, error) {
|
func (r *mutationResolver) ExportTrustCenterFile(ctx context.Context, input types.ExportTrustCenterFileInput) (*types.ExportTrustCenterFilePayload, error) {
|
||||||
|
identity := authn.IdentityFromContext(ctx)
|
||||||
|
if identity == nil {
|
||||||
|
return nil, gqlutils.Unauthenticatedf(ctx, "unauthenticated")
|
||||||
|
}
|
||||||
|
|
||||||
trustCenter := compliancepage.CompliancePageFromContext(ctx)
|
trustCenter := compliancepage.CompliancePageFromContext(ctx)
|
||||||
trustService := r.TrustService(ctx, trustCenter.ID.TenantID())
|
trustService := r.TrustService(ctx, trustCenter.ID.TenantID())
|
||||||
|
|
||||||
@@ -605,11 +622,6 @@ func (r *mutationResolver) ExportTrustCenterFile(ctx context.Context, input type
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
identity := authn.IdentityFromContext(ctx)
|
|
||||||
if identity == nil {
|
|
||||||
return nil, gqlutils.Unauthenticatedf(ctx, "unauthenticated")
|
|
||||||
}
|
|
||||||
|
|
||||||
ndaExists := true
|
ndaExists := true
|
||||||
hasAcceptedNDA := false
|
hasAcceptedNDA := false
|
||||||
|
|
||||||
@@ -782,6 +794,11 @@ func (r *queryResolver) CurrentTrustCenter(ctx context.Context) (*types.TrustCen
|
|||||||
|
|
||||||
// IsUserAuthorized is the resolver for the isUserAuthorized field.
|
// IsUserAuthorized is the resolver for the isUserAuthorized field.
|
||||||
func (r *reportResolver) IsUserAuthorized(ctx context.Context, obj *types.Report) (bool, error) {
|
func (r *reportResolver) IsUserAuthorized(ctx context.Context, obj *types.Report) (bool, error) {
|
||||||
|
identity := authn.IdentityFromContext(ctx)
|
||||||
|
if identity == nil {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
trustService := r.TrustService(ctx, obj.ID.TenantID())
|
trustService := r.TrustService(ctx, obj.ID.TenantID())
|
||||||
|
|
||||||
trustCenter := compliancepage.CompliancePageFromContext(ctx)
|
trustCenter := compliancepage.CompliancePageFromContext(ctx)
|
||||||
@@ -796,11 +813,6 @@ func (r *reportResolver) IsUserAuthorized(ctx context.Context, obj *types.Report
|
|||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
identity := authn.IdentityFromContext(ctx)
|
|
||||||
if identity == nil {
|
|
||||||
return false, gqlutils.Unauthenticatedf(ctx, "unauthenticated")
|
|
||||||
}
|
|
||||||
|
|
||||||
reportAccess, err := trustService.TrustCenterAccesses.LoadReportAccess(ctx,
|
reportAccess, err := trustService.TrustCenterAccesses.LoadReportAccess(ctx,
|
||||||
trustCenter.ID,
|
trustCenter.ID,
|
||||||
identity.EmailAddress,
|
identity.EmailAddress,
|
||||||
@@ -984,6 +996,11 @@ func (r *trustCenterResolver) TrustCenterFiles(ctx context.Context, obj *types.T
|
|||||||
|
|
||||||
// IsUserAuthorized is the resolver for the isUserAuthorized field.
|
// IsUserAuthorized is the resolver for the isUserAuthorized field.
|
||||||
func (r *trustCenterFileResolver) IsUserAuthorized(ctx context.Context, obj *types.TrustCenterFile) (bool, error) {
|
func (r *trustCenterFileResolver) IsUserAuthorized(ctx context.Context, obj *types.TrustCenterFile) (bool, error) {
|
||||||
|
identity := authn.IdentityFromContext(ctx)
|
||||||
|
if identity == nil {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
trustService := r.TrustService(ctx, obj.ID.TenantID())
|
trustService := r.TrustService(ctx, obj.ID.TenantID())
|
||||||
|
|
||||||
trustCenter := compliancepage.CompliancePageFromContext(ctx)
|
trustCenter := compliancepage.CompliancePageFromContext(ctx)
|
||||||
@@ -998,11 +1015,6 @@ func (r *trustCenterFileResolver) IsUserAuthorized(ctx context.Context, obj *typ
|
|||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
identity := authn.IdentityFromContext(ctx)
|
|
||||||
if identity == nil {
|
|
||||||
return false, gqlutils.Unauthenticatedf(ctx, "unauthenticated")
|
|
||||||
}
|
|
||||||
|
|
||||||
fileAccess, err := trustService.TrustCenterAccesses.LoadTrustCenterFileAccess(ctx,
|
fileAccess, err := trustService.TrustCenterAccesses.LoadTrustCenterFileAccess(ctx,
|
||||||
trustCenter.ID,
|
trustCenter.ID,
|
||||||
identity.EmailAddress,
|
identity.EmailAddress,
|
||||||
|
|||||||
@@ -25,6 +25,19 @@ import (
|
|||||||
"go.probo.inc/probo/pkg/validator"
|
"go.probo.inc/probo/pkg/validator"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func AlreadyAuthenticated(ctx context.Context, err error) *gqlerror.Error {
|
||||||
|
return &gqlerror.Error{
|
||||||
|
Message: "Authentication not allowed for this resource/action",
|
||||||
|
Extensions: map[string]any{
|
||||||
|
"code": "ALREADY_AUTHENTICATED",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func AlreadyAuthenticatedf(ctx context.Context, format string, a ...any) *gqlerror.Error {
|
||||||
|
return AlreadyAuthenticated(ctx, fmt.Errorf(format, a...))
|
||||||
|
}
|
||||||
|
|
||||||
func Unauthenticated(ctx context.Context, err error) *gqlerror.Error {
|
func Unauthenticated(ctx context.Context, err error) *gqlerror.Error {
|
||||||
return &gqlerror.Error{
|
return &gqlerror.Error{
|
||||||
Message: err.Error(),
|
Message: err.Error(),
|
||||||
@@ -39,15 +52,6 @@ func Unauthenticatedf(ctx context.Context, format string, a ...any) *gqlerror.Er
|
|||||||
return Unauthenticated(ctx, fmt.Errorf(format, a...))
|
return Unauthenticated(ctx, fmt.Errorf(format, a...))
|
||||||
}
|
}
|
||||||
|
|
||||||
func AlreadyUnauthenticated(ctx context.Context, err error) *gqlerror.Error {
|
|
||||||
return &gqlerror.Error{
|
|
||||||
Message: "Authentication not allowed for this resource/action",
|
|
||||||
Extensions: map[string]any{
|
|
||||||
"code": "ALREADY_AUTHENTICATED",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Forbidden(ctx context.Context, err error) *gqlerror.Error {
|
func Forbidden(ctx context.Context, err error) *gqlerror.Error {
|
||||||
return &gqlerror.Error{
|
return &gqlerror.Error{
|
||||||
Message: err.Error(),
|
Message: err.Error(),
|
||||||
|
|||||||
@@ -149,6 +149,8 @@ func (s *Server) stripTrustPrefix(next http.Handler) http.Handler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
r.URL.Path = strings.TrimPrefix(r.URL.Path, prefix)
|
r.URL.Path = strings.TrimPrefix(r.URL.Path, prefix)
|
||||||
|
r.URL.Path = strings.TrimPrefix(r.URL.Path, "/auth")
|
||||||
|
|
||||||
if r.URL.Path == "" {
|
if r.URL.Path == "" {
|
||||||
r.URL.Path = "/"
|
r.URL.Path = "/"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -229,3 +229,16 @@ func (s *Service) GetByDomainName(ctx context.Context, domain string) (*coredata
|
|||||||
|
|
||||||
return trustCenter, err
|
return trustCenter, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Service) GetCustomDomainByOrganizationID(ctx context.Context, organizationID gid.GID) (*coredata.CustomDomain, error) {
|
||||||
|
customDomain := &coredata.CustomDomain{}
|
||||||
|
|
||||||
|
err := s.pg.WithConn(
|
||||||
|
ctx,
|
||||||
|
func(conn pg.Conn) error {
|
||||||
|
return customDomain.LoadByOrganizationID(ctx, conn, coredata.NewNoScope(), s.encryptionKey, organizationID)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
return customDomain, err
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user