diff --git a/components/CreateAgreement/NavPanel.tsx b/components/CreateAgreement/NavPanel.tsx index 561f144..ef6312f 100644 --- a/components/CreateAgreement/NavPanel.tsx +++ b/components/CreateAgreement/NavPanel.tsx @@ -22,7 +22,10 @@ import { fW, } from "./styles"; import { useMutation } from "urql"; -import { saveAgreementMutation } from "../../modules/graphql/mutations"; +import { + saveAgreementMutation, + sendEmailVerificationLinkMutation, +} from "../../modules/graphql/mutations"; import { LOCATION_CLOUD, LOCATION_PUBLIC_IPFS, @@ -44,6 +47,7 @@ import { uploadFile, uploadToIpfs } from "../../modules/rest"; import { notifError } from "../../utils/notification"; import ModalConfirmAgreementDeletion from "../ModalConfirmAgreementDeletion/ModalConfirmAgreementDeletion"; import { getToken } from "../../utils/token"; +import { isEmail } from "./utils"; const FILE_UPLOAD_ERROR_DEFAULT_MESSAGE = "Failed to upload file"; @@ -64,9 +68,9 @@ export default function NavPanel({ setLoading, page }: { setLoading: any; page: const [isLoadingNextStep, setIsLoadingNextStep] = useState(false); const [isAuthorNotAddedPopupVisible, setIsAuthorNotAddedPopupVisible] = useState(false); - const [isConfirmAgreementDeletionPopupVisible, setIsConfirmAgreementDeletionPopupVisible] = useState(false); + const [, sendEmailVerificationLinkRequest] = useMutation(sendEmailVerificationLinkMutation); const validateFields = (values: CreationState, isSavingDraft: boolean = false): boolean => { const errors: CreateAgreementFieldErrors = {}; @@ -203,8 +207,41 @@ export default function NavPanel({ setLoading, page }: { setLoading: any; page: }); }; + const sendEmailVerificationEmails = async (signers: string[], observers: string[]) => { + console.log("sendEmailVerificationEmails"); + console.log({ signers, observers }); + + signers.forEach(async signer => { + if (isEmail(signer)) { + console.log(`seding an email to ${signer}`); + await sendEmailVerificationLinkRequest({ + email: signer, + isSigner: true, + agreementTitle: values.title, + }); + } + }); + + observers.forEach(async observer => { + if (isEmail(observer)) { + console.log(`seding an email to ${observer}`); + await sendEmailVerificationLinkRequest({ + email: observer, + isSigner: false, + agreementTitle: values.title, + }); + } + }); + }; + const handleSaveDraft = async () => { + console.log("handleSaveDraft"); const areFieldsValid = validateFields(values, true); + await sendEmailVerificationEmails( + values.signers.map(x => x.value), + values.observers.map(x => x.value) + ); + console.log({ values }); if (areFieldsValid) { const uploadFileData: any = await preuploadFile(); await handleCreateAgreement(uploadFileData?.filePath, uploadFileData?.agreementHash); @@ -348,6 +385,10 @@ export default function NavPanel({ setLoading, page }: { setLoading: any; page: const areFieldsValid = validateFields({ ...values, ...uploadedFileData }); if (areFieldsValid) { if (isFinishButton) { + await sendEmailVerificationEmails( + values.signers.map(x => x.value), + values.observers.map(x => x.value) + ); await handleCreateAgreement(); } else { handleNextStep(); diff --git a/components/CreateAgreement/Steps/StepThree/validationUtils.ts b/components/CreateAgreement/Steps/StepThree/validationUtils.ts index 66345fc..e0e1811 100644 --- a/components/CreateAgreement/Steps/StepThree/validationUtils.ts +++ b/components/CreateAgreement/Steps/StepThree/validationUtils.ts @@ -11,3 +11,10 @@ export const validateAddress = (value: string): string | undefined => { return "Invalid wallet address"; } }; + +export const validateEmail = (value: string): string | undefined => { + const isValidEmail = value.match(/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/); + if (!isValidEmail) { + return "Invalid email address"; + } +}; diff --git a/components/CreateAgreement/Steps/StepTwo/index.tsx b/components/CreateAgreement/Steps/StepTwo/index.tsx index d1fc26c..33c0068 100644 --- a/components/CreateAgreement/Steps/StepTwo/index.tsx +++ b/components/CreateAgreement/Steps/StepTwo/index.tsx @@ -1,5 +1,5 @@ import React, { useRef, useMemo, useState } from "react"; -import { Container, Flex, Input, Text, Button, Box, Switch, Label } from "theme-ui"; +import { Container, Flex, Input, Text, Button, Box } from "theme-ui"; import { inputCreateAgreementWithRightButton, inputCreateAgreementError, @@ -8,7 +8,7 @@ import { addMeBtn, plus, } from "../../styles"; -import { validateAddress, validateEnsDomains } from "../StepThree/validationUtils"; +import { validateAddress, validateEmail, validateEnsDomains } from "../StepThree/validationUtils"; import { useCreateAgreement } from "../../../../hooks/useCreateAgreement"; import { useEditAgreement } from "../../../../hooks/useEditAgreement"; import FieldErrorMessage from "../../../Form/FieldErrorMessage"; @@ -23,6 +23,7 @@ import Icon from "../../../icon"; import { PlusIcon } from "./svg"; import styles from "./styles"; import { notifComingSoon } from "../../../../utils/notification"; +import { isEmail } from "../../utils"; interface VerificationInfo { title: string; @@ -130,6 +131,7 @@ export default function StepTwo({ page }: { page: string }) { if (userAlreadyObserver) { return userRole === "signer" ? "Already exists as Observer" : "Observer is already added"; } + const isEns = value?.includes(".eth"); if (isEns) { const error = validateEnsDomains(value); @@ -140,13 +142,17 @@ export default function StepTwo({ page }: { page: string }) { } const isAddress = value?.startsWith("0x"); - if (isAddress) { const error = validateAddress(value); if (error) return error; } - if (!isEns && !isAddress) { + if (isEmail(value)) { + const error = validateEmail(value); + if (error) return error; + } + + if (!isEns && !isAddress && !isEmail(value)) { return "Invalid value"; } @@ -166,6 +172,7 @@ export default function StepTwo({ page }: { page: string }) { changeValue("errors", { ...values.errors, signers: validationError }); return; } + changeValue("signers", [ ...values.signers, { value: value.toLocaleLowerCase(), id: uniqueId() }, @@ -207,12 +214,13 @@ export default function StepTwo({ page }: { page: string }) { return ( <> + {/* Signers */} - Signers (ENS name or address) * + Signers (ENS name, Ethereum address, or email) * + + {/* Observers */} - Observers (ENS name or adderess){" "} + Observers (ENS name, Ethereum adderess, or email){" "} + + {/* Required Verifications */} { return ( x?.includes("@"); diff --git a/components/ModalEditObservers/index.tsx b/components/ModalEditObservers/index.tsx index 035c4c4..46295d7 100644 --- a/components/ModalEditObservers/index.tsx +++ b/components/ModalEditObservers/index.tsx @@ -155,7 +155,7 @@ export default function ModalEditObservers({ agreement, isOpen, onExit, onSucces - Observers (ENS name or adderess) + Observers (ENS name, Ethereum adderess, or email) { - - + + diff --git a/components/ViewAgreement/AgreementSignersList.tsx b/components/ViewAgreement/AgreementSignersList.tsx index a6ea3d1..4b53f3e 100644 --- a/components/ViewAgreement/AgreementSignersList.tsx +++ b/components/ViewAgreement/AgreementSignersList.tsx @@ -35,8 +35,8 @@ export const AgreementSignersList = ({ signers }: Props) => {
Observer NameObserver AddressNameAddress/Email/ENS
- - + + diff --git a/components/ViewAgreement/ObserverRow.tsx b/components/ViewAgreement/ObserverRow.tsx index ae87f2c..62ea830 100644 --- a/components/ViewAgreement/ObserverRow.tsx +++ b/components/ViewAgreement/ObserverRow.tsx @@ -26,10 +26,10 @@ export const ObserverRow = ({ observer }: Props) => { const address = useMemo( () => - observer?.wallet?.address - ? observer.wallet.address - : !!observer?.email?.startsWith("0x") + !!observer?.email?.length ? observer?.email + : observer?.wallet?.address + ? observer?.wallet?.address : "", [observer] ); diff --git a/components/ViewAgreement/SignerRow.tsx b/components/ViewAgreement/SignerRow.tsx index 931d852..3509dad 100644 --- a/components/ViewAgreement/SignerRow.tsx +++ b/components/ViewAgreement/SignerRow.tsx @@ -35,10 +35,10 @@ export const SignerRow = ({ signer, signProof, viewProof }: Props) => { const address = useMemo( () => - signer?.wallet?.address - ? signer.wallet.address - : !!signer?.email?.startsWith("0x") + !!signer?.email?.length ? signer?.email + : signer?.wallet?.address + ? signer?.wallet?.address : "", [signer] ); diff --git a/components/ViewAgreement/index.tsx b/components/ViewAgreement/index.tsx index adcbfc6..a62c6ed 100644 --- a/components/ViewAgreement/index.tsx +++ b/components/ViewAgreement/index.tsx @@ -2,7 +2,7 @@ import React, { useCallback, useEffect, useMemo, useState } from "react"; import { Box, Button, Flex } from "theme-ui"; import { useRouter } from "next/router"; -import { useMutation, useQuery, useClient } from "urql"; +import { useClient } from "urql"; import { agreementById } from "../../modules/graphql/queries"; import { diff --git a/modules/authProvider.tsx b/modules/authProvider.tsx index 98e6a6f..c35edc0 100644 --- a/modules/authProvider.tsx +++ b/modules/authProvider.tsx @@ -66,17 +66,23 @@ const AuthProvider = (props?: Partial>) => { profile: null, //isTrezor: false, }); - const { push, pathname } = useRouter(); + const { push, pathname, query, isReady } = useRouter(); const [, loginRequest] = useMutation(loginMutation); const [, verifyMyEmailRequest] = useMutation(verifyMyEmailMutation); const auth = useLock(); - const loginStarted = useRef(false); - const web3ProviderRef = useRef(); async function login(connector?: ConnectorType, email?: string, emailVerificationSalt?: string) { + console.log("login()"); + console.log({ query }); + email = email ?? (query.email as string); + emailVerificationSalt = emailVerificationSalt ?? (query.emailVerificationSalt as string); + console.log({ + email, + emailVerificationSalt, + }); // Prevent double loginRequest due to react dev useEffect[] runs twice if (loginStarted.current) return; loginStarted.current = true; @@ -125,7 +131,10 @@ const AuthProvider = (props?: Partial>) => { if (!account) return; if (getToken()) return; // user already has a token - const res = await loginRequest({ address: account }); + console.log("onAfterConnect"); + console.log({ email, emailVerificationSalt }); + + const res = await loginRequest({ address: account, email }); const payload = res?.data?.login?.payload; if (!payload) return; @@ -133,6 +142,7 @@ const AuthProvider = (props?: Partial>) => { const signature = await sign(payload); const tokenRes = await loginRequest({ address: account, + email, signature: signature, }); @@ -227,7 +237,7 @@ const AuthProvider = (props?: Partial>) => { //@ts-ignore provider.value?.wc?.peerMeta?.name || null; } catch (e) { - console.log("ERROR load web3", e); + console.error("ERROR load web3", e); //setState((state) => ({ ...state, account: "" })); loadedState.account = ""; @@ -296,9 +306,25 @@ const AuthProvider = (props?: Partial>) => { return await web3ProviderRef.current?.resolveName(name); } + async function loginWhenNecessary() { + const hasToken = Boolean(getToken()); + const loadedConnector = await auth.getConnector(); + if ((!loadedConnector || !hasToken) && pathname !== "/connect") { + // Redirect to the connect page + clearToken(); + await push("/connect"); + loginStarted.current = false; + } else { + // Perform user login + if (isReady && pathname !== "/connect") { + login(); + } + } + } + useEffect(() => { - login(); - }, []); // eslint-disable-line react-hooks/exhaustive-deps + loginWhenNecessary(); + }, [isReady]); // eslint-disable-line react-hooks/exhaustive-deps return ( >) => { signTypedData, _signTypedData, resolveEns, - //loadProvider, - //handleChainChanged, - //web3: state, ...state, }} /> diff --git a/modules/createAgreementProvider.tsx b/modules/createAgreementProvider.tsx index a1ca02b..330a831 100644 --- a/modules/createAgreementProvider.tsx +++ b/modules/createAgreementProvider.tsx @@ -1,6 +1,5 @@ import { useRouter } from "next/router"; import { useState, createContext, ProviderProps, useEffect, useRef } from "react"; -import { StringDecoder } from "string_decoder"; import { AgreementLocation, AgreementMethod, diff --git a/modules/graphql/gql/gql.ts b/modules/graphql/gql/gql.ts index 94332d6..72e248d 100644 --- a/modules/graphql/gql/gql.ts +++ b/modules/graphql/gql/gql.ts @@ -18,8 +18,9 @@ const documents = { "\n mutation sendSignedFileProofData(\n $data: AgreementFileProofDataInput!\n $signature: String!\n $agreementId: Int!\n ) {\n sendSignedFileProofData(data: $data, signature: $signature, agreementId: $agreementId) {\n cid\n }\n }\n": types.SendSignedFileProofDataDocument, "\n mutation sendSignedSignProofData(\n $data: AgreementSignProofDataInput!\n $signature: String!\n $agreementId: Int!\n ) {\n sendSignedSignProofData(data: $data, signature: $signature, agreementId: $agreementId) {\n cid\n }\n }\n": types.SendSignedSignProofDataDocument, "\n mutation EditObservers($agreementId: Int, $observers: [String!]) {\n editObservers(agreementId: $agreementId, observers: $observers) {\n message\n }\n }\n": types.EditObserversDocument, - "\n mutation login($address: String!, $signature: String) {\n login(address: $address, signature: $signature) {\n message\n payload\n token\n }\n }\n": types.LoginDocument, + "\n mutation login($address: String!, $email: String, $signature: String) {\n login(address: $address, email: $email, signature: $signature) {\n message\n payload\n token\n }\n }\n": types.LoginDocument, "\n mutation Mutation {\n logout {\n message\n }\n }\n": types.MutationDocument, + "\n mutation sendEmailVerificationLink(\n $email: String!\n $isSigner: Boolean!\n $agreementTitle: String!\n ) {\n sendEmailVerificationLink(email: $email, isSigner: $isSigner, agreementTitle: $agreementTitle)\n }\n": types.SendEmailVerificationLinkDocument, "\n mutation verifyMyEmail($emailVerificationSalt: String!, $email: String!) {\n verifyMyEmail(emailVerificationSalt: $emailVerificationSalt, email: $email)\n }\n": types.VerifyMyEmailDocument, "\n query Query($agreementId: Int!) {\n agreement(agreementId: $agreementId) {\n agreementId\n snapshotProposalUrl\n agreementFile {\n agreementFileId\n agreementHash\n createdAt\n filePath\n }\n agreementLocation {\n agreementLocationId\n isActive\n name\n }\n agreementPrivacy {\n name\n }\n agreementStatus {\n name\n }\n authorWallet {\n address\n networkId\n userId\n walletId\n }\n observers {\n email\n observerId\n wallet {\n address\n }\n ens {\n name\n }\n }\n signers {\n email\n wallet {\n address\n }\n ens {\n name\n }\n }\n title\n content\n isWaitingForMySignature\n snapshotProposalUrl\n isAllowedToEditObservers\n createdAt\n signProofs {\n signature\n cid\n signerWalletId\n signerWallet {\n address\n }\n }\n agreementFileProof {\n cid\n signature\n signers\n }\n agreementProof {\n cid\n signedAt\n }\n }\n }\n": types.QueryDocument, "\n query MyAgreements($take: Int, $filterBy: [String!], $search: String, $skip: Int) {\n myAgreements(take: $take, filterBy: $filterBy, search: $search, skip: $skip) {\n agreements {\n agreementId\n title\n content\n isWaitingForMySignature\n createdAt\n agreementLocation {\n name\n isActive\n }\n agreementPrivacy {\n name\n }\n agreementFile {\n filePath\n createdAt\n }\n authorWallet {\n address\n user {\n name\n email\n phone\n twitterVerificationCode\n twitterVerificationSig\n bio\n }\n }\n signers {\n email\n wallet {\n address\n user {\n name\n }\n }\n }\n observers {\n email\n wallet {\n address\n user {\n name\n }\n }\n }\n agreementStatus {\n name\n }\n signProofs {\n cid\n signature\n }\n }\n count\n }\n }\n": types.MyAgreementsDocument, @@ -67,11 +68,15 @@ export function graphql(source: "\n mutation EditObservers($agreementId: Int, $ /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ -export function graphql(source: "\n mutation login($address: String!, $signature: String) {\n login(address: $address, signature: $signature) {\n message\n payload\n token\n }\n }\n"): (typeof documents)["\n mutation login($address: String!, $signature: String) {\n login(address: $address, signature: $signature) {\n message\n payload\n token\n }\n }\n"]; +export function graphql(source: "\n mutation login($address: String!, $email: String, $signature: String) {\n login(address: $address, email: $email, signature: $signature) {\n message\n payload\n token\n }\n }\n"): (typeof documents)["\n mutation login($address: String!, $email: String, $signature: String) {\n login(address: $address, email: $email, signature: $signature) {\n message\n payload\n token\n }\n }\n"]; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ export function graphql(source: "\n mutation Mutation {\n logout {\n message\n }\n }\n"): (typeof documents)["\n mutation Mutation {\n logout {\n message\n }\n }\n"]; +/** + * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. + */ +export function graphql(source: "\n mutation sendEmailVerificationLink(\n $email: String!\n $isSigner: Boolean!\n $agreementTitle: String!\n ) {\n sendEmailVerificationLink(email: $email, isSigner: $isSigner, agreementTitle: $agreementTitle)\n }\n"): (typeof documents)["\n mutation sendEmailVerificationLink(\n $email: String!\n $isSigner: Boolean!\n $agreementTitle: String!\n ) {\n sendEmailVerificationLink(email: $email, isSigner: $isSigner, agreementTitle: $agreementTitle)\n }\n"]; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ diff --git a/modules/graphql/gql/graphql.ts b/modules/graphql/gql/graphql.ts index d506890..2854edc 100644 --- a/modules/graphql/gql/graphql.ts +++ b/modules/graphql/gql/graphql.ts @@ -274,12 +274,12 @@ export type LogoutResponse = { export type Mutation = { __typename?: 'Mutation'; deleteAgreement: DeleteAgreementResponse; - editObservers?: Maybe; + editObservers?: Maybe; login: LoginResponse; logout: LogoutResponse; saveAgreement?: Maybe; - sendAgreementInvitation: SendAgreementInvitationResponseResponse; - sendEmailVerificationLink: User; + sendAgreementInvitation: SendAgreementInvitationResponse; + sendEmailVerificationLink: Scalars['Boolean']; sendSignedFileProofData?: Maybe; sendSignedSignProofData?: Maybe; setAgreementReadyToSign: SetAgreementReadyToSignResponse; @@ -326,6 +326,13 @@ export type MutationSendAgreementInvitationArgs = { }; +export type MutationSendEmailVerificationLinkArgs = { + agreementTitle: Scalars['String']; + email: Scalars['String']; + isSigner: Scalars['Boolean']; +}; + + export type MutationSendSignedFileProofDataArgs = { agreementId: Scalars['Int']; data: AgreementFileProofDataInput; @@ -509,8 +516,8 @@ export type QueryWalletsArgs = { search?: InputMaybe; }; -export type SendAgreementInvitationResponseResponse = { - __typename?: 'SendAgreementInvitationResponseResponse'; +export type SendAgreementInvitationResponse = { + __typename?: 'SendAgreementInvitationResponse'; message: Scalars['String']; }; @@ -629,10 +636,11 @@ export type EditObserversMutationVariables = Exact<{ }>; -export type EditObserversMutation = { __typename?: 'Mutation', editObservers?: { __typename?: 'SendAgreementInvitationResponseResponse', message: string } | null }; +export type EditObserversMutation = { __typename?: 'Mutation', editObservers?: { __typename?: 'SendAgreementInvitationResponse', message: string } | null }; export type LoginMutationVariables = Exact<{ address: Scalars['String']; + email?: InputMaybe; signature?: InputMaybe; }>; @@ -644,6 +652,15 @@ export type MutationMutationVariables = Exact<{ [key: string]: never; }>; export type MutationMutation = { __typename?: 'Mutation', logout: { __typename?: 'LogoutResponse', message: string } }; +export type SendEmailVerificationLinkMutationVariables = Exact<{ + email: Scalars['String']; + isSigner: Scalars['Boolean']; + agreementTitle: Scalars['String']; +}>; + + +export type SendEmailVerificationLinkMutation = { __typename?: 'Mutation', sendEmailVerificationLink: boolean }; + export type VerifyMyEmailMutationVariables = Exact<{ emailVerificationSalt: Scalars['String']; email: Scalars['String']; @@ -717,8 +734,9 @@ export const DeleteAgreementMutationDocument = {"kind":"Document","definitions": export const SendSignedFileProofDataDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"sendSignedFileProofData"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"data"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"AgreementFileProofDataInput"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"signature"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"agreementId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"sendSignedFileProofData"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"data"},"value":{"kind":"Variable","name":{"kind":"Name","value":"data"}}},{"kind":"Argument","name":{"kind":"Name","value":"signature"},"value":{"kind":"Variable","name":{"kind":"Name","value":"signature"}}},{"kind":"Argument","name":{"kind":"Name","value":"agreementId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"agreementId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"cid"}}]}}]}}]} as unknown as DocumentNode; export const SendSignedSignProofDataDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"sendSignedSignProofData"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"data"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"AgreementSignProofDataInput"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"signature"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"agreementId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"sendSignedSignProofData"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"data"},"value":{"kind":"Variable","name":{"kind":"Name","value":"data"}}},{"kind":"Argument","name":{"kind":"Name","value":"signature"},"value":{"kind":"Variable","name":{"kind":"Name","value":"signature"}}},{"kind":"Argument","name":{"kind":"Name","value":"agreementId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"agreementId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"cid"}}]}}]}}]} as unknown as DocumentNode; export const EditObserversDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"EditObservers"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"agreementId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"observers"}},"type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"editObservers"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"agreementId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"agreementId"}}},{"kind":"Argument","name":{"kind":"Name","value":"observers"},"value":{"kind":"Variable","name":{"kind":"Name","value":"observers"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]} as unknown as DocumentNode; -export const LoginDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"login"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"address"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"signature"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"login"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"address"},"value":{"kind":"Variable","name":{"kind":"Name","value":"address"}}},{"kind":"Argument","name":{"kind":"Name","value":"signature"},"value":{"kind":"Variable","name":{"kind":"Name","value":"signature"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}},{"kind":"Field","name":{"kind":"Name","value":"payload"}},{"kind":"Field","name":{"kind":"Name","value":"token"}}]}}]}}]} as unknown as DocumentNode; +export const LoginDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"login"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"address"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"email"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"signature"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"login"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"address"},"value":{"kind":"Variable","name":{"kind":"Name","value":"address"}}},{"kind":"Argument","name":{"kind":"Name","value":"email"},"value":{"kind":"Variable","name":{"kind":"Name","value":"email"}}},{"kind":"Argument","name":{"kind":"Name","value":"signature"},"value":{"kind":"Variable","name":{"kind":"Name","value":"signature"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}},{"kind":"Field","name":{"kind":"Name","value":"payload"}},{"kind":"Field","name":{"kind":"Name","value":"token"}}]}}]}}]} as unknown as DocumentNode; export const MutationDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"Mutation"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"logout"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"message"}}]}}]}}]} as unknown as DocumentNode; +export const SendEmailVerificationLinkDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"sendEmailVerificationLink"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"email"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"isSigner"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"agreementTitle"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"sendEmailVerificationLink"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"email"},"value":{"kind":"Variable","name":{"kind":"Name","value":"email"}}},{"kind":"Argument","name":{"kind":"Name","value":"isSigner"},"value":{"kind":"Variable","name":{"kind":"Name","value":"isSigner"}}},{"kind":"Argument","name":{"kind":"Name","value":"agreementTitle"},"value":{"kind":"Variable","name":{"kind":"Name","value":"agreementTitle"}}}]}]}}]} as unknown as DocumentNode; export const VerifyMyEmailDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"verifyMyEmail"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"emailVerificationSalt"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"email"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"verifyMyEmail"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"emailVerificationSalt"},"value":{"kind":"Variable","name":{"kind":"Name","value":"emailVerificationSalt"}}},{"kind":"Argument","name":{"kind":"Name","value":"email"},"value":{"kind":"Variable","name":{"kind":"Name","value":"email"}}}]}]}}]} as unknown as DocumentNode; export const QueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"Query"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"agreementId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"agreement"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"agreementId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"agreementId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"agreementId"}},{"kind":"Field","name":{"kind":"Name","value":"snapshotProposalUrl"}},{"kind":"Field","name":{"kind":"Name","value":"agreementFile"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"agreementFileId"}},{"kind":"Field","name":{"kind":"Name","value":"agreementHash"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"filePath"}}]}},{"kind":"Field","name":{"kind":"Name","value":"agreementLocation"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"agreementLocationId"}},{"kind":"Field","name":{"kind":"Name","value":"isActive"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"agreementPrivacy"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"agreementStatus"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"authorWallet"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"address"}},{"kind":"Field","name":{"kind":"Name","value":"networkId"}},{"kind":"Field","name":{"kind":"Name","value":"userId"}},{"kind":"Field","name":{"kind":"Name","value":"walletId"}}]}},{"kind":"Field","name":{"kind":"Name","value":"observers"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"observerId"}},{"kind":"Field","name":{"kind":"Name","value":"wallet"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"address"}}]}},{"kind":"Field","name":{"kind":"Name","value":"ens"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"signers"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"wallet"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"address"}}]}},{"kind":"Field","name":{"kind":"Name","value":"ens"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"content"}},{"kind":"Field","name":{"kind":"Name","value":"isWaitingForMySignature"}},{"kind":"Field","name":{"kind":"Name","value":"snapshotProposalUrl"}},{"kind":"Field","name":{"kind":"Name","value":"isAllowedToEditObservers"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"signProofs"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"signature"}},{"kind":"Field","name":{"kind":"Name","value":"cid"}},{"kind":"Field","name":{"kind":"Name","value":"signerWalletId"}},{"kind":"Field","name":{"kind":"Name","value":"signerWallet"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"address"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"agreementFileProof"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"cid"}},{"kind":"Field","name":{"kind":"Name","value":"signature"}},{"kind":"Field","name":{"kind":"Name","value":"signers"}}]}},{"kind":"Field","name":{"kind":"Name","value":"agreementProof"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"cid"}},{"kind":"Field","name":{"kind":"Name","value":"signedAt"}}]}}]}}]}}]} as unknown as DocumentNode; export const MyAgreementsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"MyAgreements"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"take"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"filterBy"}},"type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"search"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"skip"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"myAgreements"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"take"},"value":{"kind":"Variable","name":{"kind":"Name","value":"take"}}},{"kind":"Argument","name":{"kind":"Name","value":"filterBy"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filterBy"}}},{"kind":"Argument","name":{"kind":"Name","value":"search"},"value":{"kind":"Variable","name":{"kind":"Name","value":"search"}}},{"kind":"Argument","name":{"kind":"Name","value":"skip"},"value":{"kind":"Variable","name":{"kind":"Name","value":"skip"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"agreements"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"agreementId"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"content"}},{"kind":"Field","name":{"kind":"Name","value":"isWaitingForMySignature"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"agreementLocation"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"isActive"}}]}},{"kind":"Field","name":{"kind":"Name","value":"agreementPrivacy"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"agreementFile"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"filePath"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}}]}},{"kind":"Field","name":{"kind":"Name","value":"authorWallet"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"address"}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"phone"}},{"kind":"Field","name":{"kind":"Name","value":"twitterVerificationCode"}},{"kind":"Field","name":{"kind":"Name","value":"twitterVerificationSig"}},{"kind":"Field","name":{"kind":"Name","value":"bio"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"signers"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"wallet"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"address"}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"observers"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"wallet"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"address"}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"agreementStatus"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"signProofs"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"cid"}},{"kind":"Field","name":{"kind":"Name","value":"signature"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"count"}}]}}]}}]} as unknown as DocumentNode; diff --git a/modules/graphql/mutations/user.ts b/modules/graphql/mutations/user.ts index fe3e04e..ae93e28 100644 --- a/modules/graphql/mutations/user.ts +++ b/modules/graphql/mutations/user.ts @@ -1,8 +1,8 @@ import { graphql } from "../gql"; export const loginMutation = graphql(` - mutation login($address: String!, $signature: String) { - login(address: $address, signature: $signature) { + mutation login($address: String!, $email: String, $signature: String) { + login(address: $address, email: $email, signature: $signature) { message payload token @@ -18,6 +18,16 @@ export const logoutMutation = graphql(` } `); +export const sendEmailVerificationLinkMutation = graphql(` + mutation sendEmailVerificationLink( + $email: String! + $isSigner: Boolean! + $agreementTitle: String! + ) { + sendEmailVerificationLink(email: $email, isSigner: $isSigner, agreementTitle: $agreementTitle) + } +`); + export const verifyMyEmailMutation = graphql(` mutation verifyMyEmail($emailVerificationSalt: String!, $email: String!) { verifyMyEmail(emailVerificationSalt: $emailVerificationSalt, email: $email)
Signer NameSigner AddressNameAddress/Email/ENS Signature status Proof of signature