Compare commits

..

5 Commits

Author SHA1 Message Date
anik-ghosh-au7
ecefe12355 chore: format graphql schema 2022-11-15 22:39:04 +05:30
anik-ghosh-au7
5c8f9406f6 fix: email template resolver and for matting changes 2022-11-15 22:12:14 +05:30
anik-ghosh-au7
ae84213e34 fix: allow design variable empty value for email templates 2022-11-09 22:54:05 +05:30
anik-ghosh-au7
87bf1c3045 fix: allow design variable empty value for email templates 2022-11-09 22:48:12 +05:30
anik-ghosh-au7
b467e7002d feat: add plain html email template editor 2022-11-09 22:17:41 +05:30
12 changed files with 588 additions and 1543 deletions

View File

@@ -2,45 +2,36 @@ on:
workflow_dispatch: workflow_dispatch:
inputs: inputs:
logLevel: logLevel:
description: "Log level" description: 'Log level'
required: true required: true
default: "warning" default: 'warning'
type: choice type: choice
options: options:
- info - info
- warning - warning
- debug - debug
tags: tags:
description: "Tags" description: 'Tags'
required: false required: false
type: boolean type: boolean
release: release:
types: [created] types: [created]
jobs: jobs:
releases: releases:
name: Release Authorizer name: Release Authorizer Binary
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v2
- uses: actions/setup-node@v2 - uses: actions/setup-node@v2
with: with:
node-version: "16" node-version: '16'
- # Add support for more platforms with QEMU (optional)
# https://github.com/docker/setup-qemu-action
name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
with:
platforms: linux/amd64,linux/arm64
buildkitd-flags: --debug
- uses: actions/setup-go@v2 - uses: actions/setup-go@v2
with: with:
go-version: "^1.17.3" go-version: '^1.17.3'
- name: Install dependencies - name: Install dependencies
run: | run: |
sudo apt-get install build-essential wget zip gcc-multilib gcc-mingw-w64 gcc-9-aarch64-linux-gnu gcc-aarch64-linux-gnu libc6-dev-arm64-cross && \ sudo apt-get install build-essential wget zip gcc-mingw-w64 && \
echo "/usr/bin/x86_64-w64-mingw32-gcc" >> GITHUB_PATH && \ echo "/usr/bin/x86_64-w64-mingw32-gcc" >> GITHUB_PATH && \
wget --no-check-certificate --progress=dot:mega https://github.com/wangyoucao577/assets-uploader/releases/download/v0.3.0/github-assets-uploader-v0.3.0-linux-amd64.tar.gz -O github-assets-uploader.tar.gz && \ wget --no-check-certificate --progress=dot:mega https://github.com/wangyoucao577/assets-uploader/releases/download/v0.3.0/github-assets-uploader-v0.3.0-linux-amd64.tar.gz -O github-assets-uploader.tar.gz && \
tar -zxf github-assets-uploader.tar.gz && \ tar -zxf github-assets-uploader.tar.gz && \
@@ -53,20 +44,25 @@ jobs:
run: whereis go run: whereis go
- name: Print Go Version - name: Print Go Version
run: go version run: go version
- name: Install gox
run: go install github.com/mitchellh/gox@latest
- name: Set VERSION env - name: Set VERSION env
run: echo VERSION=$(basename ${GITHUB_REF}) >> ${GITHUB_ENV} run: echo VERSION=$(basename ${GITHUB_REF}) >> ${GITHUB_ENV}
- name: Copy .env file - name: Copy .env file
run: mv .env.sample .env run: mv .env.sample .env
- name: Build package - name: Package files for windows
run: | run: |
make clean && \ make clean && \
make build && \ CGO_ENABLED=1 GOOS=windows CC=/usr/bin/x86_64-w64-mingw32-gcc make && \
mkdir -p authorizer-${VERSION}-darwin-amd64/build authorizer-${VERSION}-darwin-amd64/app authorizer-${VERSION}-darwin-amd64/templates authorizer-${VERSION}-darwin-amd64/dashboard && cp build/darwin/amd64/server authorizer-${VERSION}-darwin-amd64/build/ && cp .env authorizer-${VERSION}-darwin-amd64/.env && cp -rf app/build authorizer-${VERSION}-darwin-amd64/app/build && cp -rf templates authorizer-${VERSION}-darwin-amd64/templates && cp -rf dashboard/build authorizer-${VERSION}-darwin-amd64/dashboard/build && tar cvfz authorizer-${VERSION}-darwin-amd64.tar.gz authorizer-${VERSION}-darwin-amd64 mv build/server build/server.exe && \
zip -vr authorizer-${VERSION}-windows-amd64.zip .env app/build build templates dashboard/build
- name: Package files for linux
run: |
make clean && \
CGO_ENABLED=1 make && \
tar cvfz authorizer-${VERSION}-linux-amd64.tar.gz .env app/build build templates dashboard/build
- name: Upload assets - name: Upload assets
run: | run: |
github-assets-uploader -f authorizer-${VERSION}-darwin-amd64.tar.gz -mediatype application/gzip -repo authorizerdev/authorizer -token ${{secrets.RELEASE_TOKEN}} -tag ${VERSION} github-assets-uploader -f authorizer-${VERSION}-windows-amd64.zip -mediatype application/zip -repo authorizerdev/authorizer -token ${{secrets.RELEASE_TOKEN}} -tag ${VERSION} && \
github-assets-uploader -f authorizer-${VERSION}-linux-amd64.tar.gz -mediatype application/gzip -repo authorizerdev/authorizer -token ${{secrets.RELEASE_TOKEN}} -tag ${VERSION}
- name: Log in to Docker Hub - name: Log in to Docker Hub
uses: docker/login-action@v1 uses: docker/login-action@v1
with: with:
@@ -78,9 +74,6 @@ jobs:
uses: docker/metadata-action@v3 uses: docker/metadata-action@v3
with: with:
images: lakhansamani/authorizer images: lakhansamani/authorizer
tags: |
# set latest tag for default branch
type=raw,value=latest,enable={{is_default_branch}}
- name: Build and push Docker image - name: Build and push Docker image
uses: docker/build-push-action@v2 uses: docker/build-push-action@v2

View File

@@ -3,12 +3,6 @@ VERSION := $(or $(VERSION),$(DEFAULT_VERSION))
cmd: cmd:
cd server && go build -ldflags "-w -X main.VERSION=$(VERSION)" -o '../build/server' cd server && go build -ldflags "-w -X main.VERSION=$(VERSION)" -o '../build/server'
build:
cd server && gox -cgo \
-osarch="linux/amd64 linux/arm64 darwin/amd64 windows/386 windows/amd64" \
-ldflags "-w -X main.VERSION=$(VERSION)" \
-output="../build/{{.OS}}/{{.Arch}}/server" \
./...
build-app: build-app:
cd app && npm i && npm run build cd app && npm i && npm run build
build-dashboard: build-dashboard:

File diff suppressed because it is too large Load Diff

View File

@@ -29,6 +29,10 @@ import {
Tbody, Tbody,
Td, Td,
Code, Code,
Radio,
RadioGroup,
Stack,
Textarea,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { FaPlus, FaAngleDown, FaAngleUp } from 'react-icons/fa'; import { FaPlus, FaAngleDown, FaAngleUp } from 'react-icons/fa';
import { useClient } from 'urql'; import { useClient } from 'urql';
@@ -38,6 +42,7 @@ import {
EmailTemplateInputDataFields, EmailTemplateInputDataFields,
emailTemplateEventNames, emailTemplateEventNames,
emailTemplateVariables, emailTemplateVariables,
EmailTemplateEditors,
} from '../constants'; } from '../constants';
import { capitalizeFirstLetter } from '../utils'; import { capitalizeFirstLetter } from '../utils';
import { AddEmailTemplate, EditEmailTemplate } from '../graphql/mutation'; import { AddEmailTemplate, EditEmailTemplate } from '../graphql/mutation';
@@ -66,6 +71,8 @@ interface templateVariableDataTypes {
interface emailTemplateDataType { interface emailTemplateDataType {
[EmailTemplateInputDataFields.EVENT_NAME]: string; [EmailTemplateInputDataFields.EVENT_NAME]: string;
[EmailTemplateInputDataFields.SUBJECT]: string; [EmailTemplateInputDataFields.SUBJECT]: string;
[EmailTemplateInputDataFields.TEMPLATE]: string;
[EmailTemplateInputDataFields.DESIGN]: string;
} }
interface validatorDataType { interface validatorDataType {
@@ -75,6 +82,8 @@ interface validatorDataType {
const initTemplateData: emailTemplateDataType = { const initTemplateData: emailTemplateDataType = {
[EmailTemplateInputDataFields.EVENT_NAME]: emailTemplateEventNames.Signup, [EmailTemplateInputDataFields.EVENT_NAME]: emailTemplateEventNames.Signup,
[EmailTemplateInputDataFields.SUBJECT]: '', [EmailTemplateInputDataFields.SUBJECT]: '',
[EmailTemplateInputDataFields.TEMPLATE]: '',
[EmailTemplateInputDataFields.DESIGN]: '',
}; };
const initTemplateValidatorData: validatorDataType = { const initTemplateValidatorData: validatorDataType = {
@@ -91,6 +100,9 @@ const UpdateEmailTemplate = ({
const emailEditorRef = useRef(null); const emailEditorRef = useRef(null);
const { isOpen, onOpen, onClose } = useDisclosure(); const { isOpen, onOpen, onClose } = useDisclosure();
const [loading, setLoading] = useState<boolean>(false); const [loading, setLoading] = useState<boolean>(false);
const [editor, setEditor] = useState<string>(
EmailTemplateEditors.PLAIN_HTML_EDITOR,
);
const [templateVariables, setTemplateVariables] = useState< const [templateVariables, setTemplateVariables] = useState<
templateVariableDataTypes[] templateVariableDataTypes[]
>([]); >([]);
@@ -107,9 +119,11 @@ const UpdateEmailTemplate = ({
if (selectedTemplate) { if (selectedTemplate) {
const { design } = selectedTemplate; const { design } = selectedTemplate;
try { try {
const designData = JSON.parse(design); if (design) {
// @ts-ignore const designData = JSON.parse(design);
emailEditorRef.current.editor.loadDesign(designData); // @ts-ignore
emailEditorRef.current.editor.loadDesign(designData);
}
} catch (error) { } catch (error) {
console.error(error); console.error(error);
onClose(); onClose();
@@ -136,70 +150,85 @@ const UpdateEmailTemplate = ({
); );
}; };
const updateTemplate = async (params: emailTemplateDataType) => {
let res: any = {};
if (
view === UpdateModalViews.Edit &&
selectedTemplate?.[EmailTemplateInputDataFields.ID]
) {
res = await client
.mutation(EditEmailTemplate, {
params: {
...params,
id: selectedTemplate[EmailTemplateInputDataFields.ID],
},
})
.toPromise();
} else {
res = await client.mutation(AddEmailTemplate, { params }).toPromise();
}
setLoading(false);
if (res.error) {
toast({
title: capitalizeFirstLetter(res.error.message),
isClosable: true,
status: 'error',
position: 'bottom-right',
});
} else if (
res.data?._add_email_template ||
res.data?._update_email_template
) {
toast({
title: capitalizeFirstLetter(
res.data?._add_email_template?.message ||
res.data?._update_email_template?.message,
),
isClosable: true,
status: 'success',
position: 'bottom-right',
});
setTemplateData({
...initTemplateData,
});
setValidator({ ...initTemplateValidatorData });
fetchEmailTemplatesData();
}
};
const saveData = async () => { const saveData = async () => {
if (!validateData()) return; if (!validateData()) return;
setLoading(true); setLoading(true);
// @ts-ignore let params: emailTemplateDataType = {
return await emailEditorRef.current.editor.exportHtml(async (data) => { [EmailTemplateInputDataFields.EVENT_NAME]:
const { design, html } = data; templateData[EmailTemplateInputDataFields.EVENT_NAME],
if (!html || !design) { [EmailTemplateInputDataFields.SUBJECT]:
setLoading(false); templateData[EmailTemplateInputDataFields.SUBJECT],
return; [EmailTemplateInputDataFields.TEMPLATE]:
} templateData[EmailTemplateInputDataFields.TEMPLATE],
const params = { [EmailTemplateInputDataFields.DESIGN]: '',
[EmailTemplateInputDataFields.EVENT_NAME]: };
templateData[EmailTemplateInputDataFields.EVENT_NAME], if (editor === EmailTemplateEditors.UNLAYER_EDITOR) {
[EmailTemplateInputDataFields.SUBJECT]: // @ts-ignore
templateData[EmailTemplateInputDataFields.SUBJECT], await emailEditorRef.current.editor.exportHtml(async (data) => {
[EmailTemplateInputDataFields.TEMPLATE]: html.trim(), const { design, html } = data;
[EmailTemplateInputDataFields.DESIGN]: JSON.stringify(design), if (!html || !design) {
}; setLoading(false);
let res: any = {}; return;
if ( }
view === UpdateModalViews.Edit && params = {
selectedTemplate?.[EmailTemplateInputDataFields.ID] ...params,
) { [EmailTemplateInputDataFields.TEMPLATE]: html.trim(),
res = await client [EmailTemplateInputDataFields.DESIGN]: JSON.stringify(design),
.mutation(EditEmailTemplate, { };
params: { await updateTemplate(params);
...params, });
id: selectedTemplate[EmailTemplateInputDataFields.ID], } else {
}, await updateTemplate(params);
}) }
.toPromise(); view === UpdateModalViews.ADD && onClose();
} else {
res = await client.mutation(AddEmailTemplate, { params }).toPromise();
}
setLoading(false);
if (res.error) {
toast({
title: capitalizeFirstLetter(res.error.message),
isClosable: true,
status: 'error',
position: 'bottom-right',
});
} else if (
res.data?._add_email_template ||
res.data?._update_email_template
) {
toast({
title: capitalizeFirstLetter(
res.data?._add_email_template?.message ||
res.data?._update_email_template?.message,
),
isClosable: true,
status: 'success',
position: 'bottom-right',
});
setTemplateData({
...initTemplateData,
});
setValidator({ ...initTemplateValidatorData });
fetchEmailTemplatesData();
}
view === UpdateModalViews.ADD && onClose();
});
}; };
const resetData = () => { const resetData = () => {
if (selectedTemplate) { if (selectedTemplate) {
setTemplateData(selectedTemplate); setTemplateData(selectedTemplate);
@@ -207,6 +236,8 @@ const UpdateEmailTemplate = ({
setTemplateData({ ...initTemplateData }); setTemplateData({ ...initTemplateData });
} }
}; };
// set template data if edit modal is open
useEffect(() => { useEffect(() => {
if ( if (
isOpen && isOpen &&
@@ -214,10 +245,12 @@ const UpdateEmailTemplate = ({
selectedTemplate && selectedTemplate &&
Object.keys(selectedTemplate || {}).length Object.keys(selectedTemplate || {}).length
) { ) {
const { id, created_at, template, design, ...rest } = selectedTemplate; const { id, created_at, ...rest } = selectedTemplate;
setTemplateData(rest); setTemplateData(rest);
} }
}, [isOpen]); }, [isOpen]);
// set template variables
useEffect(() => { useEffect(() => {
const updatedTemplateVariables = Object.entries( const updatedTemplateVariables = Object.entries(
emailTemplateVariables, emailTemplateVariables,
@@ -244,6 +277,51 @@ const UpdateEmailTemplate = ({
setTemplateVariables(updatedTemplateVariables); setTemplateVariables(updatedTemplateVariables);
}, [templateData[EmailTemplateInputDataFields.EVENT_NAME]]); }, [templateData[EmailTemplateInputDataFields.EVENT_NAME]]);
// change editor
useEffect(() => {
if (isOpen && selectedTemplate) {
const { design } = selectedTemplate;
if (design) {
setEditor(EmailTemplateEditors.UNLAYER_EDITOR);
} else {
setEditor(EmailTemplateEditors.PLAIN_HTML_EDITOR);
}
}
}, [isOpen, selectedTemplate]);
// reset fields when editor is changed
useEffect(() => {
if (selectedTemplate?.design) {
if (editor === EmailTemplateEditors.UNLAYER_EDITOR) {
setTemplateData({
...templateData,
[EmailTemplateInputDataFields.TEMPLATE]: selectedTemplate.template,
[EmailTemplateInputDataFields.DESIGN]: selectedTemplate.design,
});
} else {
setTemplateData({
...templateData,
[EmailTemplateInputDataFields.TEMPLATE]: '',
[EmailTemplateInputDataFields.DESIGN]: '',
});
}
} else if (selectedTemplate?.template) {
if (editor === EmailTemplateEditors.UNLAYER_EDITOR) {
setTemplateData({
...templateData,
[EmailTemplateInputDataFields.TEMPLATE]: '',
[EmailTemplateInputDataFields.DESIGN]: '',
});
} else {
setTemplateData({
...templateData,
[EmailTemplateInputDataFields.TEMPLATE]: selectedTemplate?.template,
[EmailTemplateInputDataFields.DESIGN]: '',
});
}
}
}, [editor]);
return ( return (
<> <>
{view === UpdateModalViews.ADD ? ( {view === UpdateModalViews.ADD ? (
@@ -414,7 +492,22 @@ const UpdateEmailTemplate = ({
alignItems="center" alignItems="center"
marginBottom="2%" marginBottom="2%"
> >
Template Body <Flex flex="1">Template Body</Flex>
<Flex flex="3">
<RadioGroup
onChange={(value) => setEditor(value)}
value={editor}
>
<Stack direction="row" spacing="50px">
<Radio value={EmailTemplateEditors.PLAIN_HTML_EDITOR}>
Plain HTML
</Radio>
<Radio value={EmailTemplateEditors.UNLAYER_EDITOR}>
Unlayer Editor
</Radio>
</Stack>
</RadioGroup>
</Flex>
</Flex> </Flex>
<Flex <Flex
width="100%" width="100%"
@@ -423,7 +516,22 @@ const UpdateEmailTemplate = ({
border="1px solid" border="1px solid"
borderColor="gray.200" borderColor="gray.200"
> >
<EmailEditor ref={emailEditorRef} onReady={onReady} /> {editor === EmailTemplateEditors.UNLAYER_EDITOR ? (
<EmailEditor ref={emailEditorRef} onReady={onReady} />
) : (
<Textarea
value={templateData.template}
onChange={(e) => {
setTemplateData({
...templateData,
[EmailTemplateInputDataFields.TEMPLATE]: e.target.value,
});
}}
placeholder="Template HTML"
border="0"
height="500px"
/>
)}
</Flex> </Flex>
</Flex> </Flex>
</ModalBody> </ModalBody>

View File

@@ -337,3 +337,8 @@ export const webhookPayloadExample: string = `{
}, },
"auth_recipe":"google" "auth_recipe":"google"
}`; }`;
export enum EmailTemplateEditors {
UNLAYER_EDITOR = 'unlayer_editor',
PLAIN_HTML_EDITOR = 'plain_html_editor',
}

View File

@@ -17,7 +17,6 @@ require (
github.com/google/uuid v1.3.0 github.com/google/uuid v1.3.0
github.com/guregu/dynamo v1.16.0 github.com/guregu/dynamo v1.16.0
github.com/joho/godotenv v1.3.0 github.com/joho/godotenv v1.3.0
github.com/mitchellh/gox v1.0.1 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/pelletier/go-toml/v2 v2.0.5 // indirect github.com/pelletier/go-toml/v2 v2.0.5 // indirect
github.com/robertkrimen/otto v0.0.0-20211024170158-b87d35c0b86f github.com/robertkrimen/otto v0.0.0-20211024170158-b87d35c0b86f

View File

@@ -195,8 +195,6 @@ github.com/guregu/dynamo v1.16.0 h1:gmI8oi1VHwYQtq7+RPBeOiSssVLgxH/Az2t+NtDtL2c=
github.com/guregu/dynamo v1.16.0/go.mod h1:W2Gqcf3MtkrS+Q6fHPGAmRtT0Dyq+TGrqfqrUC9+R/c= github.com/guregu/dynamo v1.16.0/go.mod h1:W2Gqcf3MtkrS+Q6fHPGAmRtT0Dyq+TGrqfqrUC9+R/c=
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8= github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8=
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4=
github.com/hashicorp/go-version v1.0.0 h1:21MVWPKDphxa7ineQQTrCU5brh7OuVVAzGOCnnCPtE8=
github.com/hashicorp/go-version v1.0.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
@@ -302,10 +300,6 @@ github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peK
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-sqlite3 v1.14.9 h1:10HX2Td0ocZpYEjhilsuo6WWtUqttj2Kb0KtD86/KYA= github.com/mattn/go-sqlite3 v1.14.9 h1:10HX2Td0ocZpYEjhilsuo6WWtUqttj2Kb0KtD86/KYA=
github.com/mattn/go-sqlite3 v1.14.9/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-sqlite3 v1.14.9/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/mitchellh/gox v1.0.1 h1:x0jD3dcHk9a9xPSDN6YEL4xL6Qz0dvNYm8yZqui5chI=
github.com/mitchellh/gox v1.0.1/go.mod h1:ED6BioOGXMswlXa2zxfh/xdd5QhwYliBFn9V18Ap4z4=
github.com/mitchellh/iochan v1.0.0 h1:C+X3KsSTLFVBr/tK1eYN/vs4rJcvsiLU338UhYPJWeY=
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
github.com/mitchellh/mapstructure v1.3.1 h1:cCBH2gTD2K0OtLlv/Y5H01VQCqmlDxz30kS5Y5bqfLA= github.com/mitchellh/mapstructure v1.3.1 h1:cCBH2gTD2K0OtLlv/Y5H01VQCqmlDxz30kS5Y5bqfLA=
github.com/mitchellh/mapstructure v1.3.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.3.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=

View File

@@ -1971,501 +1971,501 @@ scalar Map
scalar Any scalar Any
type Pagination { type Pagination {
limit: Int64! limit: Int64!
page: Int64! page: Int64!
offset: Int64! offset: Int64!
total: Int64! total: Int64!
} }
type Meta { type Meta {
version: String! version: String!
client_id: String! client_id: String!
is_google_login_enabled: Boolean! is_google_login_enabled: Boolean!
is_facebook_login_enabled: Boolean! is_facebook_login_enabled: Boolean!
is_github_login_enabled: Boolean! is_github_login_enabled: Boolean!
is_linkedin_login_enabled: Boolean! is_linkedin_login_enabled: Boolean!
is_apple_login_enabled: Boolean! is_apple_login_enabled: Boolean!
is_twitter_login_enabled: Boolean! is_twitter_login_enabled: Boolean!
is_email_verification_enabled: Boolean! is_email_verification_enabled: Boolean!
is_basic_authentication_enabled: Boolean! is_basic_authentication_enabled: Boolean!
is_magic_link_login_enabled: Boolean! is_magic_link_login_enabled: Boolean!
is_sign_up_enabled: Boolean! is_sign_up_enabled: Boolean!
is_strong_password_enabled: Boolean! is_strong_password_enabled: Boolean!
is_multi_factor_auth_enabled: Boolean! is_multi_factor_auth_enabled: Boolean!
} }
type User { type User {
id: ID! id: ID!
email: String! email: String!
email_verified: Boolean! email_verified: Boolean!
signup_methods: String! signup_methods: String!
given_name: String given_name: String
family_name: String family_name: String
middle_name: String middle_name: String
nickname: String nickname: String
# defaults to email # defaults to email
preferred_username: String preferred_username: String
gender: String gender: String
birthdate: String birthdate: String
phone_number: String phone_number: String
phone_number_verified: Boolean phone_number_verified: Boolean
picture: String picture: String
roles: [String!]! roles: [String!]!
created_at: Int64 created_at: Int64
updated_at: Int64 updated_at: Int64
revoked_timestamp: Int64 revoked_timestamp: Int64
is_multi_factor_auth_enabled: Boolean is_multi_factor_auth_enabled: Boolean
} }
type Users { type Users {
pagination: Pagination! pagination: Pagination!
users: [User!]! users: [User!]!
} }
type VerificationRequest { type VerificationRequest {
id: ID! id: ID!
identifier: String identifier: String
token: String token: String
email: String email: String
expires: Int64 expires: Int64
created_at: Int64 created_at: Int64
updated_at: Int64 updated_at: Int64
nonce: String nonce: String
redirect_uri: String redirect_uri: String
} }
type VerificationRequests { type VerificationRequests {
pagination: Pagination! pagination: Pagination!
verification_requests: [VerificationRequest!]! verification_requests: [VerificationRequest!]!
} }
type Error { type Error {
message: String! message: String!
reason: String! reason: String!
} }
type AuthResponse { type AuthResponse {
message: String! message: String!
should_show_otp_screen: Boolean should_show_otp_screen: Boolean
access_token: String access_token: String
id_token: String id_token: String
refresh_token: String refresh_token: String
expires_in: Int64 expires_in: Int64
user: User user: User
} }
type Response { type Response {
message: String! message: String!
} }
type Env { type Env {
ACCESS_TOKEN_EXPIRY_TIME: String ACCESS_TOKEN_EXPIRY_TIME: String
ADMIN_SECRET: String ADMIN_SECRET: String
DATABASE_NAME: String DATABASE_NAME: String
DATABASE_URL: String DATABASE_URL: String
DATABASE_TYPE: String DATABASE_TYPE: String
DATABASE_USERNAME: String DATABASE_USERNAME: String
DATABASE_PASSWORD: String DATABASE_PASSWORD: String
DATABASE_HOST: String DATABASE_HOST: String
DATABASE_PORT: String DATABASE_PORT: String
CLIENT_ID: String! CLIENT_ID: String!
CLIENT_SECRET: String! CLIENT_SECRET: String!
CUSTOM_ACCESS_TOKEN_SCRIPT: String CUSTOM_ACCESS_TOKEN_SCRIPT: String
SMTP_HOST: String SMTP_HOST: String
SMTP_PORT: String SMTP_PORT: String
SMTP_USERNAME: String SMTP_USERNAME: String
SMTP_PASSWORD: String SMTP_PASSWORD: String
SMTP_LOCAL_NAME: String SMTP_LOCAL_NAME: String
SENDER_EMAIL: String SENDER_EMAIL: String
JWT_TYPE: String JWT_TYPE: String
JWT_SECRET: String JWT_SECRET: String
JWT_PRIVATE_KEY: String JWT_PRIVATE_KEY: String
JWT_PUBLIC_KEY: String JWT_PUBLIC_KEY: String
ALLOWED_ORIGINS: [String!] ALLOWED_ORIGINS: [String!]
APP_URL: String APP_URL: String
REDIS_URL: String REDIS_URL: String
RESET_PASSWORD_URL: String RESET_PASSWORD_URL: String
DISABLE_EMAIL_VERIFICATION: Boolean! DISABLE_EMAIL_VERIFICATION: Boolean!
DISABLE_BASIC_AUTHENTICATION: Boolean! DISABLE_BASIC_AUTHENTICATION: Boolean!
DISABLE_MAGIC_LINK_LOGIN: Boolean! DISABLE_MAGIC_LINK_LOGIN: Boolean!
DISABLE_LOGIN_PAGE: Boolean! DISABLE_LOGIN_PAGE: Boolean!
DISABLE_SIGN_UP: Boolean! DISABLE_SIGN_UP: Boolean!
DISABLE_REDIS_FOR_ENV: Boolean! DISABLE_REDIS_FOR_ENV: Boolean!
DISABLE_STRONG_PASSWORD: Boolean! DISABLE_STRONG_PASSWORD: Boolean!
DISABLE_MULTI_FACTOR_AUTHENTICATION: Boolean! DISABLE_MULTI_FACTOR_AUTHENTICATION: Boolean!
ENFORCE_MULTI_FACTOR_AUTHENTICATION: Boolean! ENFORCE_MULTI_FACTOR_AUTHENTICATION: Boolean!
ROLES: [String!] ROLES: [String!]
PROTECTED_ROLES: [String!] PROTECTED_ROLES: [String!]
DEFAULT_ROLES: [String!] DEFAULT_ROLES: [String!]
JWT_ROLE_CLAIM: String JWT_ROLE_CLAIM: String
GOOGLE_CLIENT_ID: String GOOGLE_CLIENT_ID: String
GOOGLE_CLIENT_SECRET: String GOOGLE_CLIENT_SECRET: String
GITHUB_CLIENT_ID: String GITHUB_CLIENT_ID: String
GITHUB_CLIENT_SECRET: String GITHUB_CLIENT_SECRET: String
FACEBOOK_CLIENT_ID: String FACEBOOK_CLIENT_ID: String
FACEBOOK_CLIENT_SECRET: String FACEBOOK_CLIENT_SECRET: String
LINKEDIN_CLIENT_ID: String LINKEDIN_CLIENT_ID: String
LINKEDIN_CLIENT_SECRET: String LINKEDIN_CLIENT_SECRET: String
APPLE_CLIENT_ID: String APPLE_CLIENT_ID: String
APPLE_CLIENT_SECRET: String APPLE_CLIENT_SECRET: String
TWITTER_CLIENT_ID: String TWITTER_CLIENT_ID: String
TWITTER_CLIENT_SECRET: String TWITTER_CLIENT_SECRET: String
ORGANIZATION_NAME: String ORGANIZATION_NAME: String
ORGANIZATION_LOGO: String ORGANIZATION_LOGO: String
APP_COOKIE_SECURE: Boolean! APP_COOKIE_SECURE: Boolean!
ADMIN_COOKIE_SECURE: Boolean! ADMIN_COOKIE_SECURE: Boolean!
} }
type ValidateJWTTokenResponse { type ValidateJWTTokenResponse {
is_valid: Boolean! is_valid: Boolean!
claims: Map claims: Map
} }
type GenerateJWTKeysResponse { type GenerateJWTKeysResponse {
secret: String secret: String
public_key: String public_key: String
private_key: String private_key: String
} }
type Webhook { type Webhook {
id: ID! id: ID!
event_name: String event_name: String
endpoint: String endpoint: String
enabled: Boolean enabled: Boolean
headers: Map headers: Map
created_at: Int64 created_at: Int64
updated_at: Int64 updated_at: Int64
} }
type Webhooks { type Webhooks {
pagination: Pagination! pagination: Pagination!
webhooks: [Webhook!]! webhooks: [Webhook!]!
} }
type WebhookLog { type WebhookLog {
id: ID! id: ID!
http_status: Int64 http_status: Int64
response: String response: String
request: String request: String
webhook_id: ID webhook_id: ID
created_at: Int64 created_at: Int64
updated_at: Int64 updated_at: Int64
} }
type TestEndpointResponse { type TestEndpointResponse {
http_status: Int64 http_status: Int64
response: String response: String
} }
type WebhookLogs { type WebhookLogs {
pagination: Pagination! pagination: Pagination!
webhook_logs: [WebhookLog!]! webhook_logs: [WebhookLog!]!
} }
type EmailTemplate { type EmailTemplate {
id: ID! id: ID!
event_name: String! event_name: String!
template: String! template: String!
design: String! design: String!
subject: String! subject: String!
created_at: Int64 created_at: Int64
updated_at: Int64 updated_at: Int64
} }
type EmailTemplates { type EmailTemplates {
pagination: Pagination! pagination: Pagination!
email_templates: [EmailTemplate!]! email_templates: [EmailTemplate!]!
} }
input UpdateEnvInput { input UpdateEnvInput {
ACCESS_TOKEN_EXPIRY_TIME: String ACCESS_TOKEN_EXPIRY_TIME: String
ADMIN_SECRET: String ADMIN_SECRET: String
CUSTOM_ACCESS_TOKEN_SCRIPT: String CUSTOM_ACCESS_TOKEN_SCRIPT: String
OLD_ADMIN_SECRET: String OLD_ADMIN_SECRET: String
SMTP_HOST: String SMTP_HOST: String
SMTP_PORT: String SMTP_PORT: String
SMTP_USERNAME: String SMTP_USERNAME: String
SMTP_PASSWORD: String SMTP_PASSWORD: String
SMTP_LOCAL_NAME: String SMTP_LOCAL_NAME: String
SENDER_EMAIL: String SENDER_EMAIL: String
JWT_TYPE: String JWT_TYPE: String
JWT_SECRET: String JWT_SECRET: String
JWT_PRIVATE_KEY: String JWT_PRIVATE_KEY: String
JWT_PUBLIC_KEY: String JWT_PUBLIC_KEY: String
ALLOWED_ORIGINS: [String!] ALLOWED_ORIGINS: [String!]
APP_URL: String APP_URL: String
RESET_PASSWORD_URL: String RESET_PASSWORD_URL: String
APP_COOKIE_SECURE: Boolean APP_COOKIE_SECURE: Boolean
ADMIN_COOKIE_SECURE: Boolean ADMIN_COOKIE_SECURE: Boolean
DISABLE_EMAIL_VERIFICATION: Boolean DISABLE_EMAIL_VERIFICATION: Boolean
DISABLE_BASIC_AUTHENTICATION: Boolean DISABLE_BASIC_AUTHENTICATION: Boolean
DISABLE_MAGIC_LINK_LOGIN: Boolean DISABLE_MAGIC_LINK_LOGIN: Boolean
DISABLE_LOGIN_PAGE: Boolean DISABLE_LOGIN_PAGE: Boolean
DISABLE_SIGN_UP: Boolean DISABLE_SIGN_UP: Boolean
DISABLE_REDIS_FOR_ENV: Boolean DISABLE_REDIS_FOR_ENV: Boolean
DISABLE_STRONG_PASSWORD: Boolean DISABLE_STRONG_PASSWORD: Boolean
DISABLE_MULTI_FACTOR_AUTHENTICATION: Boolean DISABLE_MULTI_FACTOR_AUTHENTICATION: Boolean
ENFORCE_MULTI_FACTOR_AUTHENTICATION: Boolean ENFORCE_MULTI_FACTOR_AUTHENTICATION: Boolean
ROLES: [String!] ROLES: [String!]
PROTECTED_ROLES: [String!] PROTECTED_ROLES: [String!]
DEFAULT_ROLES: [String!] DEFAULT_ROLES: [String!]
JWT_ROLE_CLAIM: String JWT_ROLE_CLAIM: String
GOOGLE_CLIENT_ID: String GOOGLE_CLIENT_ID: String
GOOGLE_CLIENT_SECRET: String GOOGLE_CLIENT_SECRET: String
GITHUB_CLIENT_ID: String GITHUB_CLIENT_ID: String
GITHUB_CLIENT_SECRET: String GITHUB_CLIENT_SECRET: String
FACEBOOK_CLIENT_ID: String FACEBOOK_CLIENT_ID: String
FACEBOOK_CLIENT_SECRET: String FACEBOOK_CLIENT_SECRET: String
LINKEDIN_CLIENT_ID: String LINKEDIN_CLIENT_ID: String
LINKEDIN_CLIENT_SECRET: String LINKEDIN_CLIENT_SECRET: String
APPLE_CLIENT_ID: String APPLE_CLIENT_ID: String
APPLE_CLIENT_SECRET: String APPLE_CLIENT_SECRET: String
TWITTER_CLIENT_ID: String TWITTER_CLIENT_ID: String
TWITTER_CLIENT_SECRET: String TWITTER_CLIENT_SECRET: String
ORGANIZATION_NAME: String ORGANIZATION_NAME: String
ORGANIZATION_LOGO: String ORGANIZATION_LOGO: String
} }
input AdminLoginInput { input AdminLoginInput {
admin_secret: String! admin_secret: String!
} }
input AdminSignupInput { input AdminSignupInput {
admin_secret: String! admin_secret: String!
} }
input SignUpInput { input SignUpInput {
email: String! email: String!
given_name: String given_name: String
family_name: String family_name: String
middle_name: String middle_name: String
nickname: String nickname: String
gender: String gender: String
birthdate: String birthdate: String
phone_number: String phone_number: String
picture: String picture: String
password: String! password: String!
confirm_password: String! confirm_password: String!
roles: [String!] roles: [String!]
scope: [String!] scope: [String!]
redirect_uri: String redirect_uri: String
is_multi_factor_auth_enabled: Boolean is_multi_factor_auth_enabled: Boolean
} }
input LoginInput { input LoginInput {
email: String! email: String!
password: String! password: String!
roles: [String!] roles: [String!]
scope: [String!] scope: [String!]
} }
input VerifyEmailInput { input VerifyEmailInput {
token: String! token: String!
} }
input ResendVerifyEmailInput { input ResendVerifyEmailInput {
email: String! email: String!
identifier: String! identifier: String!
} }
input UpdateProfileInput { input UpdateProfileInput {
old_password: String old_password: String
new_password: String new_password: String
confirm_new_password: String confirm_new_password: String
email: String email: String
given_name: String given_name: String
family_name: String family_name: String
middle_name: String middle_name: String
nickname: String nickname: String
gender: String gender: String
birthdate: String birthdate: String
phone_number: String phone_number: String
picture: String picture: String
is_multi_factor_auth_enabled: Boolean is_multi_factor_auth_enabled: Boolean
} }
input UpdateUserInput { input UpdateUserInput {
id: ID! id: ID!
email: String email: String
email_verified: Boolean email_verified: Boolean
given_name: String given_name: String
family_name: String family_name: String
middle_name: String middle_name: String
nickname: String nickname: String
gender: String gender: String
birthdate: String birthdate: String
phone_number: String phone_number: String
picture: String picture: String
roles: [String] roles: [String]
is_multi_factor_auth_enabled: Boolean is_multi_factor_auth_enabled: Boolean
} }
input ForgotPasswordInput { input ForgotPasswordInput {
email: String! email: String!
state: String state: String
redirect_uri: String redirect_uri: String
} }
input ResetPasswordInput { input ResetPasswordInput {
token: String! token: String!
password: String! password: String!
confirm_password: String! confirm_password: String!
} }
input DeleteUserInput { input DeleteUserInput {
email: String! email: String!
} }
input MagicLinkLoginInput { input MagicLinkLoginInput {
email: String! email: String!
roles: [String!] roles: [String!]
scope: [String!] scope: [String!]
state: String state: String
redirect_uri: String redirect_uri: String
} }
input SessionQueryInput { input SessionQueryInput {
roles: [String!] roles: [String!]
scope: [String!] scope: [String!]
} }
input PaginationInput { input PaginationInput {
limit: Int64 limit: Int64
page: Int64 page: Int64
} }
input PaginatedInput { input PaginatedInput {
pagination: PaginationInput pagination: PaginationInput
} }
input OAuthRevokeInput { input OAuthRevokeInput {
refresh_token: String! refresh_token: String!
} }
input InviteMemberInput { input InviteMemberInput {
emails: [String!]! emails: [String!]!
redirect_uri: String redirect_uri: String
} }
input UpdateAccessInput { input UpdateAccessInput {
user_id: String! user_id: String!
} }
input ValidateJWTTokenInput { input ValidateJWTTokenInput {
token_type: String! token_type: String!
token: String! token: String!
roles: [String!] roles: [String!]
} }
input GenerateJWTKeysInput { input GenerateJWTKeysInput {
type: String! type: String!
} }
input ListWebhookLogRequest { input ListWebhookLogRequest {
pagination: PaginationInput pagination: PaginationInput
webhook_id: String webhook_id: String
} }
input AddWebhookRequest { input AddWebhookRequest {
event_name: String! event_name: String!
endpoint: String! endpoint: String!
enabled: Boolean! enabled: Boolean!
headers: Map headers: Map
} }
input UpdateWebhookRequest { input UpdateWebhookRequest {
id: ID! id: ID!
event_name: String event_name: String
endpoint: String endpoint: String
enabled: Boolean enabled: Boolean
headers: Map headers: Map
} }
input WebhookRequest { input WebhookRequest {
id: ID! id: ID!
} }
input TestEndpointRequest { input TestEndpointRequest {
endpoint: String! endpoint: String!
event_name: String! event_name: String!
headers: Map headers: Map
} }
input AddEmailTemplateRequest { input AddEmailTemplateRequest {
event_name: String! event_name: String!
subject: String! subject: String!
template: String! template: String!
design: String! design: String
} }
input UpdateEmailTemplateRequest { input UpdateEmailTemplateRequest {
id: ID! id: ID!
event_name: String event_name: String
template: String template: String
subject: String subject: String
design: String design: String
} }
input DeleteEmailTemplateRequest { input DeleteEmailTemplateRequest {
id: ID! id: ID!
} }
input VerifyOTPRequest { input VerifyOTPRequest {
email: String! email: String!
otp: String! otp: String!
} }
input ResendOTPRequest { input ResendOTPRequest {
email: String! email: String!
} }
type Mutation { type Mutation {
signup(params: SignUpInput!): AuthResponse! signup(params: SignUpInput!): AuthResponse!
login(params: LoginInput!): AuthResponse! login(params: LoginInput!): AuthResponse!
magic_link_login(params: MagicLinkLoginInput!): Response! magic_link_login(params: MagicLinkLoginInput!): Response!
logout: Response! logout: Response!
update_profile(params: UpdateProfileInput!): Response! update_profile(params: UpdateProfileInput!): Response!
verify_email(params: VerifyEmailInput!): AuthResponse! verify_email(params: VerifyEmailInput!): AuthResponse!
resend_verify_email(params: ResendVerifyEmailInput!): Response! resend_verify_email(params: ResendVerifyEmailInput!): Response!
forgot_password(params: ForgotPasswordInput!): Response! forgot_password(params: ForgotPasswordInput!): Response!
reset_password(params: ResetPasswordInput!): Response! reset_password(params: ResetPasswordInput!): Response!
revoke(params: OAuthRevokeInput!): Response! revoke(params: OAuthRevokeInput!): Response!
verify_otp(params: VerifyOTPRequest!): AuthResponse! verify_otp(params: VerifyOTPRequest!): AuthResponse!
resend_otp(params: ResendOTPRequest!): Response! resend_otp(params: ResendOTPRequest!): Response!
# admin only apis # admin only apis
_delete_user(params: DeleteUserInput!): Response! _delete_user(params: DeleteUserInput!): Response!
_update_user(params: UpdateUserInput!): User! _update_user(params: UpdateUserInput!): User!
_admin_signup(params: AdminSignupInput!): Response! _admin_signup(params: AdminSignupInput!): Response!
_admin_login(params: AdminLoginInput!): Response! _admin_login(params: AdminLoginInput!): Response!
_admin_logout: Response! _admin_logout: Response!
_update_env(params: UpdateEnvInput!): Response! _update_env(params: UpdateEnvInput!): Response!
_invite_members(params: InviteMemberInput!): Response! _invite_members(params: InviteMemberInput!): Response!
_revoke_access(param: UpdateAccessInput!): Response! _revoke_access(param: UpdateAccessInput!): Response!
_enable_access(param: UpdateAccessInput!): Response! _enable_access(param: UpdateAccessInput!): Response!
_generate_jwt_keys(params: GenerateJWTKeysInput!): GenerateJWTKeysResponse! _generate_jwt_keys(params: GenerateJWTKeysInput!): GenerateJWTKeysResponse!
_add_webhook(params: AddWebhookRequest!): Response! _add_webhook(params: AddWebhookRequest!): Response!
_update_webhook(params: UpdateWebhookRequest!): Response! _update_webhook(params: UpdateWebhookRequest!): Response!
_delete_webhook(params: WebhookRequest!): Response! _delete_webhook(params: WebhookRequest!): Response!
_test_endpoint(params: TestEndpointRequest!): TestEndpointResponse! _test_endpoint(params: TestEndpointRequest!): TestEndpointResponse!
_add_email_template(params: AddEmailTemplateRequest!): Response! _add_email_template(params: AddEmailTemplateRequest!): Response!
_update_email_template(params: UpdateEmailTemplateRequest!): Response! _update_email_template(params: UpdateEmailTemplateRequest!): Response!
_delete_email_template(params: DeleteEmailTemplateRequest!): Response! _delete_email_template(params: DeleteEmailTemplateRequest!): Response!
} }
type Query { type Query {
meta: Meta! meta: Meta!
session(params: SessionQueryInput): AuthResponse! session(params: SessionQueryInput): AuthResponse!
profile: User! profile: User!
validate_jwt_token(params: ValidateJWTTokenInput!): ValidateJWTTokenResponse! validate_jwt_token(params: ValidateJWTTokenInput!): ValidateJWTTokenResponse!
# admin only apis # admin only apis
_users(params: PaginatedInput): Users! _users(params: PaginatedInput): Users!
_verification_requests(params: PaginatedInput): VerificationRequests! _verification_requests(params: PaginatedInput): VerificationRequests!
_admin_session: Response! _admin_session: Response!
_env: Env! _env: Env!
_webhook(params: WebhookRequest!): Webhook! _webhook(params: WebhookRequest!): Webhook!
_webhooks(params: PaginatedInput): Webhooks! _webhooks(params: PaginatedInput): Webhooks!
_webhook_logs(params: ListWebhookLogRequest): WebhookLogs! _webhook_logs(params: ListWebhookLogRequest): WebhookLogs!
_email_templates(params: PaginatedInput): EmailTemplates! _email_templates(params: PaginatedInput): EmailTemplates!
} }
`, BuiltIn: false}, `, BuiltIn: false},
} }
@@ -14130,7 +14130,7 @@ func (ec *executionContext) unmarshalInputAddEmailTemplateRequest(ctx context.Co
var err error var err error
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("design")) ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("design"))
it.Design, err = ec.unmarshalNString2string(ctx, v) it.Design, err = ec.unmarshalOString2string(ctx, v)
if err != nil { if err != nil {
return it, err return it, err
} }

View File

@@ -3,10 +3,10 @@
package model package model
type AddEmailTemplateRequest struct { type AddEmailTemplateRequest struct {
EventName string `json:"event_name"` EventName string `json:"event_name"`
Subject string `json:"subject"` Subject string `json:"subject"`
Template string `json:"template"` Template string `json:"template"`
Design string `json:"design"` Design *string `json:"design"`
} }
type AddWebhookRequest struct { type AddWebhookRequest struct {

View File

@@ -430,7 +430,7 @@ input AddEmailTemplateRequest {
event_name: String! event_name: String!
subject: String! subject: String!
template: String! template: String!
design: String! design: String
} }
input UpdateEmailTemplateRequest { input UpdateEmailTemplateRequest {
@@ -501,4 +501,4 @@ type Query {
_webhooks(params: PaginatedInput): Webhooks! _webhooks(params: PaginatedInput): Webhooks!
_webhook_logs(params: ListWebhookLogRequest): WebhookLogs! _webhook_logs(params: ListWebhookLogRequest): WebhookLogs!
_email_templates(params: PaginatedInput): EmailTemplates! _email_templates(params: PaginatedInput): EmailTemplates!
} }

View File

@@ -8,6 +8,7 @@ import (
"github.com/authorizerdev/authorizer/server/db" "github.com/authorizerdev/authorizer/server/db"
"github.com/authorizerdev/authorizer/server/db/models" "github.com/authorizerdev/authorizer/server/db/models"
"github.com/authorizerdev/authorizer/server/graph/model" "github.com/authorizerdev/authorizer/server/graph/model"
"github.com/authorizerdev/authorizer/server/refs"
"github.com/authorizerdev/authorizer/server/token" "github.com/authorizerdev/authorizer/server/token"
"github.com/authorizerdev/authorizer/server/utils" "github.com/authorizerdev/authorizer/server/utils"
"github.com/authorizerdev/authorizer/server/validators" "github.com/authorizerdev/authorizer/server/validators"
@@ -40,15 +41,17 @@ func AddEmailTemplateResolver(ctx context.Context, params model.AddEmailTemplate
return nil, fmt.Errorf("empty template not allowed") return nil, fmt.Errorf("empty template not allowed")
} }
if strings.TrimSpace(params.Design) == "" { var design string
return nil, fmt.Errorf("empty design not allowed")
if params.Design == nil || strings.TrimSpace(refs.StringValue(params.Design)) == "" {
design = ""
} }
_, err = db.Provider.AddEmailTemplate(ctx, models.EmailTemplate{ _, err = db.Provider.AddEmailTemplate(ctx, models.EmailTemplate{
EventName: params.EventName, EventName: params.EventName,
Template: params.Template, Template: params.Template,
Subject: params.Subject, Subject: params.Subject,
Design: params.Design, Design: design,
}) })
if err != nil { if err != nil {
log.Debug("Failed to add email template: ", err) log.Debug("Failed to add email template: ", err)

View File

@@ -51,16 +51,30 @@ func addEmailTemplateTest(t *testing.T, s TestSetup) {
assert.Nil(t, emailTemplate) assert.Nil(t, emailTemplate)
}) })
t.Run("should not add email template with empty design", func(t *testing.T) { var design string
emailTemplate, err := resolvers.AddEmailTemplateResolver(ctx, model.AddEmailTemplateRequest{ design = ""
EventName: s.TestInfo.TestEmailTemplateEventTypes[0],
Template: "test", for _, eventType := range s.TestInfo.TestEmailTemplateEventTypes {
Subject: "test", t.Run("should add email template with empty design for "+eventType, func(t *testing.T) {
Design: " ", emailTemplate, err := resolvers.AddEmailTemplateResolver(ctx, model.AddEmailTemplateRequest{
EventName: eventType,
Template: "Test email",
Subject: "Test email",
Design: &design,
})
assert.NoError(t, err)
assert.NotNil(t, emailTemplate)
assert.NotEmpty(t, emailTemplate.Message)
et, err := db.Provider.GetEmailTemplateByEventName(ctx, eventType)
assert.NoError(t, err)
assert.Equal(t, et.EventName, eventType)
assert.Equal(t, "Test email", et.Subject)
assert.Equal(t, "Test design", et.Design)
}) })
assert.Error(t, err) }
assert.Nil(t, emailTemplate)
}) design = "Test design"
for _, eventType := range s.TestInfo.TestEmailTemplateEventTypes { for _, eventType := range s.TestInfo.TestEmailTemplateEventTypes {
t.Run("should add email template for "+eventType, func(t *testing.T) { t.Run("should add email template for "+eventType, func(t *testing.T) {
@@ -68,7 +82,7 @@ func addEmailTemplateTest(t *testing.T, s TestSetup) {
EventName: eventType, EventName: eventType,
Template: "Test email", Template: "Test email",
Subject: "Test email", Subject: "Test email",
Design: "Test design", Design: &design,
}) })
assert.NoError(t, err) assert.NoError(t, err)
assert.NotNil(t, emailTemplate) assert.NotNil(t, emailTemplate)