Compare commits
68 Commits
1.1.6
...
1.1.27-bet
Author | SHA1 | Date | |
---|---|---|---|
![]() |
512fd4f1f7 | ||
![]() |
67da4a49e4 | ||
![]() |
48deae1d11 | ||
![]() |
1f2ded4219 | ||
![]() |
cb5af1e679 | ||
![]() |
27160ecbd5 | ||
![]() |
c6c3af1114 | ||
![]() |
e54b7f18f0 | ||
![]() |
a18046748b | ||
![]() |
1bff6720fc | ||
![]() |
024ffd85f3 | ||
![]() |
e171820614 | ||
![]() |
19f9caf478 | ||
![]() |
4afd544c41 | ||
![]() |
307c6f7d15 | ||
![]() |
bbc6394cf3 | ||
![]() |
63c8e2e55f | ||
![]() |
b224892a39 | ||
![]() |
13edf1965c | ||
![]() |
1f220a5205 | ||
![]() |
32fb954a1c | ||
![]() |
65eadb66fa | ||
![]() |
9ce53eb8e8 | ||
![]() |
3b196f074b | ||
![]() |
f2fe584793 | ||
![]() |
287b952dad | ||
![]() |
e690066652 | ||
![]() |
0f67d74657 | ||
![]() |
6e09307c22 | ||
![]() |
7fc69dcc55 | ||
![]() |
8449821d1b | ||
![]() |
476bdf00fc | ||
![]() |
e41f123866 | ||
![]() |
094782aeca | ||
![]() |
9630cbbc3e | ||
![]() |
1ac060136a | ||
![]() |
844e867d96 | ||
![]() |
820d294130 | ||
![]() |
e37472d498 | ||
![]() |
589af96888 | ||
![]() |
dccc70e5c0 | ||
![]() |
d8eceadd7f | ||
![]() |
e6c4fdff26 | ||
![]() |
896d8e046d | ||
![]() |
a6d5d4af24 | ||
![]() |
cc4eaa2847 | ||
![]() |
dba8944565 | ||
![]() |
e760a5598e | ||
![]() |
f62a22619b | ||
![]() |
c32a7fa1e4 | ||
![]() |
399b97079d | ||
![]() |
fe687cb0ca | ||
![]() |
9cb011e921 | ||
![]() |
4e1bba2ba8 | ||
![]() |
f1509f90f0 | ||
![]() |
bd4d48c7c5 | ||
![]() |
0e3242372b | ||
![]() |
89cea39c41 | ||
![]() |
570a0b9531 | ||
![]() |
686b3a4666 | ||
![]() |
b266a14108 | ||
![]() |
e5972a0dee | ||
![]() |
6f46f1e6ef | ||
![]() |
cfbce17ab8 | ||
![]() |
aa6601e62c | ||
![]() |
d8ea0c656f | ||
![]() |
f5323e0eec | ||
![]() |
b1bc7b5370 |
@@ -6,4 +6,5 @@ SMTP_HOST=smtp.mailtrap.io
|
||||
SMTP_PORT=2525
|
||||
SMTP_USERNAME=test
|
||||
SMTP_PASSWORD=test
|
||||
SENDER_EMAIL="info@authorizer.dev"
|
||||
SENDER_EMAIL="info@authorizer.dev"
|
||||
AWS_REGION=ap-south-1
|
62
.github/workflows/release.yaml
vendored
62
.github/workflows/release.yaml
vendored
@@ -2,36 +2,44 @@ on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
logLevel:
|
||||
description: 'Log level'
|
||||
description: "Log level"
|
||||
required: true
|
||||
default: 'warning'
|
||||
default: "warning"
|
||||
type: choice
|
||||
options:
|
||||
- info
|
||||
- warning
|
||||
- debug
|
||||
- info
|
||||
- warning
|
||||
- debug
|
||||
tags:
|
||||
description: 'Tags'
|
||||
required: false
|
||||
description: "Tags"
|
||||
required: false
|
||||
type: boolean
|
||||
release:
|
||||
types: [created]
|
||||
|
||||
jobs:
|
||||
releases:
|
||||
name: Release Authorizer Binary
|
||||
name: Release Authorizer
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v2
|
||||
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
|
||||
- uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: '^1.17.3'
|
||||
go-version: "^1.17.3"
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get install build-essential wget zip gcc-mingw-w64 && \
|
||||
sudo apt-get install build-essential wget zip libc6-dev-arm64-cross && \
|
||||
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 && \
|
||||
tar -zxf github-assets-uploader.tar.gz && \
|
||||
@@ -44,25 +52,26 @@ jobs:
|
||||
run: whereis go
|
||||
- name: Print Go Version
|
||||
run: go version
|
||||
- name: Install gox
|
||||
run: go install github.com/mitchellh/gox@latest
|
||||
- name: Set VERSION env
|
||||
run: echo VERSION=$(basename ${GITHUB_REF}) >> ${GITHUB_ENV}
|
||||
- name: Copy .env file
|
||||
run: mv .env.sample .env
|
||||
- name: Package files for windows
|
||||
- name: Build package
|
||||
run: |
|
||||
make clean && \
|
||||
CGO_ENABLED=1 GOOS=windows CC=/usr/bin/x86_64-w64-mingw32-gcc make && \
|
||||
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
|
||||
make build && \
|
||||
mkdir -p authorizer-${VERSION}-darwin-amd64/build authorizer-${VERSION}-darwin-amd64/app 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/ && cp -rf dashboard/build authorizer-${VERSION}-darwin-amd64/dashboard/build && tar cvfz authorizer-${VERSION}-darwin-amd64.tar.gz authorizer-${VERSION}-darwin-amd64 && \
|
||||
mkdir -p authorizer-${VERSION}-linux-amd64/build authorizer-${VERSION}-linux-amd64/app authorizer-${VERSION}-linux-amd64/dashboard && cp build/linux/amd64/server authorizer-${VERSION}-linux-amd64/build/ && cp .env authorizer-${VERSION}-linux-amd64/.env && cp -rf app/build authorizer-${VERSION}-linux-amd64/app/build && cp -rf templates authorizer-${VERSION}-linux-amd64/ && cp -rf dashboard/build authorizer-${VERSION}-linux-amd64/dashboard/build && tar cvfz authorizer-${VERSION}-linux-amd64.tar.gz authorizer-${VERSION}-linux-amd64 && \
|
||||
mkdir -p authorizer-${VERSION}-linux-arm64/build authorizer-${VERSION}-linux-arm64/app authorizer-${VERSION}-linux-arm64/dashboard && cp build/linux/arm64/server authorizer-${VERSION}-linux-arm64/build/ && cp .env authorizer-${VERSION}-linux-arm64/.env && cp -rf app/build authorizer-${VERSION}-linux-arm64/app/build && cp -rf templates authorizer-${VERSION}-linux-arm64/ && cp -rf dashboard/build authorizer-${VERSION}-linux-arm64/dashboard/build && tar cvfz authorizer-${VERSION}-linux-arm64.tar.gz authorizer-${VERSION}-linux-arm64 && \
|
||||
mkdir -p authorizer-${VERSION}-windows-amd64/build authorizer-${VERSION}-windows-amd64/app authorizer-${VERSION}-windows-amd64/dashboard && cp build/windows/amd64/server.exe authorizer-${VERSION}-windows-amd64/build/ && cp .env authorizer-${VERSION}-windows-amd64/.env && cp -rf app/build authorizer-${VERSION}-windows-amd64/app/build && cp -rf templates authorizer-${VERSION}-windows-amd64/ && cp -rf dashboard/build authorizer-${VERSION}-windows-amd64/dashboard/build && zip -vr authorizer-${VERSION}-windows-amd64.zip authorizer-${VERSION}-windows-amd64
|
||||
- name: Upload assets
|
||||
run: |
|
||||
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}-darwin-amd64.tar.gz -mediatype application/gzip -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}
|
||||
github-assets-uploader -f authorizer-${VERSION}-linux-arm64.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}
|
||||
- name: Log in to Docker Hub
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
@@ -74,6 +83,14 @@ jobs:
|
||||
uses: docker/metadata-action@v3
|
||||
with:
|
||||
images: lakhansamani/authorizer
|
||||
flavor: |
|
||||
latest=false
|
||||
tags: |
|
||||
type=schedule
|
||||
type=ref,event=branch
|
||||
type=ref,event=tag
|
||||
type=ref,event=pr
|
||||
type=raw,value=latest,enable={{is_default_branch}}
|
||||
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@v2
|
||||
@@ -82,5 +99,6 @@ jobs:
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
platforms: linux/amd64,linux/arm64
|
||||
build-args: |
|
||||
VERSION=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }}
|
||||
|
4
.gitignore
vendored
4
.gitignore
vendored
@@ -15,4 +15,6 @@ test.db
|
||||
.vscode/
|
||||
.yalc
|
||||
yalc.lock
|
||||
certs/
|
||||
certs/
|
||||
*-shm
|
||||
*-wal
|
@@ -1,4 +1,4 @@
|
||||
FROM golang:1.17-alpine as go-builder
|
||||
FROM golang:1.19.1-alpine as go-builder
|
||||
WORKDIR /authorizer
|
||||
COPY server server
|
||||
COPY Makefile .
|
||||
|
21
Makefile
21
Makefile
@@ -3,6 +3,12 @@ VERSION := $(or $(VERSION),$(DEFAULT_VERSION))
|
||||
|
||||
cmd:
|
||||
cd server && go build -ldflags "-w -X main.VERSION=$(VERSION)" -o '../build/server'
|
||||
build:
|
||||
cd server && gox \
|
||||
-osarch="linux/amd64 linux/arm64 darwin/amd64 windows/amd64" \
|
||||
-ldflags "-w -X main.VERSION=$(VERSION)" \
|
||||
-output="../build/{{.OS}}/{{.Arch}}/server" \
|
||||
./...
|
||||
build-app:
|
||||
cd app && npm i && npm run build
|
||||
build-dashboard:
|
||||
@@ -10,7 +16,7 @@ build-dashboard:
|
||||
clean:
|
||||
rm -rf build
|
||||
test:
|
||||
rm -rf server/test/test.db && rm -rf test.db && cd server && go clean --testcache && TEST_DBS="sqlite" go test -p 1 -v ./test
|
||||
rm -rf server/test/test.db server/test/test.db-shm server/test/test.db-wal && rm -rf test.db test.db-shm test.db-wal && cd server && go clean --testcache && TEST_DBS="sqlite" go test -p 1 -v ./test
|
||||
test-mongodb:
|
||||
docker run -d --name authorizer_mongodb_db -p 27017:27017 mongo:4.4.15
|
||||
cd server && go clean --testcache && TEST_DBS="mongodb" go test -p 1 -v ./test
|
||||
@@ -23,15 +29,20 @@ test-arangodb:
|
||||
docker run -d --name authorizer_arangodb -p 8529:8529 -e ARANGO_NO_AUTH=1 arangodb/arangodb:3.8.4
|
||||
cd server && go clean --testcache && TEST_DBS="arangodb" go test -p 1 -v ./test
|
||||
docker rm -vf authorizer_arangodb
|
||||
test-dynamodb:
|
||||
docker run -d --name dynamodb-local-test -p 8000:8000 amazon/dynamodb-local:latest
|
||||
cd server && go clean --testcache && TEST_DBS="dynamodb" go test -p 1 -v ./test
|
||||
docker rm -vf dynamodb-local-test
|
||||
test-all-db:
|
||||
rm -rf server/test/test.db && rm -rf test.db
|
||||
rm -rf server/test/test.db server/test/test.db-shm server/test/test.db-wal && rm -rf test.db test.db-shm test.db-wal
|
||||
docker run -d --name authorizer_scylla_db -p 9042:9042 scylladb/scylla
|
||||
docker run -d --name authorizer_mongodb_db -p 27017:27017 mongo:4.4.15
|
||||
docker run -d --name authorizer_arangodb -p 8529:8529 -e ARANGO_NO_AUTH=1 arangodb/arangodb:3.8.4
|
||||
cd server && go clean --testcache && TEST_DBS="sqlite,mongodb,arangodb,scylladb" go test -p 1 -v ./test
|
||||
docker run -d --name dynamodb-local-test -p 8000:8000 amazon/dynamodb-local:latest
|
||||
cd server && go clean --testcache && TEST_DBS="sqlite,mongodb,arangodb,scylladb,dynamodb" go test -p 1 -v ./test
|
||||
docker rm -vf authorizer_scylla_db
|
||||
docker rm -vf authorizer_mongodb_db
|
||||
docker rm -vf authorizer_arangodb
|
||||
docker rm -vf dynamodb-local-test
|
||||
generate:
|
||||
cd server && go get github.com/99designs/gqlgen/cmd@v0.14.0 && go run github.com/99designs/gqlgen generate
|
||||
|
||||
cd server && go run github.com/99designs/gqlgen generate && go mod tidy
|
||||
|
6
app/.prettierrc.json
Normal file
6
app/.prettierrc.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"tabWidth": 2,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "all",
|
||||
"useTabs": false
|
||||
}
|
24
app/package-lock.json
generated
24
app/package-lock.json
generated
@@ -22,7 +22,8 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react-router-dom": "^5.1.8",
|
||||
"@types/styled-components": "^5.1.11"
|
||||
"@types/styled-components": "^5.1.11",
|
||||
"prettier": "2.7.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@authorizerdev/authorizer-js": {
|
||||
@@ -617,6 +618,21 @@
|
||||
"resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
|
||||
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="
|
||||
},
|
||||
"node_modules/prettier": {
|
||||
"version": "2.7.1",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz",
|
||||
"integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"prettier": "bin-prettier.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.13.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/prettier/prettier?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/prop-types": {
|
||||
"version": "15.7.2",
|
||||
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz",
|
||||
@@ -1329,6 +1345,12 @@
|
||||
"resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
|
||||
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="
|
||||
},
|
||||
"prettier": {
|
||||
"version": "2.7.1",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz",
|
||||
"integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==",
|
||||
"dev": true
|
||||
},
|
||||
"prop-types": {
|
||||
"version": "15.7.2",
|
||||
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz",
|
||||
|
@@ -5,7 +5,8 @@
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"build": "rm -rf build && NODE_ENV=production node ./esbuild.config.js",
|
||||
"start": "NODE_ENV=development node ./esbuild.config.js"
|
||||
"start": "NODE_ENV=development node ./esbuild.config.js",
|
||||
"format": "prettier --write --use-tabs 'src/**/*.(ts|tsx|js|jsx)'"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "Lakhan Samani",
|
||||
@@ -19,11 +20,12 @@
|
||||
"react-dom": "^17.0.2",
|
||||
"react-is": "^17.0.2",
|
||||
"react-router-dom": "^5.2.0",
|
||||
"typescript": "^4.3.5",
|
||||
"styled-components": "^5.3.0"
|
||||
"styled-components": "^5.3.0",
|
||||
"typescript": "^4.3.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react-router-dom": "^5.1.8",
|
||||
"@types/styled-components": "^5.1.11"
|
||||
"@types/styled-components": "^5.1.11",
|
||||
"prettier": "2.7.1"
|
||||
}
|
||||
}
|
||||
|
@@ -5,9 +5,9 @@ import Root from './Root';
|
||||
import { createRandomString } from './utils/common';
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
__authorizer__: any;
|
||||
}
|
||||
interface Window {
|
||||
__authorizer__: any;
|
||||
}
|
||||
}
|
||||
|
||||
export default function App() {
|
||||
|
@@ -32,7 +32,7 @@ export default function Root({
|
||||
const { token, loading, config } = useAuthorizer();
|
||||
|
||||
const searchParams = new URLSearchParams(
|
||||
hasWindow() ? window.location.search : ``
|
||||
hasWindow() ? window.location.search : ``,
|
||||
);
|
||||
const state = searchParams.get('state') || createRandomString();
|
||||
const scope = searchParams.get('scope')
|
||||
|
@@ -60,7 +60,12 @@ export default function Login({ urlProps }: { urlProps: Record<string, any> }) {
|
||||
{view === VIEW_TYPES.FORGOT_PASSWORD && (
|
||||
<Fragment>
|
||||
<h1 style={{ textAlign: 'center' }}>Forgot Password</h1>
|
||||
<AuthorizerForgotPassword urlProps={urlProps} />
|
||||
<AuthorizerForgotPassword
|
||||
urlProps={{
|
||||
...urlProps,
|
||||
redirect_uri: `${window.location.origin}/app/reset-password`,
|
||||
}}
|
||||
/>
|
||||
<Footer>
|
||||
<Link
|
||||
to="#"
|
||||
|
@@ -1,28 +1,28 @@
|
||||
// colors: https://tailwindcss.com/docs/customizing-colors
|
||||
|
||||
export const theme = {
|
||||
colors: {
|
||||
primary: '#3B82F6',
|
||||
primaryDisabled: '#60A5FA',
|
||||
gray: '#D1D5DB',
|
||||
danger: '#DC2626',
|
||||
success: '#10B981',
|
||||
textColor: '#374151',
|
||||
},
|
||||
fonts: {
|
||||
// typography
|
||||
fontStack: '-apple-system, system-ui, sans-serif',
|
||||
colors: {
|
||||
primary: '#3B82F6',
|
||||
primaryDisabled: '#60A5FA',
|
||||
gray: '#D1D5DB',
|
||||
danger: '#DC2626',
|
||||
success: '#10B981',
|
||||
textColor: '#374151',
|
||||
},
|
||||
fonts: {
|
||||
// typography
|
||||
fontStack: '-apple-system, system-ui, sans-serif',
|
||||
|
||||
// font sizes
|
||||
largeText: '18px',
|
||||
mediumText: '14px',
|
||||
smallText: '12px',
|
||||
tinyText: '10px',
|
||||
},
|
||||
// font sizes
|
||||
largeText: '18px',
|
||||
mediumText: '14px',
|
||||
smallText: '12px',
|
||||
tinyText: '10px',
|
||||
},
|
||||
|
||||
radius: {
|
||||
card: '5px',
|
||||
button: '5px',
|
||||
input: '5px',
|
||||
},
|
||||
radius: {
|
||||
card: '5px',
|
||||
button: '5px',
|
||||
input: '5px',
|
||||
},
|
||||
};
|
||||
|
@@ -8,7 +8,7 @@ export const createRandomString = () => {
|
||||
'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_~.';
|
||||
let random = '';
|
||||
const randomValues = Array.from(
|
||||
getCrypto().getRandomValues(new Uint8Array(43))
|
||||
getCrypto().getRandomValues(new Uint8Array(43)),
|
||||
);
|
||||
randomValues.forEach((v) => (random += charset[v % charset.length]));
|
||||
return random;
|
||||
|
6
dashboard/.prettierrc.json
Normal file
6
dashboard/.prettierrc.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"tabWidth": 2,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "all",
|
||||
"useTabs": false
|
||||
}
|
1191
dashboard/package-lock.json
generated
1191
dashboard/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -5,7 +5,8 @@
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"build": "rm -rf build && NODE_ENV=production node ./esbuild.config.js",
|
||||
"start": "NODE_ENV=development node ./esbuild.config.js"
|
||||
"start": "NODE_ENV=development node ./esbuild.config.js",
|
||||
"format": "prettier --write --use-tabs 'src/**/*.(ts|tsx|js|jsx)'"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "Lakhan Samani",
|
||||
@@ -35,6 +36,7 @@
|
||||
"urql": "^2.0.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react-email-editor": "^1.1.7"
|
||||
"@types/react-email-editor": "^1.1.7",
|
||||
"prettier": "2.7.1"
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import React from 'react';
|
||||
import React, { useState } from 'react';
|
||||
import {
|
||||
Button,
|
||||
Center,
|
||||
@@ -20,13 +20,14 @@ import { useClient } from 'urql';
|
||||
import { FaSave } from 'react-icons/fa';
|
||||
import InputField from './InputField';
|
||||
import {
|
||||
ArrayInputType,
|
||||
DateInputType,
|
||||
MultiSelectInputType,
|
||||
SelectInputType,
|
||||
TextInputType,
|
||||
} from '../constants';
|
||||
import { getObjectDiff } from '../utils';
|
||||
import { UpdateUser } from '../graphql/mutation';
|
||||
import { GetAvailableRolesQuery } from '../graphql/queries';
|
||||
|
||||
const GenderTypes = {
|
||||
Undisclosed: null,
|
||||
@@ -57,8 +58,9 @@ const EditUserModal = ({
|
||||
}) => {
|
||||
const client = useClient();
|
||||
const toast = useToast();
|
||||
const [availableRoles, setAvailableRoles] = useState<string[]>([]);
|
||||
const { isOpen, onOpen, onClose } = useDisclosure();
|
||||
const [userData, setUserData] = React.useState<userDataTypes>({
|
||||
const [userData, setUserData] = useState<userDataTypes>({
|
||||
id: '',
|
||||
email: '',
|
||||
given_name: '',
|
||||
@@ -73,7 +75,17 @@ const EditUserModal = ({
|
||||
});
|
||||
React.useEffect(() => {
|
||||
setUserData(user);
|
||||
fetchAvailableRoles();
|
||||
}, []);
|
||||
const fetchAvailableRoles = async () => {
|
||||
const res = await client.query(GetAvailableRolesQuery).toPromise();
|
||||
if (res.data?._env?.ROLES && res.data?._env?.PROTECTED_ROLES) {
|
||||
setAvailableRoles([
|
||||
...res.data._env.ROLES,
|
||||
...res.data._env.PROTECTED_ROLES,
|
||||
]);
|
||||
}
|
||||
};
|
||||
const saveHandler = async () => {
|
||||
const diff = getObjectDiff(user, userData);
|
||||
const updatedUserData = diff.reduce(
|
||||
@@ -82,7 +94,7 @@ const EditUserModal = ({
|
||||
// @ts-ignore
|
||||
[property]: userData[property],
|
||||
}),
|
||||
{}
|
||||
{},
|
||||
);
|
||||
const res = await client
|
||||
.mutation(UpdateUser, { params: { ...updatedUserData, id: userData.id } })
|
||||
@@ -221,7 +233,8 @@ const EditUserModal = ({
|
||||
<InputField
|
||||
variables={userData}
|
||||
setVariables={setUserData}
|
||||
inputType={ArrayInputType.USER_ROLES}
|
||||
availableRoles={availableRoles}
|
||||
inputType={MultiSelectInputType.USER_ROLES}
|
||||
/>
|
||||
</Center>
|
||||
</Flex>
|
||||
|
@@ -1,65 +1,65 @@
|
||||
import React from "react";
|
||||
import { Flex, Stack, Text, useMediaQuery } from "@chakra-ui/react";
|
||||
import InputField from "../../components/InputField";
|
||||
import { TextInputType, TextAreaInputType } from "../../constants";
|
||||
import React from 'react';
|
||||
import { Flex, Stack, Text, useMediaQuery } from '@chakra-ui/react';
|
||||
import InputField from '../../components/InputField';
|
||||
import { TextInputType, TextAreaInputType } from '../../constants';
|
||||
|
||||
const AccessToken = ({ variables, setVariables }: any) => {
|
||||
const [isNotSmallerScreen] = useMediaQuery("(min-width:600px)");
|
||||
return (
|
||||
<div>
|
||||
{" "}
|
||||
<Text fontSize="md" paddingTop="2%" fontWeight="bold" mb={5}>
|
||||
Access Token
|
||||
</Text>
|
||||
<Stack spacing={6} padding="2% 0%">
|
||||
<Flex direction={isNotSmallerScreen ? "row" : "column"}>
|
||||
<Flex
|
||||
w={isNotSmallerScreen ? "30%" : "50%"}
|
||||
justifyContent="start"
|
||||
alignItems="center"
|
||||
>
|
||||
<Text fontSize="sm">Access Token Expiry Time:</Text>
|
||||
</Flex>
|
||||
<Flex
|
||||
w={isNotSmallerScreen ? "70%" : "100%"}
|
||||
mt={isNotSmallerScreen ? "0" : "3"}
|
||||
>
|
||||
<InputField
|
||||
borderRadius={5}
|
||||
variables={variables}
|
||||
setVariables={setVariables}
|
||||
inputType={TextInputType.ACCESS_TOKEN_EXPIRY_TIME}
|
||||
placeholder="0h15m0s"
|
||||
/>
|
||||
</Flex>
|
||||
</Flex>
|
||||
<Flex direction={isNotSmallerScreen ? "row" : "column"}>
|
||||
<Flex
|
||||
w={isNotSmallerScreen ? "30%" : "60%"}
|
||||
justifyContent="start"
|
||||
direction="column"
|
||||
>
|
||||
<Text fontSize="sm">Custom Scripts:</Text>
|
||||
<Text fontSize="xs" color="blackAlpha.500">
|
||||
(Used to add custom fields in ID token)
|
||||
</Text>
|
||||
</Flex>
|
||||
<Flex
|
||||
w={isNotSmallerScreen ? "70%" : "100%"}
|
||||
mt={isNotSmallerScreen ? "0" : "3"}
|
||||
>
|
||||
<InputField
|
||||
variables={variables}
|
||||
setVariables={setVariables}
|
||||
inputType={TextAreaInputType.CUSTOM_ACCESS_TOKEN_SCRIPT}
|
||||
placeholder="Add script here"
|
||||
minH="25vh"
|
||||
/>
|
||||
</Flex>
|
||||
</Flex>
|
||||
</Stack>
|
||||
</div>
|
||||
);
|
||||
const [isNotSmallerScreen] = useMediaQuery('(min-width:600px)');
|
||||
return (
|
||||
<div>
|
||||
{' '}
|
||||
<Text fontSize="md" paddingTop="2%" fontWeight="bold" mb={5}>
|
||||
Access Token
|
||||
</Text>
|
||||
<Stack spacing={6} padding="2% 0%">
|
||||
<Flex direction={isNotSmallerScreen ? 'row' : 'column'}>
|
||||
<Flex
|
||||
w={isNotSmallerScreen ? '30%' : '50%'}
|
||||
justifyContent="start"
|
||||
alignItems="center"
|
||||
>
|
||||
<Text fontSize="sm">Access Token Expiry Time:</Text>
|
||||
</Flex>
|
||||
<Flex
|
||||
w={isNotSmallerScreen ? '70%' : '100%'}
|
||||
mt={isNotSmallerScreen ? '0' : '3'}
|
||||
>
|
||||
<InputField
|
||||
borderRadius={5}
|
||||
variables={variables}
|
||||
setVariables={setVariables}
|
||||
inputType={TextInputType.ACCESS_TOKEN_EXPIRY_TIME}
|
||||
placeholder="0h15m0s"
|
||||
/>
|
||||
</Flex>
|
||||
</Flex>
|
||||
<Flex direction={isNotSmallerScreen ? 'row' : 'column'}>
|
||||
<Flex
|
||||
w={isNotSmallerScreen ? '30%' : '60%'}
|
||||
justifyContent="start"
|
||||
direction="column"
|
||||
>
|
||||
<Text fontSize="sm">Custom Scripts:</Text>
|
||||
<Text fontSize="xs" color="blackAlpha.500">
|
||||
(Used to add custom fields in ID token)
|
||||
</Text>
|
||||
</Flex>
|
||||
<Flex
|
||||
w={isNotSmallerScreen ? '70%' : '100%'}
|
||||
mt={isNotSmallerScreen ? '0' : '3'}
|
||||
>
|
||||
<InputField
|
||||
variables={variables}
|
||||
setVariables={setVariables}
|
||||
inputType={TextAreaInputType.CUSTOM_ACCESS_TOKEN_SCRIPT}
|
||||
placeholder="Add script here"
|
||||
minH="25vh"
|
||||
/>
|
||||
</Flex>
|
||||
</Flex>
|
||||
</Stack>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default AccessToken;
|
||||
export default AccessToken;
|
||||
|
@@ -1,35 +1,35 @@
|
||||
import React from "react";
|
||||
import { Flex, Stack, Center, Text, useMediaQuery } from "@chakra-ui/react";
|
||||
import InputField from "../../components/InputField";
|
||||
import { ArrayInputType} from "../../constants";
|
||||
import React from 'react';
|
||||
import { Flex, Stack, Center, Text, useMediaQuery } from '@chakra-ui/react';
|
||||
import InputField from '../../components/InputField';
|
||||
import { ArrayInputType } from '../../constants';
|
||||
|
||||
const DomainWhiteListing = ({ variables, setVariables }: any) => {
|
||||
const [isNotSmallerScreen] = useMediaQuery("(min-width:600px)");
|
||||
return (
|
||||
<div>
|
||||
{" "}
|
||||
<Text fontSize="md" paddingTop="2%" fontWeight="bold" mb={5}>
|
||||
Domain White Listing
|
||||
</Text>
|
||||
<Stack spacing={6} padding="2% 0%">
|
||||
<Flex direction={isNotSmallerScreen ? "row" : "column"}>
|
||||
<Flex w="30%" justifyContent="start" alignItems="center">
|
||||
<Text fontSize="sm">Allowed Origins:</Text>
|
||||
</Flex>
|
||||
<Center
|
||||
w={isNotSmallerScreen ? "70%" : "100%"}
|
||||
mt={isNotSmallerScreen ? "0" : "3"}
|
||||
>
|
||||
<InputField
|
||||
variables={variables}
|
||||
setVariables={setVariables}
|
||||
inputType={ArrayInputType.ALLOWED_ORIGINS}
|
||||
/>
|
||||
</Center>
|
||||
</Flex>
|
||||
</Stack>
|
||||
</div>
|
||||
);
|
||||
const [isNotSmallerScreen] = useMediaQuery('(min-width:600px)');
|
||||
return (
|
||||
<div>
|
||||
{' '}
|
||||
<Text fontSize="md" paddingTop="2%" fontWeight="bold" mb={5}>
|
||||
Domain White Listing
|
||||
</Text>
|
||||
<Stack spacing={6} padding="2% 0%">
|
||||
<Flex direction={isNotSmallerScreen ? 'row' : 'column'}>
|
||||
<Flex w="30%" justifyContent="start" alignItems="center">
|
||||
<Text fontSize="sm">Allowed Origins:</Text>
|
||||
</Flex>
|
||||
<Center
|
||||
w={isNotSmallerScreen ? '70%' : '100%'}
|
||||
mt={isNotSmallerScreen ? '0' : '3'}
|
||||
>
|
||||
<InputField
|
||||
variables={variables}
|
||||
setVariables={setVariables}
|
||||
inputType={ArrayInputType.ALLOWED_ORIGINS}
|
||||
/>
|
||||
</Center>
|
||||
</Flex>
|
||||
</Stack>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default DomainWhiteListing;
|
||||
export default DomainWhiteListing;
|
||||
|
@@ -1,114 +1,134 @@
|
||||
import React from "react";
|
||||
import { Flex, Stack, Center, Text, useMediaQuery } from "@chakra-ui/react";
|
||||
import InputField from "../../components/InputField";
|
||||
import { TextInputType, HiddenInputType} from "../../constants";
|
||||
import React from 'react';
|
||||
import { Flex, Stack, Center, Text, useMediaQuery } from '@chakra-ui/react';
|
||||
import InputField from '../../components/InputField';
|
||||
import { TextInputType, HiddenInputType } from '../../constants';
|
||||
const EmailConfigurations = ({
|
||||
variables,
|
||||
setVariables,
|
||||
fieldVisibility,
|
||||
setFieldVisibility,
|
||||
variables,
|
||||
setVariables,
|
||||
fieldVisibility,
|
||||
setFieldVisibility,
|
||||
}: any) => {
|
||||
const [isNotSmallerScreen] = useMediaQuery("(min-width:600px)");
|
||||
return (
|
||||
<div>
|
||||
{" "}
|
||||
<Text fontSize="md" paddingTop="2%" fontWeight="bold" mb={5}>
|
||||
Email Configurations
|
||||
</Text>
|
||||
<Stack spacing={6} padding="2% 0%">
|
||||
<Flex direction={isNotSmallerScreen ? "row" : "column"}>
|
||||
<Flex w="30%" justifyContent="start" alignItems="center">
|
||||
<Text fontSize="sm">SMTP Host:</Text>
|
||||
</Flex>
|
||||
<Center
|
||||
w={isNotSmallerScreen ? "70%" : "100%"}
|
||||
mt={isNotSmallerScreen ? "0" : "3"}
|
||||
>
|
||||
<InputField
|
||||
borderRadius={5}
|
||||
variables={variables}
|
||||
setVariables={setVariables}
|
||||
inputType={TextInputType.SMTP_HOST}
|
||||
/>
|
||||
</Center>
|
||||
</Flex>
|
||||
<Flex direction={isNotSmallerScreen ? "row" : "column"}>
|
||||
<Flex w="30%" justifyContent="start" alignItems="center">
|
||||
<Text fontSize="sm">SMTP Port:</Text>
|
||||
</Flex>
|
||||
<Center
|
||||
w={isNotSmallerScreen ? "70%" : "100%"}
|
||||
mt={isNotSmallerScreen ? "0" : "3"}
|
||||
>
|
||||
<InputField
|
||||
borderRadius={5}
|
||||
variables={variables}
|
||||
setVariables={setVariables}
|
||||
inputType={TextInputType.SMTP_PORT}
|
||||
/>
|
||||
</Center>
|
||||
</Flex>
|
||||
<Flex direction={isNotSmallerScreen ? "row" : "column"}>
|
||||
<Flex
|
||||
w={isNotSmallerScreen ? "30%" : "40%"}
|
||||
justifyContent="start"
|
||||
alignItems="center"
|
||||
>
|
||||
<Text fontSize="sm">SMTP Username:</Text>
|
||||
</Flex>
|
||||
<Center
|
||||
w={isNotSmallerScreen ? "70%" : "100%"}
|
||||
mt={isNotSmallerScreen ? "0" : "3"}
|
||||
>
|
||||
<InputField
|
||||
borderRadius={5}
|
||||
variables={variables}
|
||||
setVariables={setVariables}
|
||||
inputType={TextInputType.SMTP_USERNAME}
|
||||
/>
|
||||
</Center>
|
||||
</Flex>
|
||||
<Flex direction={isNotSmallerScreen ? "row" : "column"}>
|
||||
<Flex
|
||||
w={isNotSmallerScreen ? "30%" : "40%"}
|
||||
justifyContent="start"
|
||||
alignItems="center"
|
||||
>
|
||||
<Text fontSize="sm">SMTP Password:</Text>
|
||||
</Flex>
|
||||
<Center
|
||||
w={isNotSmallerScreen ? "70%" : "100%"}
|
||||
mt={isNotSmallerScreen ? "0" : "3"}
|
||||
>
|
||||
<InputField
|
||||
borderRadius={5}
|
||||
variables={variables}
|
||||
setVariables={setVariables}
|
||||
fieldVisibility={fieldVisibility}
|
||||
setFieldVisibility={setFieldVisibility}
|
||||
inputType={HiddenInputType.SMTP_PASSWORD}
|
||||
/>
|
||||
</Center>
|
||||
</Flex>
|
||||
<Flex direction={isNotSmallerScreen ? "row" : "column"}>
|
||||
<Flex w="30%" justifyContent="start" alignItems="center">
|
||||
<Text fontSize="sm">From Email:</Text>
|
||||
</Flex>
|
||||
<Center
|
||||
w={isNotSmallerScreen ? "70%" : "100%"}
|
||||
mt={isNotSmallerScreen ? "0" : "3"}
|
||||
>
|
||||
<InputField
|
||||
borderRadius={5}
|
||||
variables={variables}
|
||||
setVariables={setVariables}
|
||||
inputType={TextInputType.SENDER_EMAIL}
|
||||
/>
|
||||
</Center>
|
||||
</Flex>
|
||||
</Stack>
|
||||
</div>
|
||||
);
|
||||
const [isNotSmallerScreen] = useMediaQuery('(min-width:600px)');
|
||||
return (
|
||||
<div>
|
||||
{' '}
|
||||
<Text fontSize="md" paddingTop="2%" fontWeight="bold" mb={5}>
|
||||
Email Configurations
|
||||
</Text>
|
||||
<Stack spacing={6} padding="2% 0%">
|
||||
<Flex direction={isNotSmallerScreen ? 'row' : 'column'}>
|
||||
<Flex w="30%" justifyContent="start" alignItems="center">
|
||||
<Text fontSize="sm">SMTP Host:</Text>
|
||||
</Flex>
|
||||
<Center
|
||||
w={isNotSmallerScreen ? '70%' : '100%'}
|
||||
mt={isNotSmallerScreen ? '0' : '3'}
|
||||
>
|
||||
<InputField
|
||||
borderRadius={5}
|
||||
variables={variables}
|
||||
setVariables={setVariables}
|
||||
inputType={TextInputType.SMTP_HOST}
|
||||
/>
|
||||
</Center>
|
||||
</Flex>
|
||||
<Flex direction={isNotSmallerScreen ? 'row' : 'column'}>
|
||||
<Flex w="30%" justifyContent="start" alignItems="center">
|
||||
<Text fontSize="sm">SMTP Port:</Text>
|
||||
</Flex>
|
||||
<Center
|
||||
w={isNotSmallerScreen ? '70%' : '100%'}
|
||||
mt={isNotSmallerScreen ? '0' : '3'}
|
||||
>
|
||||
<InputField
|
||||
borderRadius={5}
|
||||
variables={variables}
|
||||
setVariables={setVariables}
|
||||
inputType={TextInputType.SMTP_PORT}
|
||||
/>
|
||||
</Center>
|
||||
</Flex>
|
||||
<Flex direction={isNotSmallerScreen ? 'row' : 'column'}>
|
||||
<Flex
|
||||
w={isNotSmallerScreen ? '30%' : '40%'}
|
||||
justifyContent="start"
|
||||
alignItems="center"
|
||||
>
|
||||
<Text fontSize="sm">SMTP Local Name:</Text>
|
||||
</Flex>
|
||||
<Center
|
||||
w={isNotSmallerScreen ? '70%' : '100%'}
|
||||
mt={isNotSmallerScreen ? '0' : '3'}
|
||||
>
|
||||
<InputField
|
||||
borderRadius={5}
|
||||
variables={variables}
|
||||
setVariables={setVariables}
|
||||
inputType={TextInputType.SMTP_LOCAL_NAME}
|
||||
/>
|
||||
</Center>
|
||||
</Flex>
|
||||
<Flex direction={isNotSmallerScreen ? 'row' : 'column'}>
|
||||
<Flex
|
||||
w={isNotSmallerScreen ? '30%' : '40%'}
|
||||
justifyContent="start"
|
||||
alignItems="center"
|
||||
>
|
||||
<Text fontSize="sm">SMTP Username:</Text>
|
||||
</Flex>
|
||||
<Center
|
||||
w={isNotSmallerScreen ? '70%' : '100%'}
|
||||
mt={isNotSmallerScreen ? '0' : '3'}
|
||||
>
|
||||
<InputField
|
||||
borderRadius={5}
|
||||
variables={variables}
|
||||
setVariables={setVariables}
|
||||
inputType={TextInputType.SMTP_USERNAME}
|
||||
/>
|
||||
</Center>
|
||||
</Flex>
|
||||
<Flex direction={isNotSmallerScreen ? 'row' : 'column'}>
|
||||
<Flex
|
||||
w={isNotSmallerScreen ? '30%' : '40%'}
|
||||
justifyContent="start"
|
||||
alignItems="center"
|
||||
>
|
||||
<Text fontSize="sm">SMTP Password:</Text>
|
||||
</Flex>
|
||||
<Center
|
||||
w={isNotSmallerScreen ? '70%' : '100%'}
|
||||
mt={isNotSmallerScreen ? '0' : '3'}
|
||||
>
|
||||
<InputField
|
||||
borderRadius={5}
|
||||
variables={variables}
|
||||
setVariables={setVariables}
|
||||
fieldVisibility={fieldVisibility}
|
||||
setFieldVisibility={setFieldVisibility}
|
||||
inputType={HiddenInputType.SMTP_PASSWORD}
|
||||
/>
|
||||
</Center>
|
||||
</Flex>
|
||||
<Flex direction={isNotSmallerScreen ? 'row' : 'column'}>
|
||||
<Flex w="30%" justifyContent="start" alignItems="center">
|
||||
<Text fontSize="sm">From Email:</Text>
|
||||
</Flex>
|
||||
<Center
|
||||
w={isNotSmallerScreen ? '70%' : '100%'}
|
||||
mt={isNotSmallerScreen ? '0' : '3'}
|
||||
>
|
||||
<InputField
|
||||
borderRadius={5}
|
||||
variables={variables}
|
||||
setVariables={setVariables}
|
||||
inputType={TextInputType.SENDER_EMAIL}
|
||||
/>
|
||||
</Center>
|
||||
</Flex>
|
||||
</Stack>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default EmailConfigurations;
|
||||
export default EmailConfigurations;
|
||||
|
@@ -126,6 +126,40 @@ const Features = ({ variables, setVariables }: any) => {
|
||||
</Flex>
|
||||
</Flex>
|
||||
</Stack>
|
||||
<Divider paddingY={5} />
|
||||
<Text fontSize="md" paddingTop={5} fontWeight="bold" mb={5}>
|
||||
Cookie Security Features
|
||||
</Text>
|
||||
<Stack spacing={6}>
|
||||
<Flex>
|
||||
<Flex w="100%" alignItems="baseline" flexDir="column">
|
||||
<Text fontSize="sm">Use Secure App Cookie:</Text>
|
||||
<Text fontSize="x-small">
|
||||
Note: If you set this to insecure, it will set{' '}
|
||||
<code>sameSite</code> property of cookie to <code>lax</code> mode
|
||||
</Text>
|
||||
</Flex>
|
||||
<Flex justifyContent="start">
|
||||
<InputField
|
||||
variables={variables}
|
||||
setVariables={setVariables}
|
||||
inputType={SwitchInputType.APP_COOKIE_SECURE}
|
||||
/>
|
||||
</Flex>
|
||||
</Flex>
|
||||
<Flex>
|
||||
<Flex w="100%" alignItems="baseline" flexDir="column">
|
||||
<Text fontSize="sm">Use Secure Admin Cookie:</Text>
|
||||
</Flex>
|
||||
<Flex justifyContent="start">
|
||||
<InputField
|
||||
variables={variables}
|
||||
setVariables={setVariables}
|
||||
inputType={SwitchInputType.ADMIN_COOKIE_SECURE}
|
||||
/>
|
||||
</Flex>
|
||||
</Flex>
|
||||
</Stack>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@@ -37,7 +37,7 @@ const JSTConfigurations = ({
|
||||
JSON.stringify({
|
||||
type: variables.JWT_TYPE,
|
||||
key: variables.JWT_PUBLIC_KEY || variables.JWT_SECRET,
|
||||
})
|
||||
}),
|
||||
);
|
||||
toast({
|
||||
title: `JWT config copied successfully`,
|
||||
|
@@ -1,60 +1,60 @@
|
||||
import React from "react";
|
||||
import { Flex, Stack, Center, Text, useMediaQuery } from "@chakra-ui/react";
|
||||
import InputField from "../InputField";
|
||||
import { TextInputType } from "../../constants";
|
||||
import React from 'react';
|
||||
import { Flex, Stack, Center, Text, useMediaQuery } from '@chakra-ui/react';
|
||||
import InputField from '../InputField';
|
||||
import { TextInputType } from '../../constants';
|
||||
|
||||
const OrganizationInfo = ({ variables, setVariables }: any) => {
|
||||
const [isNotSmallerScreen] = useMediaQuery("(min-width:600px)");
|
||||
return (
|
||||
<div>
|
||||
{" "}
|
||||
<Text fontSize="md" paddingTop="2%" fontWeight="bold" mb={5}>
|
||||
Organization Information
|
||||
</Text>
|
||||
<Stack spacing={6} padding="2% 0%">
|
||||
<Flex direction={isNotSmallerScreen ? "row" : "column"}>
|
||||
<Flex
|
||||
w={isNotSmallerScreen ? "30%" : "40%"}
|
||||
justifyContent="start"
|
||||
alignItems="center"
|
||||
>
|
||||
<Text fontSize="sm">Organization Name:</Text>
|
||||
</Flex>
|
||||
<Center
|
||||
w={isNotSmallerScreen ? "70%" : "100%"}
|
||||
mt={isNotSmallerScreen ? "0" : "3"}
|
||||
>
|
||||
<InputField
|
||||
borderRadius={5}
|
||||
variables={variables}
|
||||
setVariables={setVariables}
|
||||
inputType={TextInputType.ORGANIZATION_NAME}
|
||||
/>
|
||||
</Center>
|
||||
</Flex>
|
||||
<Flex direction={isNotSmallerScreen ? "row" : "column"}>
|
||||
<Flex
|
||||
w={isNotSmallerScreen ? "30%" : "40%"}
|
||||
justifyContent="start"
|
||||
alignItems="center"
|
||||
>
|
||||
<Text fontSize="sm">Organization Logo:</Text>
|
||||
</Flex>
|
||||
<Center
|
||||
w={isNotSmallerScreen ? "70%" : "100%"}
|
||||
mt={isNotSmallerScreen ? "0" : "3"}
|
||||
>
|
||||
<InputField
|
||||
borderRadius={5}
|
||||
variables={variables}
|
||||
setVariables={setVariables}
|
||||
inputType={TextInputType.ORGANIZATION_LOGO}
|
||||
/>
|
||||
</Center>
|
||||
</Flex>
|
||||
</Stack>
|
||||
</div>
|
||||
);
|
||||
const [isNotSmallerScreen] = useMediaQuery('(min-width:600px)');
|
||||
return (
|
||||
<div>
|
||||
{' '}
|
||||
<Text fontSize="md" paddingTop="2%" fontWeight="bold" mb={5}>
|
||||
Organization Information
|
||||
</Text>
|
||||
<Stack spacing={6} padding="2% 0%">
|
||||
<Flex direction={isNotSmallerScreen ? 'row' : 'column'}>
|
||||
<Flex
|
||||
w={isNotSmallerScreen ? '30%' : '40%'}
|
||||
justifyContent="start"
|
||||
alignItems="center"
|
||||
>
|
||||
<Text fontSize="sm">Organization Name:</Text>
|
||||
</Flex>
|
||||
<Center
|
||||
w={isNotSmallerScreen ? '70%' : '100%'}
|
||||
mt={isNotSmallerScreen ? '0' : '3'}
|
||||
>
|
||||
<InputField
|
||||
borderRadius={5}
|
||||
variables={variables}
|
||||
setVariables={setVariables}
|
||||
inputType={TextInputType.ORGANIZATION_NAME}
|
||||
/>
|
||||
</Center>
|
||||
</Flex>
|
||||
<Flex direction={isNotSmallerScreen ? 'row' : 'column'}>
|
||||
<Flex
|
||||
w={isNotSmallerScreen ? '30%' : '40%'}
|
||||
justifyContent="start"
|
||||
alignItems="center"
|
||||
>
|
||||
<Text fontSize="sm">Organization Logo:</Text>
|
||||
</Flex>
|
||||
<Center
|
||||
w={isNotSmallerScreen ? '70%' : '100%'}
|
||||
mt={isNotSmallerScreen ? '0' : '3'}
|
||||
>
|
||||
<InputField
|
||||
borderRadius={5}
|
||||
variables={variables}
|
||||
setVariables={setVariables}
|
||||
inputType={TextInputType.ORGANIZATION_LOGO}
|
||||
/>
|
||||
</Center>
|
||||
</Flex>
|
||||
</Stack>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default OrganizationInfo;
|
||||
export default OrganizationInfo;
|
||||
|
@@ -1,138 +1,138 @@
|
||||
import React from "react";
|
||||
import React from 'react';
|
||||
import {
|
||||
Flex,
|
||||
Stack,
|
||||
Center,
|
||||
Text,
|
||||
Input,
|
||||
InputGroup,
|
||||
InputRightElement,
|
||||
useMediaQuery,
|
||||
} from "@chakra-ui/react";
|
||||
import { FaRegEyeSlash, FaRegEye } from "react-icons/fa";
|
||||
import InputField from "../InputField";
|
||||
import { HiddenInputType } from "../../constants";
|
||||
Flex,
|
||||
Stack,
|
||||
Center,
|
||||
Text,
|
||||
Input,
|
||||
InputGroup,
|
||||
InputRightElement,
|
||||
useMediaQuery,
|
||||
} from '@chakra-ui/react';
|
||||
import { FaRegEyeSlash, FaRegEye } from 'react-icons/fa';
|
||||
import InputField from '../InputField';
|
||||
import { HiddenInputType } from '../../constants';
|
||||
const SecurityAdminSecret = ({
|
||||
variables,
|
||||
setVariables,
|
||||
fieldVisibility,
|
||||
setFieldVisibility,
|
||||
validateAdminSecretHandler,
|
||||
adminSecret,
|
||||
variables,
|
||||
setVariables,
|
||||
fieldVisibility,
|
||||
setFieldVisibility,
|
||||
validateAdminSecretHandler,
|
||||
adminSecret,
|
||||
}: any) => {
|
||||
const [isNotSmallerScreen] = useMediaQuery("(min-width:600px)");
|
||||
return (
|
||||
<div>
|
||||
{" "}
|
||||
<Text fontSize="md" paddingTop="2%" fontWeight="bold">
|
||||
Security (Admin Secret)
|
||||
</Text>
|
||||
<Stack
|
||||
spacing={6}
|
||||
padding="0 5%"
|
||||
marginTop="3%"
|
||||
border="1px solid #ff7875"
|
||||
borderRadius="5px"
|
||||
>
|
||||
<Flex
|
||||
marginTop={isNotSmallerScreen ? "3%" : "5%"}
|
||||
direction={isNotSmallerScreen ? "row" : "column"}
|
||||
>
|
||||
<Flex
|
||||
mt={3}
|
||||
w={isNotSmallerScreen ? "30%" : "40%"}
|
||||
justifyContent="start"
|
||||
alignItems="center"
|
||||
>
|
||||
<Text fontSize="sm">Old Admin Secret:</Text>
|
||||
</Flex>
|
||||
<Center
|
||||
w={isNotSmallerScreen ? "70%" : "100%"}
|
||||
mt={isNotSmallerScreen ? "0" : "3"}
|
||||
>
|
||||
<InputGroup size="sm">
|
||||
<Input
|
||||
borderRadius={5}
|
||||
size="sm"
|
||||
placeholder="Enter Old Admin Secret"
|
||||
value={adminSecret.value as string}
|
||||
onChange={(event: any) => validateAdminSecretHandler(event)}
|
||||
type={
|
||||
!fieldVisibility[HiddenInputType.OLD_ADMIN_SECRET]
|
||||
? "password"
|
||||
: "text"
|
||||
}
|
||||
/>
|
||||
<InputRightElement
|
||||
right="5px"
|
||||
children={
|
||||
<Flex>
|
||||
{fieldVisibility[HiddenInputType.OLD_ADMIN_SECRET] ? (
|
||||
<Center
|
||||
w="25px"
|
||||
margin="0 1.5%"
|
||||
cursor="pointer"
|
||||
onClick={() =>
|
||||
setFieldVisibility({
|
||||
...fieldVisibility,
|
||||
[HiddenInputType.OLD_ADMIN_SECRET]: false,
|
||||
})
|
||||
}
|
||||
>
|
||||
<FaRegEyeSlash color="#bfbfbf" />
|
||||
</Center>
|
||||
) : (
|
||||
<Center
|
||||
w="25px"
|
||||
margin="0 1.5%"
|
||||
cursor="pointer"
|
||||
onClick={() =>
|
||||
setFieldVisibility({
|
||||
...fieldVisibility,
|
||||
[HiddenInputType.OLD_ADMIN_SECRET]: true,
|
||||
})
|
||||
}
|
||||
>
|
||||
<FaRegEye color="#bfbfbf" />
|
||||
</Center>
|
||||
)}
|
||||
</Flex>
|
||||
}
|
||||
/>
|
||||
</InputGroup>
|
||||
</Center>
|
||||
</Flex>
|
||||
<Flex
|
||||
paddingBottom="3%"
|
||||
direction={isNotSmallerScreen ? "row" : "column"}
|
||||
>
|
||||
<Flex
|
||||
w={isNotSmallerScreen ? "30%" : "50%"}
|
||||
justifyContent="start"
|
||||
alignItems="center"
|
||||
>
|
||||
<Text fontSize="sm">New Admin Secret:</Text>
|
||||
</Flex>
|
||||
<Center
|
||||
w={isNotSmallerScreen ? "70%" : "100%"}
|
||||
mt={isNotSmallerScreen ? "0" : "3"}
|
||||
>
|
||||
<InputField
|
||||
borderRadius={5}
|
||||
mb={3}
|
||||
variables={variables}
|
||||
setVariables={setVariables}
|
||||
inputType={HiddenInputType.ADMIN_SECRET}
|
||||
fieldVisibility={fieldVisibility}
|
||||
setFieldVisibility={setFieldVisibility}
|
||||
isDisabled={adminSecret.disableInputField}
|
||||
placeholder="Enter New Admin Secret"
|
||||
/>
|
||||
</Center>
|
||||
</Flex>
|
||||
</Stack>
|
||||
</div>
|
||||
);
|
||||
const [isNotSmallerScreen] = useMediaQuery('(min-width:600px)');
|
||||
return (
|
||||
<div>
|
||||
{' '}
|
||||
<Text fontSize="md" paddingTop="2%" fontWeight="bold">
|
||||
Security (Admin Secret)
|
||||
</Text>
|
||||
<Stack
|
||||
spacing={6}
|
||||
padding="0 5%"
|
||||
marginTop="3%"
|
||||
border="1px solid #ff7875"
|
||||
borderRadius="5px"
|
||||
>
|
||||
<Flex
|
||||
marginTop={isNotSmallerScreen ? '3%' : '5%'}
|
||||
direction={isNotSmallerScreen ? 'row' : 'column'}
|
||||
>
|
||||
<Flex
|
||||
mt={3}
|
||||
w={isNotSmallerScreen ? '30%' : '40%'}
|
||||
justifyContent="start"
|
||||
alignItems="center"
|
||||
>
|
||||
<Text fontSize="sm">Old Admin Secret:</Text>
|
||||
</Flex>
|
||||
<Center
|
||||
w={isNotSmallerScreen ? '70%' : '100%'}
|
||||
mt={isNotSmallerScreen ? '0' : '3'}
|
||||
>
|
||||
<InputGroup size="sm">
|
||||
<Input
|
||||
borderRadius={5}
|
||||
size="sm"
|
||||
placeholder="Enter Old Admin Secret"
|
||||
value={adminSecret.value as string}
|
||||
onChange={(event: any) => validateAdminSecretHandler(event)}
|
||||
type={
|
||||
!fieldVisibility[HiddenInputType.OLD_ADMIN_SECRET]
|
||||
? 'password'
|
||||
: 'text'
|
||||
}
|
||||
/>
|
||||
<InputRightElement
|
||||
right="5px"
|
||||
children={
|
||||
<Flex>
|
||||
{fieldVisibility[HiddenInputType.OLD_ADMIN_SECRET] ? (
|
||||
<Center
|
||||
w="25px"
|
||||
margin="0 1.5%"
|
||||
cursor="pointer"
|
||||
onClick={() =>
|
||||
setFieldVisibility({
|
||||
...fieldVisibility,
|
||||
[HiddenInputType.OLD_ADMIN_SECRET]: false,
|
||||
})
|
||||
}
|
||||
>
|
||||
<FaRegEyeSlash color="#bfbfbf" />
|
||||
</Center>
|
||||
) : (
|
||||
<Center
|
||||
w="25px"
|
||||
margin="0 1.5%"
|
||||
cursor="pointer"
|
||||
onClick={() =>
|
||||
setFieldVisibility({
|
||||
...fieldVisibility,
|
||||
[HiddenInputType.OLD_ADMIN_SECRET]: true,
|
||||
})
|
||||
}
|
||||
>
|
||||
<FaRegEye color="#bfbfbf" />
|
||||
</Center>
|
||||
)}
|
||||
</Flex>
|
||||
}
|
||||
/>
|
||||
</InputGroup>
|
||||
</Center>
|
||||
</Flex>
|
||||
<Flex
|
||||
paddingBottom="3%"
|
||||
direction={isNotSmallerScreen ? 'row' : 'column'}
|
||||
>
|
||||
<Flex
|
||||
w={isNotSmallerScreen ? '30%' : '50%'}
|
||||
justifyContent="start"
|
||||
alignItems="center"
|
||||
>
|
||||
<Text fontSize="sm">New Admin Secret:</Text>
|
||||
</Flex>
|
||||
<Center
|
||||
w={isNotSmallerScreen ? '70%' : '100%'}
|
||||
mt={isNotSmallerScreen ? '0' : '3'}
|
||||
>
|
||||
<InputField
|
||||
borderRadius={5}
|
||||
mb={3}
|
||||
variables={variables}
|
||||
setVariables={setVariables}
|
||||
inputType={HiddenInputType.ADMIN_SECRET}
|
||||
fieldVisibility={fieldVisibility}
|
||||
setFieldVisibility={setFieldVisibility}
|
||||
isDisabled={adminSecret.disableInputField}
|
||||
placeholder="Enter New Admin Secret"
|
||||
/>
|
||||
</Center>
|
||||
</Flex>
|
||||
</Stack>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SecurityAdminSecret;
|
||||
export default SecurityAdminSecret;
|
||||
|
@@ -167,7 +167,7 @@ const GenerateKeysModal = ({ jwtType, getData }: propTypes) => {
|
||||
) : (
|
||||
<>
|
||||
{Object.values(HMACEncryptionType).includes(
|
||||
stateVariables.JWT_TYPE
|
||||
stateVariables.JWT_TYPE,
|
||||
) ? (
|
||||
<Flex marginTop="8">
|
||||
<Flex w="23%" justifyContent="start" alignItems="center">
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import React from 'react';
|
||||
import React, { useState } from 'react';
|
||||
import {
|
||||
Box,
|
||||
Flex,
|
||||
@@ -13,6 +13,12 @@ import {
|
||||
Textarea,
|
||||
Switch,
|
||||
Text,
|
||||
MenuButton,
|
||||
MenuList,
|
||||
MenuItemOption,
|
||||
MenuOptionGroup,
|
||||
Button,
|
||||
Menu,
|
||||
} from '@chakra-ui/react';
|
||||
import {
|
||||
FaRegClone,
|
||||
@@ -20,6 +26,7 @@ import {
|
||||
FaRegEyeSlash,
|
||||
FaPlus,
|
||||
FaTimes,
|
||||
FaAngleDown,
|
||||
} from 'react-icons/fa';
|
||||
import {
|
||||
ArrayInputOperations,
|
||||
@@ -30,6 +37,7 @@ import {
|
||||
TextAreaInputType,
|
||||
SwitchInputType,
|
||||
DateInputType,
|
||||
MultiSelectInputType,
|
||||
} from '../constants';
|
||||
import { copyTextToClipboard } from '../utils';
|
||||
|
||||
@@ -39,13 +47,16 @@ const InputField = ({
|
||||
setVariables,
|
||||
fieldVisibility,
|
||||
setFieldVisibility,
|
||||
availableRoles,
|
||||
...downshiftProps
|
||||
}: any) => {
|
||||
const props = {
|
||||
size: 'sm',
|
||||
...downshiftProps,
|
||||
};
|
||||
const [inputFieldVisibility, setInputFieldVisibility] = React.useState<
|
||||
const [availableUserRoles, setAvailableUserRoles] =
|
||||
useState<string[]>(availableRoles);
|
||||
const [inputFieldVisibility, setInputFieldVisibility] = useState<
|
||||
Record<string, boolean>
|
||||
>({
|
||||
ROLES: false,
|
||||
@@ -54,7 +65,7 @@ const InputField = ({
|
||||
ALLOWED_ORIGINS: false,
|
||||
roles: false,
|
||||
});
|
||||
const [inputData, setInputData] = React.useState<Record<string, string>>({
|
||||
const [inputData, setInputData] = useState<Record<string, string>>({
|
||||
ROLES: '',
|
||||
DEFAULT_ROLES: '',
|
||||
PROTECTED_ROLES: '',
|
||||
@@ -64,7 +75,7 @@ const InputField = ({
|
||||
const updateInputHandler = (
|
||||
type: string,
|
||||
operation: any,
|
||||
role: string = ''
|
||||
role: string = '',
|
||||
) => {
|
||||
if (operation === ArrayInputOperations.APPEND) {
|
||||
if (inputData[type] !== '') {
|
||||
@@ -78,7 +89,7 @@ const InputField = ({
|
||||
}
|
||||
if (operation === ArrayInputOperations.REMOVE) {
|
||||
let updatedEnvVars = variables[type].filter(
|
||||
(item: string) => item !== role
|
||||
(item: string) => item !== role,
|
||||
);
|
||||
setVariables({
|
||||
...variables,
|
||||
@@ -95,7 +106,7 @@ const InputField = ({
|
||||
onChange={(
|
||||
event: Event & {
|
||||
target: HTMLInputElement;
|
||||
}
|
||||
},
|
||||
) =>
|
||||
setVariables({
|
||||
...variables,
|
||||
@@ -116,11 +127,11 @@ const InputField = ({
|
||||
<InputGroup size="sm">
|
||||
<Input
|
||||
{...props}
|
||||
value={variables[inputType] ?? ''}
|
||||
value={variables[inputType] || ''}
|
||||
onChange={(
|
||||
event: Event & {
|
||||
target: HTMLInputElement;
|
||||
}
|
||||
},
|
||||
) =>
|
||||
setVariables({
|
||||
...variables,
|
||||
@@ -207,7 +218,7 @@ const InputField = ({
|
||||
updateInputHandler(
|
||||
inputType,
|
||||
ArrayInputOperations.REMOVE,
|
||||
role
|
||||
role,
|
||||
)
|
||||
}
|
||||
/>
|
||||
@@ -221,7 +232,7 @@ const InputField = ({
|
||||
size="xs"
|
||||
minW="150px"
|
||||
placeholder="add a new value"
|
||||
value={inputData[inputType] ?? ''}
|
||||
value={inputData[inputType] || ''}
|
||||
onChange={(e: any) => {
|
||||
setInputData({ ...inputData, [inputType]: e.target.value });
|
||||
}}
|
||||
@@ -278,6 +289,87 @@ const InputField = ({
|
||||
</Select>
|
||||
);
|
||||
}
|
||||
if (Object.values(MultiSelectInputType).includes(inputType)) {
|
||||
return (
|
||||
<Flex w="100%" style={{ position: 'relative' }}>
|
||||
<Flex
|
||||
border="1px solid #e2e8f0"
|
||||
w="100%"
|
||||
borderRadius="var(--chakra-radii-sm)"
|
||||
p="1% 0 0 2.5%"
|
||||
overflowX={variables[inputType].length > 3 ? 'scroll' : 'hidden'}
|
||||
overflowY="hidden"
|
||||
justifyContent="space-between"
|
||||
alignItems="center"
|
||||
>
|
||||
<Flex justifyContent="start" alignItems="center" w="100%" wrap="wrap">
|
||||
{variables[inputType].map((role: string, index: number) => (
|
||||
<Box key={index} margin="0.5%" role="group">
|
||||
<Tag
|
||||
size="sm"
|
||||
variant="outline"
|
||||
colorScheme="gray"
|
||||
minW="fit-content"
|
||||
>
|
||||
<TagLabel cursor="default">{role}</TagLabel>
|
||||
<TagRightIcon
|
||||
boxSize="12px"
|
||||
as={FaTimes}
|
||||
display="none"
|
||||
cursor="pointer"
|
||||
_groupHover={{ display: 'block' }}
|
||||
onClick={() =>
|
||||
updateInputHandler(
|
||||
inputType,
|
||||
ArrayInputOperations.REMOVE,
|
||||
role,
|
||||
)
|
||||
}
|
||||
/>
|
||||
</Tag>
|
||||
</Box>
|
||||
))}
|
||||
</Flex>
|
||||
<Menu matchWidth={true}>
|
||||
<MenuButton px="10px" py="7.5px">
|
||||
<FaAngleDown />
|
||||
</MenuButton>
|
||||
<MenuList
|
||||
position="absolute"
|
||||
top="0"
|
||||
right="0"
|
||||
zIndex="10"
|
||||
maxH="150"
|
||||
overflowX="scroll"
|
||||
>
|
||||
<MenuOptionGroup
|
||||
title={undefined}
|
||||
value={variables[inputType]}
|
||||
type="checkbox"
|
||||
onChange={(values: string[] | string) => {
|
||||
setVariables({
|
||||
...variables,
|
||||
[inputType]: values,
|
||||
});
|
||||
}}
|
||||
>
|
||||
{availableUserRoles.map((role) => {
|
||||
return (
|
||||
<MenuItemOption
|
||||
key={`multiselect-menu-${role}`}
|
||||
value={role}
|
||||
>
|
||||
{role}
|
||||
</MenuItemOption>
|
||||
);
|
||||
})}
|
||||
</MenuOptionGroup>
|
||||
</MenuList>
|
||||
</Menu>
|
||||
</Flex>
|
||||
</Flex>
|
||||
);
|
||||
}
|
||||
if (Object.values(TextAreaInputType).includes(inputType)) {
|
||||
return (
|
||||
<Textarea
|
||||
@@ -288,7 +380,7 @@ const InputField = ({
|
||||
onChange={(
|
||||
event: Event & {
|
||||
target: HTMLInputElement;
|
||||
}
|
||||
},
|
||||
) =>
|
||||
setVariables({
|
||||
...variables,
|
||||
|
@@ -304,7 +304,7 @@ const InviteMembersModal = ({
|
||||
onClick={() =>
|
||||
updateEmailListHandler(
|
||||
ArrayInputOperations.REMOVE,
|
||||
index
|
||||
index,
|
||||
)
|
||||
}
|
||||
>
|
||||
|
@@ -218,7 +218,7 @@ export const Sidebar = ({ onClose, ...rest }: SidebarProps) => {
|
||||
</NavItem>{' '}
|
||||
</Text>
|
||||
</NavLink>
|
||||
)
|
||||
),
|
||||
)}
|
||||
<Link
|
||||
href="/playground"
|
||||
|
@@ -185,7 +185,7 @@ const UpdateEmailTemplate = ({
|
||||
toast({
|
||||
title: capitalizeFirstLetter(
|
||||
res.data?._add_email_template?.message ||
|
||||
res.data?._update_email_template?.message
|
||||
res.data?._update_email_template?.message,
|
||||
),
|
||||
isClosable: true,
|
||||
status: 'success',
|
||||
@@ -220,7 +220,7 @@ const UpdateEmailTemplate = ({
|
||||
}, [isOpen]);
|
||||
useEffect(() => {
|
||||
const updatedTemplateVariables = Object.entries(
|
||||
emailTemplateVariables
|
||||
emailTemplateVariables,
|
||||
).reduce((acc, [key, val]): any => {
|
||||
if (
|
||||
(templateData[EmailTemplateInputDataFields.EVENT_NAME] !==
|
||||
@@ -367,7 +367,7 @@ const UpdateEmailTemplate = ({
|
||||
onChange={(e) =>
|
||||
inputChangehandler(
|
||||
EmailTemplateInputDataFields.EVENT_NAME,
|
||||
e.currentTarget.value
|
||||
e.currentTarget.value,
|
||||
)
|
||||
}
|
||||
>
|
||||
@@ -376,7 +376,7 @@ const UpdateEmailTemplate = ({
|
||||
<option value={value} key={key}>
|
||||
{key}
|
||||
</option>
|
||||
)
|
||||
),
|
||||
)}
|
||||
</Select>
|
||||
</Flex>
|
||||
@@ -401,7 +401,7 @@ const UpdateEmailTemplate = ({
|
||||
onChange={(e) =>
|
||||
inputChangehandler(
|
||||
EmailTemplateInputDataFields.SUBJECT,
|
||||
e.currentTarget.value
|
||||
e.currentTarget.value,
|
||||
)
|
||||
}
|
||||
/>
|
||||
|
@@ -126,13 +126,13 @@ const UpdateWebhookModal = ({
|
||||
...initWebhookValidatorData,
|
||||
});
|
||||
const [verifiedStatus, setVerifiedStatus] = useState<webhookVerifiedStatus>(
|
||||
webhookVerifiedStatus.PENDING
|
||||
webhookVerifiedStatus.PENDING,
|
||||
);
|
||||
const inputChangehandler = (
|
||||
inputType: string,
|
||||
value: any,
|
||||
headerInputType: string = WebhookInputHeaderFields.KEY,
|
||||
headerIndex: number = 0
|
||||
headerIndex: number = 0,
|
||||
) => {
|
||||
if (
|
||||
verifiedStatus !== webhookVerifiedStatus.PENDING &&
|
||||
@@ -238,7 +238,7 @@ const UpdateWebhookModal = ({
|
||||
validator[WebhookInputDataFields.ENDPOINT] &&
|
||||
!validator[WebhookInputDataFields.HEADERS].some(
|
||||
(headerData: headersValidatorDataType) =>
|
||||
!headerData.key || !headerData.value
|
||||
!headerData.key || !headerData.value,
|
||||
)
|
||||
);
|
||||
};
|
||||
@@ -256,7 +256,7 @@ const UpdateWebhookModal = ({
|
||||
(acc, data) => {
|
||||
return data.key ? { ...acc, [data.key]: data.value } : acc;
|
||||
},
|
||||
{}
|
||||
{},
|
||||
);
|
||||
if (Object.keys(headers).length) {
|
||||
params[WebhookInputDataFields.HEADERS] = headers;
|
||||
@@ -295,7 +295,7 @@ const UpdateWebhookModal = ({
|
||||
} else if (res.data?._add_webhook || res.data?._update_webhook) {
|
||||
toast({
|
||||
title: capitalizeFirstLetter(
|
||||
res.data?._add_webhook?.message || res.data?._update_webhook?.message
|
||||
res.data?._add_webhook?.message || res.data?._update_webhook?.message,
|
||||
),
|
||||
isClosable: true,
|
||||
status: 'success',
|
||||
@@ -333,7 +333,7 @@ const UpdateWebhookModal = ({
|
||||
setValidator({
|
||||
...validator,
|
||||
[WebhookInputDataFields.HEADERS]: new Array(
|
||||
formattedHeadersData.length
|
||||
formattedHeadersData.length,
|
||||
)
|
||||
.fill({})
|
||||
.map(() => ({ ...initHeadersValidatorData })),
|
||||
@@ -406,7 +406,7 @@ const UpdateWebhookModal = ({
|
||||
onChange={(e) =>
|
||||
inputChangehandler(
|
||||
WebhookInputDataFields.EVENT_NAME,
|
||||
e.currentTarget.value
|
||||
e.currentTarget.value,
|
||||
)
|
||||
}
|
||||
>
|
||||
@@ -415,7 +415,7 @@ const UpdateWebhookModal = ({
|
||||
<option value={value} key={key}>
|
||||
{key}
|
||||
</option>
|
||||
)
|
||||
),
|
||||
)}
|
||||
</Select>
|
||||
</Flex>
|
||||
@@ -438,7 +438,7 @@ const UpdateWebhookModal = ({
|
||||
onChange={(e) =>
|
||||
inputChangehandler(
|
||||
WebhookInputDataFields.ENDPOINT,
|
||||
e.currentTarget.value
|
||||
e.currentTarget.value,
|
||||
)
|
||||
}
|
||||
/>
|
||||
@@ -462,7 +462,7 @@ const UpdateWebhookModal = ({
|
||||
onChange={() =>
|
||||
inputChangehandler(
|
||||
WebhookInputDataFields.ENABLED,
|
||||
!webhook[WebhookInputDataFields.ENABLED]
|
||||
!webhook[WebhookInputDataFields.ENABLED],
|
||||
)
|
||||
}
|
||||
/>
|
||||
@@ -517,7 +517,7 @@ const UpdateWebhookModal = ({
|
||||
WebhookInputDataFields.HEADERS,
|
||||
e.target.value,
|
||||
WebhookInputHeaderFields.KEY,
|
||||
index
|
||||
index,
|
||||
)
|
||||
}
|
||||
width="30%"
|
||||
@@ -540,7 +540,7 @@ const UpdateWebhookModal = ({
|
||||
WebhookInputDataFields.HEADERS,
|
||||
e.target.value,
|
||||
WebhookInputHeaderFields.VALUE,
|
||||
index
|
||||
index,
|
||||
)
|
||||
}
|
||||
width="65%"
|
||||
@@ -560,7 +560,7 @@ const UpdateWebhookModal = ({
|
||||
</InputRightElement>
|
||||
</InputGroup>
|
||||
</Flex>
|
||||
)
|
||||
),
|
||||
)}
|
||||
</Flex>
|
||||
<Divider marginY={5} />
|
||||
|
@@ -161,15 +161,15 @@ const ViewWebhookLogsModal = ({
|
||||
<Td>
|
||||
<Text fontSize="sm">{`${logData.id.substring(
|
||||
0,
|
||||
5
|
||||
5,
|
||||
)}***${logData.id.substring(
|
||||
logData.id.length - 5,
|
||||
logData.id.length
|
||||
logData.id.length,
|
||||
)}`}</Text>
|
||||
</Td>
|
||||
<Td>
|
||||
{dayjs(logData.created_at * 1000).format(
|
||||
'MMM DD, YYYY'
|
||||
'MMM DD, YYYY',
|
||||
)}
|
||||
</Td>
|
||||
<Td>
|
||||
|
@@ -15,6 +15,7 @@ export const TextInputType = {
|
||||
SMTP_HOST: 'SMTP_HOST',
|
||||
SMTP_PORT: 'SMTP_PORT',
|
||||
SMTP_USERNAME: 'SMTP_USERNAME',
|
||||
SMTP_LOCAL_NAME: 'SMTP_LOCAL_NAME',
|
||||
SENDER_EMAIL: 'SENDER_EMAIL',
|
||||
ORGANIZATION_NAME: 'ORGANIZATION_NAME',
|
||||
ORGANIZATION_LOGO: 'ORGANIZATION_LOGO',
|
||||
@@ -48,7 +49,6 @@ export const ArrayInputType = {
|
||||
DEFAULT_ROLES: 'DEFAULT_ROLES',
|
||||
PROTECTED_ROLES: 'PROTECTED_ROLES',
|
||||
ALLOWED_ORIGINS: 'ALLOWED_ORIGINS',
|
||||
USER_ROLES: 'roles',
|
||||
};
|
||||
|
||||
export const SelectInputType = {
|
||||
@@ -56,6 +56,10 @@ export const SelectInputType = {
|
||||
GENDER: 'gender',
|
||||
};
|
||||
|
||||
export const MultiSelectInputType = {
|
||||
USER_ROLES: 'roles',
|
||||
};
|
||||
|
||||
export const TextAreaInputType = {
|
||||
CUSTOM_ACCESS_TOKEN_SCRIPT: 'CUSTOM_ACCESS_TOKEN_SCRIPT',
|
||||
JWT_PRIVATE_KEY: 'JWT_PRIVATE_KEY',
|
||||
@@ -63,6 +67,8 @@ export const TextAreaInputType = {
|
||||
};
|
||||
|
||||
export const SwitchInputType = {
|
||||
APP_COOKIE_SECURE: 'APP_COOKIE_SECURE',
|
||||
ADMIN_COOKIE_SECURE: 'ADMIN_COOKIE_SECURE',
|
||||
DISABLE_LOGIN_PAGE: 'DISABLE_LOGIN_PAGE',
|
||||
DISABLE_MAGIC_LINK_LOGIN: 'DISABLE_MAGIC_LINK_LOGIN',
|
||||
DISABLE_EMAIL_VERIFICATION: 'DISABLE_EMAIL_VERIFICATION',
|
||||
@@ -127,12 +133,15 @@ export interface envVarTypes {
|
||||
SMTP_PORT: string;
|
||||
SMTP_USERNAME: string;
|
||||
SMTP_PASSWORD: string;
|
||||
SMTP_LOCAL_NAME: string;
|
||||
SENDER_EMAIL: string;
|
||||
ALLOWED_ORIGINS: [string] | [];
|
||||
ORGANIZATION_NAME: string;
|
||||
ORGANIZATION_LOGO: string;
|
||||
CUSTOM_ACCESS_TOKEN_SCRIPT: string;
|
||||
ADMIN_SECRET: string;
|
||||
APP_COOKIE_SECURE: boolean;
|
||||
ADMIN_COOKIE_SECURE: boolean;
|
||||
DISABLE_LOGIN_PAGE: boolean;
|
||||
DISABLE_MAGIC_LINK_LOGIN: boolean;
|
||||
DISABLE_EMAIL_VERIFICATION: boolean;
|
||||
|
@@ -45,11 +45,14 @@ export const EnvVariablesQuery = `
|
||||
SMTP_PORT
|
||||
SMTP_USERNAME
|
||||
SMTP_PASSWORD
|
||||
SMTP_LOCAL_NAME
|
||||
SENDER_EMAIL
|
||||
ALLOWED_ORIGINS
|
||||
ORGANIZATION_NAME
|
||||
ORGANIZATION_LOGO
|
||||
ADMIN_SECRET
|
||||
APP_COOKIE_SECURE
|
||||
ADMIN_COOKIE_SECURE
|
||||
DISABLE_LOGIN_PAGE
|
||||
DISABLE_MAGIC_LINK_LOGIN
|
||||
DISABLE_EMAIL_VERIFICATION
|
||||
@@ -167,3 +170,12 @@ export const WebhookLogsQuery = `
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const GetAvailableRolesQuery = `
|
||||
query {
|
||||
_env {
|
||||
ROLES
|
||||
PROTECTED_ROLES
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
@@ -6,5 +6,5 @@ ReactDOM.render(
|
||||
<div>
|
||||
<App />
|
||||
</div>,
|
||||
document.getElementById('root')
|
||||
document.getElementById('root'),
|
||||
);
|
||||
|
@@ -154,7 +154,7 @@ const EmailTemplates = () => {
|
||||
<Td>{templateData[EmailTemplateInputDataFields.SUBJECT]}</Td>
|
||||
<Td>
|
||||
{dayjs(templateData.created_at * 1000).format(
|
||||
'MMM DD, YYYY'
|
||||
'MMM DD, YYYY',
|
||||
)}
|
||||
</Td>
|
||||
<Td>
|
||||
|
@@ -65,12 +65,15 @@ const Environment = () => {
|
||||
SMTP_PORT: '',
|
||||
SMTP_USERNAME: '',
|
||||
SMTP_PASSWORD: '',
|
||||
SMTP_LOCAL_NAME: '',
|
||||
SENDER_EMAIL: '',
|
||||
ALLOWED_ORIGINS: [],
|
||||
ORGANIZATION_NAME: '',
|
||||
ORGANIZATION_LOGO: '',
|
||||
CUSTOM_ACCESS_TOKEN_SCRIPT: '',
|
||||
ADMIN_SECRET: '',
|
||||
APP_COOKIE_SECURE: false,
|
||||
ADMIN_COOKIE_SECURE: false,
|
||||
DISABLE_LOGIN_PAGE: false,
|
||||
DISABLE_MAGIC_LINK_LOGIN: false,
|
||||
DISABLE_EMAIL_VERIFICATION: false,
|
||||
@@ -155,7 +158,7 @@ const Environment = () => {
|
||||
// @ts-ignore
|
||||
[property]: envVariables[property],
|
||||
}),
|
||||
{}
|
||||
{},
|
||||
);
|
||||
if (
|
||||
updatedEnvVariables[HiddenInputType.ADMIN_SECRET] === '' ||
|
||||
|
@@ -29,7 +29,7 @@ import {
|
||||
MenuItem,
|
||||
useToast,
|
||||
Spinner,
|
||||
TableContainer
|
||||
TableContainer,
|
||||
} from '@chakra-ui/react';
|
||||
import {
|
||||
FaAngleLeft,
|
||||
@@ -195,7 +195,7 @@ export default function Users() {
|
||||
|
||||
const updateAccessHandler = async (
|
||||
id: string,
|
||||
action: updateAccessActions
|
||||
action: updateAccessActions,
|
||||
) => {
|
||||
switch (action) {
|
||||
case updateAccessActions.ENABLE:
|
||||
@@ -263,8 +263,9 @@ export default function Users() {
|
||||
.toPromise();
|
||||
if (res.data?._update_user?.id) {
|
||||
toast({
|
||||
title: `Multi factor authentication ${user.is_multi_factor_auth_enabled ? 'disabled' : 'enabled'
|
||||
} for user`,
|
||||
title: `Multi factor authentication ${
|
||||
user.is_multi_factor_auth_enabled ? 'disabled' : 'enabled'
|
||||
} for user`,
|
||||
isClosable: true,
|
||||
status: 'success',
|
||||
position: 'bottom-right',
|
||||
@@ -387,7 +388,7 @@ export default function Users() {
|
||||
onClick={() =>
|
||||
updateAccessHandler(
|
||||
user.id,
|
||||
updateAccessActions.ENABLE
|
||||
updateAccessActions.ENABLE,
|
||||
)
|
||||
}
|
||||
>
|
||||
@@ -398,7 +399,7 @@ export default function Users() {
|
||||
onClick={() =>
|
||||
updateAccessHandler(
|
||||
user.id,
|
||||
updateAccessActions.REVOKE
|
||||
updateAccessActions.REVOKE,
|
||||
)
|
||||
}
|
||||
>
|
||||
@@ -407,13 +408,17 @@ export default function Users() {
|
||||
)}
|
||||
{user.is_multi_factor_auth_enabled ? (
|
||||
<MenuItem
|
||||
onClick={() => multiFactorAuthUpdateHandler(user)}
|
||||
onClick={() =>
|
||||
multiFactorAuthUpdateHandler(user)
|
||||
}
|
||||
>
|
||||
Disable MultiFactor Authentication
|
||||
</MenuItem>
|
||||
) : (
|
||||
<MenuItem
|
||||
onClick={() => multiFactorAuthUpdateHandler(user)}
|
||||
onClick={() =>
|
||||
multiFactorAuthUpdateHandler(user)
|
||||
}
|
||||
>
|
||||
Enable MultiFactor Authentication
|
||||
</MenuItem>
|
||||
|
@@ -170,12 +170,12 @@ const Webhooks = () => {
|
||||
label={JSON.stringify(
|
||||
webhook[WebhookInputDataFields.HEADERS],
|
||||
null,
|
||||
' '
|
||||
' ',
|
||||
)}
|
||||
>
|
||||
<Tag size="sm" variant="outline" colorScheme="gray">
|
||||
{Object.keys(
|
||||
webhook[WebhookInputDataFields.HEADERS] || {}
|
||||
webhook[WebhookInputDataFields.HEADERS] || {},
|
||||
)?.length.toString()}
|
||||
</Tag>
|
||||
</Tooltip>
|
||||
|
@@ -67,7 +67,7 @@ export const validateEmail = (email: string) => {
|
||||
return email
|
||||
.toLowerCase()
|
||||
.match(
|
||||
/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
|
||||
/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,
|
||||
)
|
||||
? true
|
||||
: false;
|
||||
@@ -78,7 +78,7 @@ export const validateURI = (uri: string) => {
|
||||
return uri
|
||||
.toLowerCase()
|
||||
.match(
|
||||
/(?:^|\s)((https?:\/\/)?(?:localhost|[\w-]+(?:\.[\w-]+)+)(:\d+)?(\/\S*)?)/
|
||||
/(?:^|\s)((https?:\/\/)?(?:localhost|[\w-]+(?:\.[\w-]+)+)(:\d+)?(\/\S*)?)/,
|
||||
)
|
||||
? true
|
||||
: false;
|
||||
|
@@ -27,7 +27,7 @@ const parseCSV = (file: File, delimiter: string): Promise<dataTypes[]> => {
|
||||
value: email.trim(),
|
||||
isInvalid: !validateEmail(email.trim()),
|
||||
};
|
||||
})
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
|
@@ -25,4 +25,6 @@ const (
|
||||
DbTypeCockroachDB = "cockroachdb"
|
||||
// DbTypePlanetScaleDB is the planetscale database type
|
||||
DbTypePlanetScaleDB = "planetscale"
|
||||
// DbTypeDynamoDB is the Dynamo database type
|
||||
DbTypeDynamoDB = "dynamodb"
|
||||
)
|
||||
|
@@ -21,6 +21,12 @@ const (
|
||||
EnvKeyDatabaseType = "DATABASE_TYPE"
|
||||
// EnvKeyDatabaseURL key for env variable DATABASE_URL
|
||||
EnvKeyDatabaseURL = "DATABASE_URL"
|
||||
// EnvAwsRegion key for env variable AWS REGION
|
||||
EnvAwsRegion = "AWS_REGION"
|
||||
// EnvAwsAccessKeyID key for env variable AWS_ACCESS_KEY_ID
|
||||
EnvAwsAccessKeyID = "AWS_ACCESS_KEY_ID"
|
||||
// EnvAwsAccessKey key for env variable AWS_SECRET_ACCESS_KEY
|
||||
EnvAwsSecretAccessKey = "AWS_SECRET_ACCESS_KEY"
|
||||
// EnvKeyDatabaseName key for env variable DATABASE_NAME
|
||||
EnvKeyDatabaseName = "DATABASE_NAME"
|
||||
// EnvKeyDatabaseUsername key for env variable DATABASE_USERNAME
|
||||
@@ -45,6 +51,8 @@ const (
|
||||
EnvKeySmtpUsername = "SMTP_USERNAME"
|
||||
// EnvKeySmtpPassword key for env variable SMTP_PASSWORD
|
||||
EnvKeySmtpPassword = "SMTP_PASSWORD"
|
||||
// EnvKeySmtpLocalName key for env variable SMTP_LOCAL_NAME
|
||||
EnvKeySmtpLocalName = "SMTP_LOCAL_NAME"
|
||||
// EnvKeySenderEmail key for env variable SENDER_EMAIL
|
||||
EnvKeySenderEmail = "SENDER_EMAIL"
|
||||
// EnvKeyIsEmailServiceEnabled key for env variable IS_EMAIL_SERVICE_ENABLED
|
||||
|
@@ -29,10 +29,20 @@ func SetSession(gc *gin.Context, sessionID string) {
|
||||
domain = "." + domain
|
||||
}
|
||||
|
||||
// Since app cookie can come from cross site it becomes important to set this in lax mode when insecure.
|
||||
// Example person using custom UI on their app domain and making request to authorizer domain.
|
||||
// For more information check:
|
||||
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite
|
||||
// https://github.com/gin-gonic/gin/blob/master/context.go#L86
|
||||
// TODO add ability to sameSite = none / strict from dashboard
|
||||
if !appCookieSecure {
|
||||
gc.SetSameSite(http.SameSiteLaxMode)
|
||||
} else {
|
||||
gc.SetSameSite(http.SameSiteNoneMode)
|
||||
}
|
||||
// TODO allow configuring from dashboard
|
||||
year := 60 * 60 * 24 * 365
|
||||
|
||||
gc.SetSameSite(http.SameSiteNoneMode)
|
||||
gc.SetCookie(constants.AppCookieName+"_session", sessionID, year, "/", host, secure, httpOnly)
|
||||
gc.SetCookie(constants.AppCookieName+"_session_domain", sessionID, year, "/", domain, secure, httpOnly)
|
||||
}
|
||||
|
@@ -7,6 +7,7 @@ import (
|
||||
"github.com/authorizerdev/authorizer/server/db/providers"
|
||||
"github.com/authorizerdev/authorizer/server/db/providers/arangodb"
|
||||
"github.com/authorizerdev/authorizer/server/db/providers/cassandradb"
|
||||
"github.com/authorizerdev/authorizer/server/db/providers/dynamodb"
|
||||
"github.com/authorizerdev/authorizer/server/db/providers/mongodb"
|
||||
"github.com/authorizerdev/authorizer/server/db/providers/sql"
|
||||
"github.com/authorizerdev/authorizer/server/memorystore"
|
||||
@@ -20,10 +21,11 @@ func InitDB() error {
|
||||
|
||||
envs := memorystore.RequiredEnvStoreObj.GetRequiredEnv()
|
||||
|
||||
isSQL := envs.DatabaseType != constants.DbTypeArangodb && envs.DatabaseType != constants.DbTypeMongodb && envs.DatabaseType != constants.DbTypeCassandraDB && envs.DatabaseType != constants.DbTypeScyllaDB
|
||||
isSQL := envs.DatabaseType != constants.DbTypeArangodb && envs.DatabaseType != constants.DbTypeMongodb && envs.DatabaseType != constants.DbTypeCassandraDB && envs.DatabaseType != constants.DbTypeScyllaDB && envs.DatabaseType != constants.DbTypeDynamoDB
|
||||
isArangoDB := envs.DatabaseType == constants.DbTypeArangodb
|
||||
isMongoDB := envs.DatabaseType == constants.DbTypeMongodb
|
||||
isCassandra := envs.DatabaseType == constants.DbTypeCassandraDB || envs.DatabaseType == constants.DbTypeScyllaDB
|
||||
isDynamoDB := envs.DatabaseType == constants.DbTypeDynamoDB
|
||||
|
||||
if isSQL {
|
||||
log.Info("Initializing SQL Driver for: ", envs.DatabaseType)
|
||||
@@ -61,5 +63,14 @@ func InitDB() error {
|
||||
}
|
||||
}
|
||||
|
||||
if isDynamoDB {
|
||||
log.Info("Initializing DynamoDB Driver for: ", envs.DatabaseType)
|
||||
Provider, err = dynamodb.NewProvider()
|
||||
if err != nil {
|
||||
log.Fatal("Failed to initialize DynamoDB driver: ", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@@ -9,14 +9,14 @@ import (
|
||||
|
||||
// EmailTemplate model for database
|
||||
type EmailTemplate struct {
|
||||
Key string `json:"_key,omitempty" bson:"_key,omitempty" cql:"_key,omitempty"` // for arangodb
|
||||
ID string `gorm:"primaryKey;type:char(36)" json:"_id" bson:"_id" cql:"id"`
|
||||
EventName string `gorm:"unique" json:"event_name" bson:"event_name" cql:"event_name"`
|
||||
Subject string `gorm:"type:text" json:"subject" bson:"subject" cql:"subject"`
|
||||
Template string `gorm:"type:text" json:"template" bson:"template" cql:"template"`
|
||||
Design string `gorm:"type:text" json:"design" bson:"design" cql:"design"`
|
||||
CreatedAt int64 `json:"created_at" bson:"created_at" cql:"created_at"`
|
||||
UpdatedAt int64 `json:"updated_at" bson:"updated_at" cql:"updated_at"`
|
||||
Key string `json:"_key,omitempty" bson:"_key,omitempty" cql:"_key,omitempty" dynamo:"key,omitempty"` // for arangodb
|
||||
ID string `gorm:"primaryKey;type:char(36)" json:"_id" bson:"_id" cql:"id" dynamo:"id,hash"`
|
||||
EventName string `gorm:"unique" json:"event_name" bson:"event_name" cql:"event_name" dynamo:"event_name" index:"event_name,hash"`
|
||||
Subject string `json:"subject" bson:"subject" cql:"subject" dynamo:"subject"`
|
||||
Template string `json:"template" bson:"template" cql:"template" dynamo:"template"`
|
||||
Design string `json:"design" bson:"design" cql:"design" dynamo:"design"`
|
||||
CreatedAt int64 `json:"created_at" bson:"created_at" cql:"created_at" dynamo:"created_at"`
|
||||
UpdatedAt int64 `json:"updated_at" bson:"updated_at" cql:"updated_at" dynamo:"updated_at"`
|
||||
}
|
||||
|
||||
// AsAPIEmailTemplate to return email template as graphql response object
|
||||
|
@@ -4,10 +4,10 @@ package models
|
||||
|
||||
// Env model for db
|
||||
type Env struct {
|
||||
Key string `json:"_key,omitempty" bson:"_key,omitempty" cql:"_key,omitempty"` // for arangodb
|
||||
ID string `gorm:"primaryKey;type:char(36)" json:"_id" bson:"_id" cql:"id"`
|
||||
EnvData string `gorm:"type:text" json:"env" bson:"env" cql:"env"`
|
||||
Hash string `gorm:"type:text" json:"hash" bson:"hash" cql:"hash"`
|
||||
UpdatedAt int64 `json:"updated_at" bson:"updated_at" cql:"updated_at"`
|
||||
CreatedAt int64 `json:"created_at" bson:"created_at" cql:"created_at"`
|
||||
Key string `json:"_key,omitempty" bson:"_key,omitempty" cql:"_key,omitempty" dynamo:"key,omitempty"` // for arangodb
|
||||
ID string `gorm:"primaryKey;type:char(36)" json:"_id" bson:"_id" cql:"id" dynamo:"id,hash"`
|
||||
EnvData string `json:"env" bson:"env" cql:"env" dynamo:"env"`
|
||||
Hash string `json:"hash" bson:"hash" cql:"hash" dynamo:"hash"`
|
||||
UpdatedAt int64 `json:"updated_at" bson:"updated_at" cql:"updated_at" dynamo:"updated_at"`
|
||||
CreatedAt int64 `json:"created_at" bson:"created_at" cql:"created_at" dynamo:"created_at"`
|
||||
}
|
||||
|
@@ -2,11 +2,15 @@ package models
|
||||
|
||||
// OTP model for database
|
||||
type OTP struct {
|
||||
Key string `json:"_key,omitempty" bson:"_key,omitempty" cql:"_key,omitempty"` // for arangodb
|
||||
ID string `gorm:"primaryKey;type:char(36)" json:"_id" bson:"_id" cql:"id"`
|
||||
Email string `gorm:"unique" json:"email" bson:"email" cql:"email"`
|
||||
Otp string `json:"otp" bson:"otp" cql:"otp"`
|
||||
ExpiresAt int64 `json:"expires_at" bson:"expires_at" cql:"expires_at"`
|
||||
CreatedAt int64 `json:"created_at" bson:"created_at" cql:"created_at"`
|
||||
UpdatedAt int64 `json:"updated_at" bson:"updated_at" cql:"updated_at"`
|
||||
Key string `json:"_key,omitempty" bson:"_key,omitempty" cql:"_key,omitempty" dynamo:"key,omitempty"` // for arangodb
|
||||
ID string `gorm:"primaryKey;type:char(36)" json:"_id" bson:"_id" cql:"id" dynamo:"id,hash"`
|
||||
Email string `gorm:"unique" json:"email" bson:"email" cql:"email" dynamo:"email" index:"email,hash"`
|
||||
Otp string `json:"otp" bson:"otp" cql:"otp" dynamo:"otp"`
|
||||
ExpiresAt int64 `json:"expires_at" bson:"expires_at" cql:"expires_at" dynamo:"expires_at"`
|
||||
CreatedAt int64 `json:"created_at" bson:"created_at" cql:"created_at" dynamo:"created_at"`
|
||||
UpdatedAt int64 `json:"updated_at" bson:"updated_at" cql:"updated_at" dynamo:"updated_at"`
|
||||
}
|
||||
|
||||
type Paging struct {
|
||||
ID string `json:"id,omitempty" dynamo:"id,hash"`
|
||||
}
|
||||
|
@@ -4,11 +4,11 @@ package models
|
||||
|
||||
// Session model for db
|
||||
type Session struct {
|
||||
Key string `json:"_key,omitempty" bson:"_key,omitempty" cql:"_key,omitempty"` // for arangodb
|
||||
ID string `gorm:"primaryKey;type:char(36)" json:"_id" bson:"_id" cql:"id"`
|
||||
UserID string `gorm:"type:char(36)" json:"user_id" bson:"user_id" cql:"user_id"`
|
||||
UserAgent string `json:"user_agent" bson:"user_agent" cql:"user_agent"`
|
||||
IP string `json:"ip" bson:"ip" cql:"ip"`
|
||||
CreatedAt int64 `json:"created_at" bson:"created_at" cql:"created_at"`
|
||||
UpdatedAt int64 `json:"updated_at" bson:"updated_at" cql:"updated_at"`
|
||||
Key string `json:"_key,omitempty" bson:"_key,omitempty" cql:"_key,omitempty" dynamo:"key,omitempty"` // for arangodb
|
||||
ID string `gorm:"primaryKey;type:char(36)" json:"_id" bson:"_id" cql:"id" dynamo:"id,hash"`
|
||||
UserID string `gorm:"type:char(36)" json:"user_id" bson:"user_id" cql:"user_id" dynamo:"user_id" index:"user_id,hash"`
|
||||
UserAgent string `json:"user_agent" bson:"user_agent" cql:"user_agent" dynamo:"user_agent"`
|
||||
IP string `json:"ip" bson:"ip" cql:"ip" dynamo:"ip"`
|
||||
CreatedAt int64 `json:"created_at" bson:"created_at" cql:"created_at" dynamo:"created_at"`
|
||||
UpdatedAt int64 `json:"updated_at" bson:"updated_at" cql:"updated_at" dynamo:"updated_at"`
|
||||
}
|
||||
|
@@ -12,27 +12,27 @@ import (
|
||||
|
||||
// User model for db
|
||||
type User struct {
|
||||
Key string `json:"_key,omitempty" bson:"_key,omitempty" cql:"_key,omitempty"` // for arangodb
|
||||
ID string `gorm:"primaryKey;type:char(36)" json:"_id" bson:"_id" cql:"id"`
|
||||
Key string `json:"_key,omitempty" bson:"_key,omitempty" cql:"_key,omitempty" dynamo:"key,omitempty"` // for arangodb
|
||||
ID string `gorm:"primaryKey;type:char(36)" json:"_id" bson:"_id" cql:"id" dynamo:"id,hash"`
|
||||
|
||||
Email string `gorm:"unique" json:"email" bson:"email" cql:"email"`
|
||||
EmailVerifiedAt *int64 `json:"email_verified_at" bson:"email_verified_at" cql:"email_verified_at"`
|
||||
Password *string `gorm:"type:text" json:"password" bson:"password" cql:"password"`
|
||||
SignupMethods string `json:"signup_methods" bson:"signup_methods" cql:"signup_methods"`
|
||||
GivenName *string `json:"given_name" bson:"given_name" cql:"given_name"`
|
||||
FamilyName *string `json:"family_name" bson:"family_name" cql:"family_name"`
|
||||
MiddleName *string `json:"middle_name" bson:"middle_name" cql:"middle_name"`
|
||||
Nickname *string `json:"nickname" bson:"nickname" cql:"nickname"`
|
||||
Gender *string `json:"gender" bson:"gender" cql:"gender"`
|
||||
Birthdate *string `json:"birthdate" bson:"birthdate" cql:"birthdate"`
|
||||
PhoneNumber *string `gorm:"unique" json:"phone_number" bson:"phone_number" cql:"phone_number"`
|
||||
PhoneNumberVerifiedAt *int64 `json:"phone_number_verified_at" bson:"phone_number_verified_at" cql:"phone_number_verified_at"`
|
||||
Picture *string `gorm:"type:text" json:"picture" bson:"picture" cql:"picture"`
|
||||
Roles string `json:"roles" bson:"roles" cql:"roles"`
|
||||
RevokedTimestamp *int64 `json:"revoked_timestamp" bson:"revoked_timestamp" cql:"revoked_timestamp"`
|
||||
IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled" bson:"is_multi_factor_auth_enabled" cql:"is_multi_factor_auth_enabled"`
|
||||
UpdatedAt int64 `json:"updated_at" bson:"updated_at" cql:"updated_at"`
|
||||
CreatedAt int64 `json:"created_at" bson:"created_at" cql:"created_at"`
|
||||
Email string `gorm:"unique" json:"email" bson:"email" cql:"email" dynamo:"email" index:"email,hash"`
|
||||
EmailVerifiedAt *int64 `json:"email_verified_at" bson:"email_verified_at" cql:"email_verified_at" dynamo:"email_verified_at"`
|
||||
Password *string `json:"password" bson:"password" cql:"password" dynamo:"password"`
|
||||
SignupMethods string `json:"signup_methods" bson:"signup_methods" cql:"signup_methods" dynamo:"signup_methods"`
|
||||
GivenName *string `json:"given_name" bson:"given_name" cql:"given_name" dynamo:"given_name"`
|
||||
FamilyName *string `json:"family_name" bson:"family_name" cql:"family_name" dynamo:"family_name"`
|
||||
MiddleName *string `json:"middle_name" bson:"middle_name" cql:"middle_name" dynamo:"middle_name"`
|
||||
Nickname *string `json:"nickname" bson:"nickname" cql:"nickname" dynamo:"nickname"`
|
||||
Gender *string `json:"gender" bson:"gender" cql:"gender" dynamo:"gender"`
|
||||
Birthdate *string `json:"birthdate" bson:"birthdate" cql:"birthdate" dynamo:"birthdate"`
|
||||
PhoneNumber *string `gorm:"unique" json:"phone_number" bson:"phone_number" cql:"phone_number" dynamo:"phone_number"`
|
||||
PhoneNumberVerifiedAt *int64 `json:"phone_number_verified_at" bson:"phone_number_verified_at" cql:"phone_number_verified_at" dynamo:"phone_number_verified_at"`
|
||||
Picture *string `json:"picture" bson:"picture" cql:"picture" dynamo:"picture"`
|
||||
Roles string `json:"roles" bson:"roles" cql:"roles" dynamo:"roles"`
|
||||
RevokedTimestamp *int64 `json:"revoked_timestamp" bson:"revoked_timestamp" cql:"revoked_timestamp" dynamo:"revoked_timestamp"`
|
||||
IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled" bson:"is_multi_factor_auth_enabled" cql:"is_multi_factor_auth_enabled" dynamo:"is_multi_factor_auth_enabled"`
|
||||
UpdatedAt int64 `json:"updated_at" bson:"updated_at" cql:"updated_at" dynamo:"updated_at"`
|
||||
CreatedAt int64 `json:"created_at" bson:"created_at" cql:"created_at" dynamo:"created_at"`
|
||||
}
|
||||
|
||||
func (user *User) AsAPIUser() *model.User {
|
||||
|
@@ -11,16 +11,16 @@ import (
|
||||
|
||||
// VerificationRequest model for db
|
||||
type VerificationRequest struct {
|
||||
Key string `json:"_key,omitempty" bson:"_key" cql:"_key,omitempty"` // for arangodb
|
||||
ID string `gorm:"primaryKey;type:char(36)" json:"_id" bson:"_id" cql:"id"`
|
||||
Token string `gorm:"type:text" json:"token" bson:"token" cql:"jwt_token"` // token is reserved keyword in cassandra
|
||||
Identifier string `gorm:"uniqueIndex:idx_email_identifier;type:varchar(64)" json:"identifier" bson:"identifier" cql:"identifier"`
|
||||
ExpiresAt int64 `json:"expires_at" bson:"expires_at" cql:"expires_at"`
|
||||
Email string `gorm:"uniqueIndex:idx_email_identifier;type:varchar(256)" json:"email" bson:"email" cql:"email"`
|
||||
Nonce string `gorm:"type:text" json:"nonce" bson:"nonce" cql:"nonce"`
|
||||
RedirectURI string `gorm:"type:text" json:"redirect_uri" bson:"redirect_uri" cql:"redirect_uri"`
|
||||
CreatedAt int64 `json:"created_at" bson:"created_at" cql:"created_at"`
|
||||
UpdatedAt int64 `json:"updated_at" bson:"updated_at" cql:"updated_at"`
|
||||
Key string `json:"_key,omitempty" bson:"_key" cql:"_key,omitempty" dynamo:"key,omitempty"` // for arangodb
|
||||
ID string `gorm:"primaryKey;type:char(36)" json:"_id" bson:"_id" cql:"id" dynamo:"id,hash"`
|
||||
Token string `json:"token" bson:"token" cql:"jwt_token" dynamo:"token" index:"token,hash"`
|
||||
Identifier string `gorm:"uniqueIndex:idx_email_identifier;type:varchar(64)" json:"identifier" bson:"identifier" cql:"identifier" dynamo:"identifier"`
|
||||
ExpiresAt int64 `json:"expires_at" bson:"expires_at" cql:"expires_at" dynamo:"expires_at"`
|
||||
Email string `gorm:"uniqueIndex:idx_email_identifier;type:varchar(256)" json:"email" bson:"email" cql:"email" dynamo:"email"`
|
||||
Nonce string `json:"nonce" bson:"nonce" cql:"nonce" dynamo:"nonce"`
|
||||
RedirectURI string `json:"redirect_uri" bson:"redirect_uri" cql:"redirect_uri" dynamo:"redirect_uri"`
|
||||
CreatedAt int64 `json:"created_at" bson:"created_at" cql:"created_at" dynamo:"created_at"`
|
||||
UpdatedAt int64 `json:"updated_at" bson:"updated_at" cql:"updated_at" dynamo:"updated_at"`
|
||||
}
|
||||
|
||||
func (v *VerificationRequest) AsAPIVerificationRequest() *model.VerificationRequest {
|
||||
|
@@ -12,14 +12,14 @@ import (
|
||||
|
||||
// Webhook model for db
|
||||
type Webhook struct {
|
||||
Key string `json:"_key,omitempty" bson:"_key,omitempty" cql:"_key,omitempty"` // for arangodb
|
||||
ID string `gorm:"primaryKey;type:char(36)" json:"_id" bson:"_id" cql:"id"`
|
||||
EventName string `gorm:"unique" json:"event_name" bson:"event_name" cql:"event_name"`
|
||||
EndPoint string `gorm:"type:text" json:"endpoint" bson:"endpoint" cql:"endpoint"`
|
||||
Headers string `gorm:"type:text" json:"headers" bson:"headers" cql:"headers"`
|
||||
Enabled bool `json:"enabled" bson:"enabled" cql:"enabled"`
|
||||
CreatedAt int64 `json:"created_at" bson:"created_at" cql:"created_at"`
|
||||
UpdatedAt int64 `json:"updated_at" bson:"updated_at" cql:"updated_at"`
|
||||
Key string `json:"_key,omitempty" bson:"_key,omitempty" cql:"_key,omitempty" dynamo:"key,omitempty"` // for arangodb
|
||||
ID string `gorm:"primaryKey;type:char(36)" json:"_id" bson:"_id" cql:"id" dynamo:"id,hash"`
|
||||
EventName string `gorm:"unique" json:"event_name" bson:"event_name" cql:"event_name" dynamo:"event_name" index:"event_name,hash"`
|
||||
EndPoint string `json:"endpoint" bson:"endpoint" cql:"endpoint" dynamo:"endpoint"`
|
||||
Headers string `json:"headers" bson:"headers" cql:"headers" dynamo:"headers"`
|
||||
Enabled bool `json:"enabled" bson:"enabled" cql:"enabled" dynamo:"enabled"`
|
||||
CreatedAt int64 `json:"created_at" bson:"created_at" cql:"created_at" dynamo:"created_at"`
|
||||
UpdatedAt int64 `json:"updated_at" bson:"updated_at" cql:"updated_at" dynamo:"updated_at"`
|
||||
}
|
||||
|
||||
// AsAPIWebhook to return webhook as graphql response object
|
||||
|
@@ -11,14 +11,14 @@ import (
|
||||
|
||||
// WebhookLog model for db
|
||||
type WebhookLog struct {
|
||||
Key string `json:"_key,omitempty" bson:"_key,omitempty" cql:"_key,omitempty"` // for arangodb
|
||||
ID string `gorm:"primaryKey;type:char(36)" json:"_id" bson:"_id" cql:"id"`
|
||||
HttpStatus int64 `json:"http_status" bson:"http_status" cql:"http_status"`
|
||||
Response string `gorm:"type:text" json:"response" bson:"response" cql:"response"`
|
||||
Request string `gorm:"type:text" json:"request" bson:"request" cql:"request"`
|
||||
WebhookID string `gorm:"type:char(36)" json:"webhook_id" bson:"webhook_id" cql:"webhook_id"`
|
||||
CreatedAt int64 `json:"created_at" bson:"created_at" cql:"created_at"`
|
||||
UpdatedAt int64 `json:"updated_at" bson:"updated_at" cql:"updated_at"`
|
||||
Key string `json:"_key,omitempty" bson:"_key,omitempty" cql:"_key,omitempty" dynamo:"key,omitempty"` // for arangodb
|
||||
ID string `gorm:"primaryKey;type:char(36)" json:"_id" bson:"_id" cql:"id" dynamo:"id,hash"`
|
||||
HttpStatus int64 `json:"http_status" bson:"http_status" cql:"http_status" dynamo:"http_status"`
|
||||
Response string `json:"response" bson:"response" cql:"response" dynamo:"response"`
|
||||
Request string `json:"request" bson:"request" cql:"request" dynamo:"request"`
|
||||
WebhookID string `gorm:"type:char(36)" json:"webhook_id" bson:"webhook_id" cql:"webhook_id" dynamo:"webhook_id" index:"webhook_id,hash"`
|
||||
CreatedAt int64 `json:"created_at" bson:"created_at" cql:"created_at" dynamo:"created_at"`
|
||||
UpdatedAt int64 `json:"updated_at" bson:"updated_at" cql:"updated_at" dynamo:"updated_at"`
|
||||
}
|
||||
|
||||
// AsAPIWebhookLog to return webhook log as graphql response object
|
||||
|
121
server/db/providers/dynamodb/email_template.go
Normal file
121
server/db/providers/dynamodb/email_template.go
Normal file
@@ -0,0 +1,121 @@
|
||||
package dynamodb
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/authorizerdev/authorizer/server/db/models"
|
||||
"github.com/authorizerdev/authorizer/server/graph/model"
|
||||
"github.com/google/uuid"
|
||||
"github.com/guregu/dynamo"
|
||||
)
|
||||
|
||||
// AddEmailTemplate to add EmailTemplate
|
||||
func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate models.EmailTemplate) (*model.EmailTemplate, error) {
|
||||
collection := p.db.Table(models.Collections.EmailTemplate)
|
||||
if emailTemplate.ID == "" {
|
||||
emailTemplate.ID = uuid.New().String()
|
||||
}
|
||||
|
||||
emailTemplate.Key = emailTemplate.ID
|
||||
emailTemplate.CreatedAt = time.Now().Unix()
|
||||
emailTemplate.UpdatedAt = time.Now().Unix()
|
||||
err := collection.Put(emailTemplate).RunWithContext(ctx)
|
||||
|
||||
if err != nil {
|
||||
return emailTemplate.AsAPIEmailTemplate(), err
|
||||
}
|
||||
|
||||
return emailTemplate.AsAPIEmailTemplate(), nil
|
||||
}
|
||||
|
||||
// UpdateEmailTemplate to update EmailTemplate
|
||||
func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate models.EmailTemplate) (*model.EmailTemplate, error) {
|
||||
collection := p.db.Table(models.Collections.EmailTemplate)
|
||||
emailTemplate.UpdatedAt = time.Now().Unix()
|
||||
err := UpdateByHashKey(collection, "id", emailTemplate.ID, emailTemplate)
|
||||
if err != nil {
|
||||
return emailTemplate.AsAPIEmailTemplate(), err
|
||||
}
|
||||
return emailTemplate.AsAPIEmailTemplate(), nil
|
||||
}
|
||||
|
||||
// ListEmailTemplates to list EmailTemplate
|
||||
func (p *provider) ListEmailTemplate(ctx context.Context, pagination model.Pagination) (*model.EmailTemplates, error) {
|
||||
|
||||
var emailTemplate models.EmailTemplate
|
||||
var iter dynamo.PagingIter
|
||||
var lastEval dynamo.PagingKey
|
||||
var iteration int64 = 0
|
||||
|
||||
collection := p.db.Table(models.Collections.EmailTemplate)
|
||||
emailTemplates := []*model.EmailTemplate{}
|
||||
paginationClone := pagination
|
||||
scanner := collection.Scan()
|
||||
count, err := scanner.Count()
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for (paginationClone.Offset + paginationClone.Limit) > iteration {
|
||||
iter = scanner.StartFrom(lastEval).Limit(paginationClone.Limit).Iter()
|
||||
for iter.NextWithContext(ctx, &emailTemplate) {
|
||||
if paginationClone.Offset == iteration {
|
||||
emailTemplates = append(emailTemplates, emailTemplate.AsAPIEmailTemplate())
|
||||
}
|
||||
}
|
||||
lastEval = iter.LastEvaluatedKey()
|
||||
iteration += paginationClone.Limit
|
||||
}
|
||||
|
||||
paginationClone.Total = count
|
||||
|
||||
return &model.EmailTemplates{
|
||||
Pagination: &paginationClone,
|
||||
EmailTemplates: emailTemplates,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// GetEmailTemplateByID to get EmailTemplate by id
|
||||
func (p *provider) GetEmailTemplateByID(ctx context.Context, emailTemplateID string) (*model.EmailTemplate, error) {
|
||||
collection := p.db.Table(models.Collections.EmailTemplate)
|
||||
var emailTemplate models.EmailTemplate
|
||||
err := collection.Get("id", emailTemplateID).OneWithContext(ctx, &emailTemplate)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return emailTemplate.AsAPIEmailTemplate(), nil
|
||||
}
|
||||
|
||||
// GetEmailTemplateByEventName to get EmailTemplate by event_name
|
||||
func (p *provider) GetEmailTemplateByEventName(ctx context.Context, eventName string) (*model.EmailTemplate, error) {
|
||||
collection := p.db.Table(models.Collections.EmailTemplate)
|
||||
var emailTemplates []models.EmailTemplate
|
||||
var emailTemplate models.EmailTemplate
|
||||
|
||||
err := collection.Scan().Index("event_name").Filter("'event_name' = ?", eventName).Limit(1).AllWithContext(ctx, &emailTemplates)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(emailTemplates) > 0 {
|
||||
emailTemplate = emailTemplates[0]
|
||||
return emailTemplate.AsAPIEmailTemplate(), nil
|
||||
} else {
|
||||
return nil, errors.New("no record found")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// DeleteEmailTemplate to delete EmailTemplate
|
||||
func (p *provider) DeleteEmailTemplate(ctx context.Context, emailTemplate *model.EmailTemplate) error {
|
||||
collection := p.db.Table(models.Collections.EmailTemplate)
|
||||
err := collection.Delete("id", emailTemplate.ID).RunWithContext(ctx)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
72
server/db/providers/dynamodb/env.go
Normal file
72
server/db/providers/dynamodb/env.go
Normal file
@@ -0,0 +1,72 @@
|
||||
package dynamodb
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/authorizerdev/authorizer/server/db/models"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
// AddEnv to save environment information in database
|
||||
func (p *provider) AddEnv(ctx context.Context, env models.Env) (models.Env, error) {
|
||||
collection := p.db.Table(models.Collections.Env)
|
||||
|
||||
if env.ID == "" {
|
||||
env.ID = uuid.New().String()
|
||||
}
|
||||
|
||||
env.Key = env.ID
|
||||
|
||||
env.CreatedAt = time.Now().Unix()
|
||||
env.UpdatedAt = time.Now().Unix()
|
||||
|
||||
err := collection.Put(env).RunWithContext(ctx)
|
||||
|
||||
if err != nil {
|
||||
return env, err
|
||||
}
|
||||
|
||||
return env, nil
|
||||
}
|
||||
|
||||
// UpdateEnv to update environment information in database
|
||||
func (p *provider) UpdateEnv(ctx context.Context, env models.Env) (models.Env, error) {
|
||||
|
||||
collection := p.db.Table(models.Collections.Env)
|
||||
env.UpdatedAt = time.Now().Unix()
|
||||
|
||||
err := UpdateByHashKey(collection, "id", env.ID, env)
|
||||
|
||||
if err != nil {
|
||||
return env, err
|
||||
}
|
||||
return env, nil
|
||||
}
|
||||
|
||||
// GetEnv to get environment information from database
|
||||
func (p *provider) GetEnv(ctx context.Context) (models.Env, error) {
|
||||
var env models.Env
|
||||
|
||||
collection := p.db.Table(models.Collections.Env)
|
||||
// As there is no Findone supported.
|
||||
iter := collection.Scan().Limit(1).Iter()
|
||||
|
||||
for iter.NextWithContext(ctx, &env) {
|
||||
if env.ID == "" {
|
||||
return env, errors.New("no documets found")
|
||||
} else {
|
||||
return env, nil
|
||||
}
|
||||
}
|
||||
|
||||
err := iter.Err()
|
||||
|
||||
if err != nil {
|
||||
return env, fmt.Errorf("config not found")
|
||||
}
|
||||
|
||||
return env, nil
|
||||
}
|
80
server/db/providers/dynamodb/otp.go
Normal file
80
server/db/providers/dynamodb/otp.go
Normal file
@@ -0,0 +1,80 @@
|
||||
package dynamodb
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/authorizerdev/authorizer/server/db/models"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
// UpsertOTP to add or update otp
|
||||
func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models.OTP, error) {
|
||||
otp, _ := p.GetOTPByEmail(ctx, otpParam.Email)
|
||||
shouldCreate := false
|
||||
if otp == nil {
|
||||
id := uuid.NewString()
|
||||
otp = &models.OTP{
|
||||
ID: id,
|
||||
Key: id,
|
||||
Otp: otpParam.Otp,
|
||||
Email: otpParam.Email,
|
||||
ExpiresAt: otpParam.ExpiresAt,
|
||||
CreatedAt: time.Now().Unix(),
|
||||
}
|
||||
shouldCreate = true
|
||||
} else {
|
||||
otp.Otp = otpParam.Otp
|
||||
otp.ExpiresAt = otpParam.ExpiresAt
|
||||
}
|
||||
|
||||
collection := p.db.Table(models.Collections.OTP)
|
||||
otp.UpdatedAt = time.Now().Unix()
|
||||
|
||||
var err error
|
||||
if shouldCreate {
|
||||
err = collection.Put(otp).RunWithContext(ctx)
|
||||
} else {
|
||||
err = UpdateByHashKey(collection, "id", otp.ID, otp)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return otp, nil
|
||||
}
|
||||
|
||||
// GetOTPByEmail to get otp for a given email address
|
||||
func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*models.OTP, error) {
|
||||
var otps []models.OTP
|
||||
var otp models.OTP
|
||||
|
||||
collection := p.db.Table(models.Collections.OTP)
|
||||
|
||||
err := collection.Scan().Index("email").Filter("'email' = ?", emailAddress).Limit(1).AllWithContext(ctx, &otps)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(otps) > 0 {
|
||||
otp = otps[0]
|
||||
return &otp, nil
|
||||
} else {
|
||||
return nil, errors.New("no docuemnt found")
|
||||
}
|
||||
}
|
||||
|
||||
// DeleteOTP to delete otp
|
||||
func (p *provider) DeleteOTP(ctx context.Context, otp *models.OTP) error {
|
||||
collection := p.db.Table(models.Collections.OTP)
|
||||
|
||||
if otp.ID != "" {
|
||||
err := collection.Delete("id", otp.ID).RunWithContext(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
61
server/db/providers/dynamodb/provider.go
Normal file
61
server/db/providers/dynamodb/provider.go
Normal file
@@ -0,0 +1,61 @@
|
||||
package dynamodb
|
||||
|
||||
import (
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||
"github.com/aws/aws-sdk-go/aws/session"
|
||||
"github.com/guregu/dynamo"
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/authorizerdev/authorizer/server/constants"
|
||||
"github.com/authorizerdev/authorizer/server/db/models"
|
||||
"github.com/authorizerdev/authorizer/server/memorystore"
|
||||
)
|
||||
|
||||
type provider struct {
|
||||
db *dynamo.DB
|
||||
}
|
||||
|
||||
// NewProvider returns a new Dynamo provider
|
||||
func NewProvider() (*provider, error) {
|
||||
dbURL := memorystore.RequiredEnvStoreObj.GetRequiredEnv().DatabaseURL
|
||||
awsRegion := memorystore.RequiredEnvStoreObj.GetRequiredEnv().AwsRegion
|
||||
awsAccessKeyID := memorystore.RequiredEnvStoreObj.GetRequiredEnv().AwsAccessKeyID
|
||||
awsSecretAccessKey := memorystore.RequiredEnvStoreObj.GetRequiredEnv().AwsSecretAccessKey
|
||||
|
||||
config := aws.Config{
|
||||
MaxRetries: aws.Int(3),
|
||||
CredentialsChainVerboseErrors: aws.Bool(true), // for full error logs
|
||||
}
|
||||
|
||||
if awsRegion != "" {
|
||||
config.Region = aws.String(awsRegion)
|
||||
}
|
||||
|
||||
// custom awsAccessKeyID, awsSecretAccessKey took first priority, if not then fetch config from aws credentials
|
||||
if awsAccessKeyID != "" && awsSecretAccessKey != "" {
|
||||
config.Credentials = credentials.NewStaticCredentials(awsAccessKeyID, awsSecretAccessKey, "")
|
||||
} else if dbURL != "" {
|
||||
// static config in case of testing or local-setup
|
||||
config.Credentials = credentials.NewStaticCredentials("key", "key", "")
|
||||
config.Endpoint = aws.String(dbURL)
|
||||
} else {
|
||||
log.Debugf("%s or %s or %s not found. Trying to load default credentials from aws config", constants.EnvAwsRegion, constants.EnvAwsAccessKeyID, constants.EnvAwsSecretAccessKey)
|
||||
}
|
||||
|
||||
session := session.Must(session.NewSession(&config))
|
||||
db := dynamo.New(session)
|
||||
|
||||
db.CreateTable(models.Collections.User, models.User{}).Wait()
|
||||
db.CreateTable(models.Collections.Session, models.Session{}).Wait()
|
||||
db.CreateTable(models.Collections.EmailTemplate, models.EmailTemplate{}).Wait()
|
||||
db.CreateTable(models.Collections.Env, models.Env{}).Wait()
|
||||
db.CreateTable(models.Collections.OTP, models.OTP{}).Wait()
|
||||
db.CreateTable(models.Collections.VerificationRequest, models.VerificationRequest{}).Wait()
|
||||
db.CreateTable(models.Collections.Webhook, models.Webhook{}).Wait()
|
||||
db.CreateTable(models.Collections.WebhookLog, models.WebhookLog{}).Wait()
|
||||
|
||||
return &provider{
|
||||
db: db,
|
||||
}, nil
|
||||
}
|
28
server/db/providers/dynamodb/session.go
Normal file
28
server/db/providers/dynamodb/session.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package dynamodb
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/authorizerdev/authorizer/server/db/models"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
// AddSession to save session information in database
|
||||
func (p *provider) AddSession(ctx context.Context, session models.Session) error {
|
||||
collection := p.db.Table(models.Collections.Session)
|
||||
|
||||
if session.ID == "" {
|
||||
session.ID = uuid.New().String()
|
||||
}
|
||||
|
||||
session.CreatedAt = time.Now().Unix()
|
||||
session.UpdatedAt = time.Now().Unix()
|
||||
err := collection.Put(session).RunWithContext(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteSession to delete session information from database
|
||||
func (p *provider) DeleteSession(ctx context.Context, userId string) error {
|
||||
return nil
|
||||
}
|
46
server/db/providers/dynamodb/shared.go
Normal file
46
server/db/providers/dynamodb/shared.go
Normal file
@@ -0,0 +1,46 @@
|
||||
package dynamodb
|
||||
|
||||
import (
|
||||
"github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute"
|
||||
"github.com/guregu/dynamo"
|
||||
)
|
||||
|
||||
// As updpate all item not supported so set manually via Set and SetNullable for empty field
|
||||
func UpdateByHashKey(table dynamo.Table, hashKey string, hashValue string, item interface{}) error {
|
||||
existingValue, err := dynamo.MarshalItem(item)
|
||||
var i interface{}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
nullableValue, err := dynamodbattribute.MarshalMap(item)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
u := table.Update(hashKey, hashValue)
|
||||
for k, v := range existingValue {
|
||||
if k == hashKey {
|
||||
continue
|
||||
}
|
||||
u = u.Set(k, v)
|
||||
}
|
||||
|
||||
for k, v := range nullableValue {
|
||||
if k == hashKey {
|
||||
continue
|
||||
}
|
||||
dynamodbattribute.Unmarshal(v, &i)
|
||||
if i == nil {
|
||||
u = u.SetNullable(k, v)
|
||||
}
|
||||
}
|
||||
|
||||
err = u.Run()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
195
server/db/providers/dynamodb/user.go
Normal file
195
server/db/providers/dynamodb/user.go
Normal file
@@ -0,0 +1,195 @@
|
||||
package dynamodb
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/authorizerdev/authorizer/server/constants"
|
||||
"github.com/authorizerdev/authorizer/server/db/models"
|
||||
"github.com/authorizerdev/authorizer/server/graph/model"
|
||||
"github.com/authorizerdev/authorizer/server/memorystore"
|
||||
"github.com/google/uuid"
|
||||
"github.com/guregu/dynamo"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// AddUser to save user information in database
|
||||
func (p *provider) AddUser(ctx context.Context, user models.User) (models.User, error) {
|
||||
collection := p.db.Table(models.Collections.User)
|
||||
|
||||
if user.ID == "" {
|
||||
user.ID = uuid.New().String()
|
||||
}
|
||||
|
||||
if user.Roles == "" {
|
||||
defaultRoles, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyDefaultRoles)
|
||||
if err != nil {
|
||||
return user, err
|
||||
}
|
||||
user.Roles = defaultRoles
|
||||
}
|
||||
|
||||
user.CreatedAt = time.Now().Unix()
|
||||
user.UpdatedAt = time.Now().Unix()
|
||||
|
||||
err := collection.Put(user).RunWithContext(ctx)
|
||||
|
||||
if err != nil {
|
||||
return user, err
|
||||
}
|
||||
return user, nil
|
||||
}
|
||||
|
||||
// UpdateUser to update user information in database
|
||||
func (p *provider) UpdateUser(ctx context.Context, user models.User) (models.User, error) {
|
||||
collection := p.db.Table(models.Collections.User)
|
||||
|
||||
if user.ID != "" {
|
||||
|
||||
user.UpdatedAt = time.Now().Unix()
|
||||
|
||||
err := UpdateByHashKey(collection, "id", user.ID, user)
|
||||
if err != nil {
|
||||
return user, err
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return user, err
|
||||
}
|
||||
|
||||
}
|
||||
return user, nil
|
||||
}
|
||||
|
||||
// DeleteUser to delete user information from database
|
||||
func (p *provider) DeleteUser(ctx context.Context, user models.User) error {
|
||||
collection := p.db.Table(models.Collections.User)
|
||||
sessionCollection := p.db.Table(models.Collections.Session)
|
||||
|
||||
if user.ID != "" {
|
||||
err := collection.Delete("id", user.ID).Run()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = sessionCollection.Batch("id").Write().Delete(dynamo.Keys{"user_id", user.ID}).RunWithContext(ctx)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ListUsers to get list of users from database
|
||||
func (p *provider) ListUsers(ctx context.Context, pagination model.Pagination) (*model.Users, error) {
|
||||
var user models.User
|
||||
var lastEval dynamo.PagingKey
|
||||
var iter dynamo.PagingIter
|
||||
var iteration int64 = 0
|
||||
|
||||
collection := p.db.Table(models.Collections.User)
|
||||
users := []*model.User{}
|
||||
|
||||
paginationClone := pagination
|
||||
scanner := collection.Scan()
|
||||
count, err := scanner.Count()
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for (paginationClone.Offset + paginationClone.Limit) > iteration {
|
||||
iter = scanner.StartFrom(lastEval).Limit(paginationClone.Limit).Iter()
|
||||
for iter.NextWithContext(ctx, &user) {
|
||||
if paginationClone.Offset == iteration {
|
||||
users = append(users, user.AsAPIUser())
|
||||
}
|
||||
}
|
||||
lastEval = iter.LastEvaluatedKey()
|
||||
iteration += paginationClone.Limit
|
||||
}
|
||||
|
||||
err = iter.Err()
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
paginationClone.Total = count
|
||||
|
||||
return &model.Users{
|
||||
Pagination: &paginationClone,
|
||||
Users: users,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// GetUserByEmail to get user information from database using email address
|
||||
func (p *provider) GetUserByEmail(ctx context.Context, email string) (models.User, error) {
|
||||
var users []models.User
|
||||
var user models.User
|
||||
|
||||
collection := p.db.Table(models.Collections.User)
|
||||
err := collection.Scan().Index("email").Filter("'email' = ?", email).AllWithContext(ctx, &users)
|
||||
|
||||
if err != nil {
|
||||
return user, nil
|
||||
}
|
||||
|
||||
if len(users) > 0 {
|
||||
user = users[0]
|
||||
return user, nil
|
||||
} else {
|
||||
return user, errors.New("no record found")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// GetUserByID to get user information from database using user ID
|
||||
func (p *provider) GetUserByID(ctx context.Context, id string) (models.User, error) {
|
||||
collection := p.db.Table(models.Collections.User)
|
||||
var user models.User
|
||||
err := collection.Get("id", id).OneWithContext(ctx, &user)
|
||||
|
||||
if err != nil {
|
||||
if user.Email == "" {
|
||||
return user, errors.New("no documets found")
|
||||
} else {
|
||||
return user, nil
|
||||
}
|
||||
}
|
||||
return user, nil
|
||||
}
|
||||
|
||||
// UpdateUsers to update multiple users, with parameters of user IDs slice
|
||||
// If ids set to nil / empty all the users will be updated
|
||||
func (p *provider) UpdateUsers(ctx context.Context, data map[string]interface{}, ids []string) error {
|
||||
// set updated_at time for all users
|
||||
userCollection := p.db.Table(models.Collections.User)
|
||||
var allUsers []models.User
|
||||
var res int64 = 0
|
||||
var err error
|
||||
if len(ids) > 0 {
|
||||
for _, v := range ids {
|
||||
err = UpdateByHashKey(userCollection, "id", v, data)
|
||||
}
|
||||
} else {
|
||||
// as there is no facility to update all doc - https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/SQLtoNoSQL.UpdateData.html
|
||||
userCollection.Scan().All(&allUsers)
|
||||
|
||||
for _, user := range allUsers {
|
||||
err = UpdateByHashKey(userCollection, "id", user.ID, data)
|
||||
if err == nil {
|
||||
res = res + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
} else {
|
||||
log.Info("Updated users: ", res)
|
||||
}
|
||||
return nil
|
||||
}
|
116
server/db/providers/dynamodb/verification_requests.go
Normal file
116
server/db/providers/dynamodb/verification_requests.go
Normal file
@@ -0,0 +1,116 @@
|
||||
package dynamodb
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/authorizerdev/authorizer/server/db/models"
|
||||
"github.com/authorizerdev/authorizer/server/graph/model"
|
||||
"github.com/google/uuid"
|
||||
"github.com/guregu/dynamo"
|
||||
)
|
||||
|
||||
// AddVerification to save verification request in database
|
||||
func (p *provider) AddVerificationRequest(ctx context.Context, verificationRequest models.VerificationRequest) (models.VerificationRequest, error) {
|
||||
collection := p.db.Table(models.Collections.VerificationRequest)
|
||||
|
||||
if verificationRequest.ID == "" {
|
||||
verificationRequest.ID = uuid.New().String()
|
||||
verificationRequest.CreatedAt = time.Now().Unix()
|
||||
verificationRequest.UpdatedAt = time.Now().Unix()
|
||||
err := collection.Put(verificationRequest).RunWithContext(ctx)
|
||||
if err != nil {
|
||||
return verificationRequest, err
|
||||
}
|
||||
}
|
||||
|
||||
return verificationRequest, nil
|
||||
}
|
||||
|
||||
// GetVerificationRequestByToken to get verification request from database using token
|
||||
func (p *provider) GetVerificationRequestByToken(ctx context.Context, token string) (models.VerificationRequest, error) {
|
||||
collection := p.db.Table(models.Collections.VerificationRequest)
|
||||
var verificationRequest models.VerificationRequest
|
||||
|
||||
iter := collection.Scan().Filter("'token' = ?", token).Iter()
|
||||
for iter.NextWithContext(ctx, &verificationRequest) {
|
||||
return verificationRequest, nil
|
||||
}
|
||||
|
||||
err := iter.Err()
|
||||
if err != nil {
|
||||
return verificationRequest, err
|
||||
}
|
||||
return verificationRequest, nil
|
||||
}
|
||||
|
||||
// GetVerificationRequestByEmail to get verification request by email from database
|
||||
func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email string, identifier string) (models.VerificationRequest, error) {
|
||||
var verificationRequest models.VerificationRequest
|
||||
collection := p.db.Table(models.Collections.VerificationRequest)
|
||||
iter := collection.Scan().Filter("'email' = ?", email).Filter("'identifier' = ?", identifier).Iter()
|
||||
for iter.NextWithContext(ctx, &verificationRequest) {
|
||||
return verificationRequest, nil
|
||||
}
|
||||
|
||||
err := iter.Err()
|
||||
if err != nil {
|
||||
return verificationRequest, err
|
||||
}
|
||||
return verificationRequest, nil
|
||||
}
|
||||
|
||||
// ListVerificationRequests to get list of verification requests from database
|
||||
func (p *provider) ListVerificationRequests(ctx context.Context, pagination model.Pagination) (*model.VerificationRequests, error) {
|
||||
verificationRequests := []*model.VerificationRequest{}
|
||||
var verificationRequest models.VerificationRequest
|
||||
var lastEval dynamo.PagingKey
|
||||
var iter dynamo.PagingIter
|
||||
var iteration int64 = 0
|
||||
|
||||
collection := p.db.Table(models.Collections.VerificationRequest)
|
||||
paginationClone := pagination
|
||||
|
||||
scanner := collection.Scan()
|
||||
count, err := scanner.Count()
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for (paginationClone.Offset + paginationClone.Limit) > iteration {
|
||||
iter = scanner.StartFrom(lastEval).Limit(paginationClone.Limit).Iter()
|
||||
for iter.NextWithContext(ctx, &verificationRequest) {
|
||||
if paginationClone.Offset == iteration {
|
||||
verificationRequests = append(verificationRequests, verificationRequest.AsAPIVerificationRequest())
|
||||
}
|
||||
}
|
||||
err = iter.Err()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
lastEval = iter.LastEvaluatedKey()
|
||||
iteration += paginationClone.Limit
|
||||
}
|
||||
|
||||
paginationClone.Total = count
|
||||
|
||||
return &model.VerificationRequests{
|
||||
VerificationRequests: verificationRequests,
|
||||
Pagination: &paginationClone,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// DeleteVerificationRequest to delete verification request from database
|
||||
func (p *provider) DeleteVerificationRequest(ctx context.Context, verificationRequest models.VerificationRequest) error {
|
||||
collection := p.db.Table(models.Collections.VerificationRequest)
|
||||
|
||||
if verificationRequest.ID != "" {
|
||||
err := collection.Delete("id", verificationRequest.ID).RunWithContext(ctx)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
148
server/db/providers/dynamodb/webhook.go
Normal file
148
server/db/providers/dynamodb/webhook.go
Normal file
@@ -0,0 +1,148 @@
|
||||
package dynamodb
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/authorizerdev/authorizer/server/db/models"
|
||||
"github.com/authorizerdev/authorizer/server/graph/model"
|
||||
"github.com/google/uuid"
|
||||
"github.com/guregu/dynamo"
|
||||
)
|
||||
|
||||
// AddWebhook to add webhook
|
||||
func (p *provider) AddWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) {
|
||||
collection := p.db.Table(models.Collections.Webhook)
|
||||
|
||||
if webhook.ID == "" {
|
||||
webhook.ID = uuid.New().String()
|
||||
}
|
||||
|
||||
webhook.Key = webhook.ID
|
||||
webhook.CreatedAt = time.Now().Unix()
|
||||
webhook.UpdatedAt = time.Now().Unix()
|
||||
|
||||
err := collection.Put(webhook).RunWithContext(ctx)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return webhook.AsAPIWebhook(), nil
|
||||
}
|
||||
|
||||
// UpdateWebhook to update webhook
|
||||
func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) {
|
||||
collection := p.db.Table(models.Collections.Webhook)
|
||||
|
||||
webhook.UpdatedAt = time.Now().Unix()
|
||||
err := UpdateByHashKey(collection, "id", webhook.ID, webhook)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return webhook.AsAPIWebhook(), nil
|
||||
}
|
||||
|
||||
// ListWebhooks to list webhook
|
||||
func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination) (*model.Webhooks, error) {
|
||||
webhooks := []*model.Webhook{}
|
||||
var webhook models.Webhook
|
||||
var lastEval dynamo.PagingKey
|
||||
var iter dynamo.PagingIter
|
||||
var iteration int64 = 0
|
||||
|
||||
collection := p.db.Table(models.Collections.Webhook)
|
||||
paginationClone := pagination
|
||||
scanner := collection.Scan()
|
||||
count, err := scanner.Count()
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for (paginationClone.Offset + paginationClone.Limit) > iteration {
|
||||
iter = scanner.StartFrom(lastEval).Limit(paginationClone.Limit).Iter()
|
||||
for iter.NextWithContext(ctx, &webhook) {
|
||||
if paginationClone.Offset == iteration {
|
||||
webhooks = append(webhooks, webhook.AsAPIWebhook())
|
||||
}
|
||||
}
|
||||
err = iter.Err()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
lastEval = iter.LastEvaluatedKey()
|
||||
iteration += paginationClone.Limit
|
||||
}
|
||||
|
||||
paginationClone.Total = count
|
||||
|
||||
return &model.Webhooks{
|
||||
Pagination: &paginationClone,
|
||||
Webhooks: webhooks,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// GetWebhookByID to get webhook by id
|
||||
func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*model.Webhook, error) {
|
||||
collection := p.db.Table(models.Collections.Webhook)
|
||||
var webhook models.Webhook
|
||||
|
||||
err := collection.Get("id", webhookID).OneWithContext(ctx, &webhook)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if webhook.ID == "" {
|
||||
return webhook.AsAPIWebhook(), errors.New("no documets found")
|
||||
}
|
||||
|
||||
return webhook.AsAPIWebhook(), nil
|
||||
}
|
||||
|
||||
// GetWebhookByEventName to get webhook by event_name
|
||||
func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string) (*model.Webhook, error) {
|
||||
var webhook models.Webhook
|
||||
collection := p.db.Table(models.Collections.Webhook)
|
||||
|
||||
iter := collection.Scan().Index("event_name").Filter("'event_name' = ?", eventName).Iter()
|
||||
|
||||
for iter.NextWithContext(ctx, &webhook) {
|
||||
return webhook.AsAPIWebhook(), nil
|
||||
}
|
||||
|
||||
err := iter.Err()
|
||||
|
||||
if err != nil {
|
||||
return webhook.AsAPIWebhook(), err
|
||||
}
|
||||
return webhook.AsAPIWebhook(), nil
|
||||
}
|
||||
|
||||
// DeleteWebhook to delete webhook
|
||||
func (p *provider) DeleteWebhook(ctx context.Context, webhook *model.Webhook) error {
|
||||
// Also delete webhook logs for given webhook id
|
||||
if webhook.ID != "" {
|
||||
webhookCollection := p.db.Table(models.Collections.Webhook)
|
||||
pagination := model.Pagination{}
|
||||
webhookLogCollection := p.db.Table(models.Collections.WebhookLog)
|
||||
err := webhookCollection.Delete("id", webhook.ID).RunWithContext(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
webhookLogs, errIs := p.ListWebhookLogs(ctx, pagination, webhook.ID)
|
||||
|
||||
for _, webhookLog := range webhookLogs.WebhookLogs {
|
||||
err = webhookLogCollection.Delete("id", webhookLog.ID).RunWithContext(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if errIs != nil {
|
||||
return errIs
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
78
server/db/providers/dynamodb/webhook_log.go
Normal file
78
server/db/providers/dynamodb/webhook_log.go
Normal file
@@ -0,0 +1,78 @@
|
||||
package dynamodb
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/authorizerdev/authorizer/server/db/models"
|
||||
"github.com/authorizerdev/authorizer/server/graph/model"
|
||||
"github.com/google/uuid"
|
||||
"github.com/guregu/dynamo"
|
||||
)
|
||||
|
||||
// AddWebhookLog to add webhook log
|
||||
func (p *provider) AddWebhookLog(ctx context.Context, webhookLog models.WebhookLog) (*model.WebhookLog, error) {
|
||||
collection := p.db.Table(models.Collections.WebhookLog)
|
||||
|
||||
if webhookLog.ID == "" {
|
||||
webhookLog.ID = uuid.New().String()
|
||||
}
|
||||
|
||||
webhookLog.Key = webhookLog.ID
|
||||
webhookLog.CreatedAt = time.Now().Unix()
|
||||
webhookLog.UpdatedAt = time.Now().Unix()
|
||||
err := collection.Put(webhookLog).RunWithContext(ctx)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return webhookLog.AsAPIWebhookLog(), nil
|
||||
}
|
||||
|
||||
// ListWebhookLogs to list webhook logs
|
||||
func (p *provider) ListWebhookLogs(ctx context.Context, pagination model.Pagination, webhookID string) (*model.WebhookLogs, error) {
|
||||
webhookLogs := []*model.WebhookLog{}
|
||||
var webhookLog models.WebhookLog
|
||||
var lastEval dynamo.PagingKey
|
||||
var iter dynamo.PagingIter
|
||||
var iteration int64 = 0
|
||||
var err error
|
||||
var count int64
|
||||
|
||||
collection := p.db.Table(models.Collections.WebhookLog)
|
||||
paginationClone := pagination
|
||||
scanner := collection.Scan()
|
||||
|
||||
if webhookID != "" {
|
||||
iter = scanner.Index("webhook_id").Filter("'webhook_id' = ?", webhookID).Iter()
|
||||
for iter.NextWithContext(ctx, &webhookLog) {
|
||||
webhookLogs = append(webhookLogs, webhookLog.AsAPIWebhookLog())
|
||||
}
|
||||
err = iter.Err()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
for (paginationClone.Offset + paginationClone.Limit) > iteration {
|
||||
iter = scanner.StartFrom(lastEval).Limit(paginationClone.Limit).Iter()
|
||||
for iter.NextWithContext(ctx, &webhookLog) {
|
||||
if paginationClone.Offset == iteration {
|
||||
webhookLogs = append(webhookLogs, webhookLog.AsAPIWebhookLog())
|
||||
}
|
||||
}
|
||||
err = iter.Err()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
lastEval = iter.LastEvaluatedKey()
|
||||
iteration += paginationClone.Limit
|
||||
}
|
||||
}
|
||||
|
||||
paginationClone.Total = count
|
||||
// paginationClone.Cursor = iter.LastEvaluatedKey()
|
||||
return &model.WebhookLogs{
|
||||
Pagination: &paginationClone,
|
||||
WebhookLogs: webhookLogs,
|
||||
}, nil
|
||||
}
|
@@ -1,6 +1,7 @@
|
||||
package sql
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"time"
|
||||
@@ -8,9 +9,9 @@ import (
|
||||
"github.com/authorizerdev/authorizer/server/constants"
|
||||
"github.com/authorizerdev/authorizer/server/db/models"
|
||||
"github.com/authorizerdev/authorizer/server/memorystore"
|
||||
"github.com/glebarez/sqlite"
|
||||
"gorm.io/driver/mysql"
|
||||
"gorm.io/driver/postgres"
|
||||
"gorm.io/driver/sqlite"
|
||||
"gorm.io/driver/sqlserver"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/logger"
|
||||
@@ -21,6 +22,16 @@ type provider struct {
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
const (
|
||||
phoneNumberIndexName = "UQ_phone_number"
|
||||
phoneNumberColumnName = "phone_number"
|
||||
)
|
||||
|
||||
type indexInfo struct {
|
||||
IndexName string `json:"index_name"`
|
||||
ColumnName string `json:"column_name"`
|
||||
}
|
||||
|
||||
// NewProvider returns a new SQL provider
|
||||
func NewProvider() (*provider, error) {
|
||||
var sqlDB *gorm.DB
|
||||
@@ -50,7 +61,7 @@ func NewProvider() (*provider, error) {
|
||||
case constants.DbTypePostgres, constants.DbTypeYugabyte, constants.DbTypeCockroachDB:
|
||||
sqlDB, err = gorm.Open(postgres.Open(dbURL), ormConfig)
|
||||
case constants.DbTypeSqlite:
|
||||
sqlDB, err = gorm.Open(sqlite.Open(dbURL), ormConfig)
|
||||
sqlDB, err = gorm.Open(sqlite.Open(dbURL+"?_pragma=busy_timeout(5000)&_pragma=journal_mode(WAL)"), ormConfig)
|
||||
case constants.DbTypeMysql, constants.DbTypeMariaDB, constants.DbTypePlanetScaleDB:
|
||||
sqlDB, err = gorm.Open(mysql.Open(dbURL), ormConfig)
|
||||
case constants.DbTypeSqlserver:
|
||||
@@ -65,6 +76,32 @@ func NewProvider() (*provider, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// unique constraint on phone number does not work with multiple null values for sqlserver
|
||||
// for more information check https://stackoverflow.com/a/767702
|
||||
if dbType == constants.DbTypeSqlserver {
|
||||
var indexInfos []indexInfo
|
||||
// remove index on phone number if present with different name
|
||||
res := sqlDB.Raw("SELECT i.name AS index_name, i.type_desc AS index_algorithm, CASE i.is_unique WHEN 1 THEN 'TRUE' ELSE 'FALSE' END AS is_unique, ac.Name AS column_name FROM sys.tables AS t INNER JOIN sys.indexes AS i ON t.object_id = i.object_id INNER JOIN sys.index_columns AS ic ON ic.object_id = i.object_id AND ic.index_id = i.index_id INNER JOIN sys.all_columns AS ac ON ic.object_id = ac.object_id AND ic.column_id = ac.column_id WHERE t.name = 'authorizer_users' AND SCHEMA_NAME(t.schema_id) = 'dbo';").Scan(&indexInfos)
|
||||
if res.Error != nil {
|
||||
return nil, res.Error
|
||||
}
|
||||
|
||||
for _, val := range indexInfos {
|
||||
if val.ColumnName == phoneNumberColumnName && val.IndexName != phoneNumberIndexName {
|
||||
// drop index & create new
|
||||
if res := sqlDB.Exec(fmt.Sprintf(`ALTER TABLE authorizer_users DROP CONSTRAINT "%s";`, val.IndexName)); res.Error != nil {
|
||||
return nil, res.Error
|
||||
}
|
||||
|
||||
// create index
|
||||
if res := sqlDB.Exec(fmt.Sprintf("CREATE UNIQUE NONCLUSTERED INDEX %s ON authorizer_users(phone_number) WHERE phone_number IS NOT NULL;", phoneNumberIndexName)); res.Error != nil {
|
||||
return nil, res.Error
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return &provider{
|
||||
db: sqlDB,
|
||||
}, nil
|
||||
|
@@ -5,6 +5,7 @@ import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"strconv"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
@@ -126,6 +127,12 @@ func SendEmail(to []string, event string, data map[string]interface{}) error {
|
||||
return err
|
||||
}
|
||||
|
||||
smtpLocalName, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeySmtpLocalName)
|
||||
if err != nil {
|
||||
log.Debugf("Error while getting smtp localname from env variable: %v", err)
|
||||
smtpLocalName = ""
|
||||
}
|
||||
|
||||
isProd, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyIsProd)
|
||||
if err != nil {
|
||||
log.Errorf("Error while getting env variable: %v", err)
|
||||
@@ -141,6 +148,11 @@ func SendEmail(to []string, event string, data map[string]interface{}) error {
|
||||
if !isProd {
|
||||
d.TLSConfig = &tls.Config{InsecureSkipVerify: true}
|
||||
}
|
||||
|
||||
if strings.TrimSpace(smtpLocalName) != "" {
|
||||
d.LocalName = smtpLocalName
|
||||
}
|
||||
|
||||
if err := d.DialAndSend(m); err != nil {
|
||||
log.Debug("SMTP Failed: ", err)
|
||||
return err
|
||||
|
32
server/env/env.go
vendored
32
server/env/env.go
vendored
@@ -55,6 +55,7 @@ func InitAllEnv() error {
|
||||
osSmtpPort := os.Getenv(constants.EnvKeySmtpPort)
|
||||
osSmtpUsername := os.Getenv(constants.EnvKeySmtpUsername)
|
||||
osSmtpPassword := os.Getenv(constants.EnvKeySmtpPassword)
|
||||
osSmtpLocalName := os.Getenv(constants.EnvKeySmtpLocalName)
|
||||
osSenderEmail := os.Getenv(constants.EnvKeySenderEmail)
|
||||
osJwtType := os.Getenv(constants.EnvKeyJwtType)
|
||||
osJwtSecret := os.Getenv(constants.EnvKeyJwtSecret)
|
||||
@@ -77,6 +78,9 @@ func InitAllEnv() error {
|
||||
osResetPasswordURL := os.Getenv(constants.EnvKeyResetPasswordURL)
|
||||
osOrganizationName := os.Getenv(constants.EnvKeyOrganizationName)
|
||||
osOrganizationLogo := os.Getenv(constants.EnvKeyOrganizationLogo)
|
||||
osAwsRegion := os.Getenv(constants.EnvAwsRegion)
|
||||
osAwsAccessKey := os.Getenv(constants.EnvAwsAccessKeyID)
|
||||
osAwsSecretKey := os.Getenv(constants.EnvAwsSecretAccessKey)
|
||||
|
||||
// os bool vars
|
||||
osAppCookieSecure := os.Getenv(constants.EnvKeyAppCookieSecure)
|
||||
@@ -119,6 +123,27 @@ func InitAllEnv() error {
|
||||
}
|
||||
}
|
||||
|
||||
if val, ok := envData[constants.EnvAwsRegion]; !ok || val == "" {
|
||||
envData[constants.EnvAwsRegion] = osAwsRegion
|
||||
}
|
||||
if osAwsRegion != "" && envData[constants.EnvAwsRegion] != osAwsRegion {
|
||||
envData[constants.EnvAwsRegion] = osAwsRegion
|
||||
}
|
||||
|
||||
if val, ok := envData[constants.EnvAwsAccessKeyID]; !ok || val == "" {
|
||||
envData[constants.EnvAwsAccessKeyID] = osAwsAccessKey
|
||||
}
|
||||
if osAwsAccessKey != "" && envData[constants.EnvAwsAccessKeyID] != osAwsRegion {
|
||||
envData[constants.EnvAwsAccessKeyID] = osAwsAccessKey
|
||||
}
|
||||
|
||||
if val, ok := envData[constants.EnvAwsSecretAccessKey]; !ok || val == "" {
|
||||
envData[constants.EnvAwsSecretAccessKey] = osAwsSecretKey
|
||||
}
|
||||
if osAwsSecretKey != "" && envData[constants.EnvAwsSecretAccessKey] != osAwsRegion {
|
||||
envData[constants.EnvAwsSecretAccessKey] = osAwsSecretKey
|
||||
}
|
||||
|
||||
if val, ok := envData[constants.EnvKeyAppURL]; !ok || val == "" {
|
||||
envData[constants.EnvKeyAppURL] = osAppURL
|
||||
}
|
||||
@@ -181,6 +206,13 @@ func InitAllEnv() error {
|
||||
envData[constants.EnvKeySmtpUsername] = osSmtpUsername
|
||||
}
|
||||
|
||||
if val, ok := envData[constants.EnvKeySmtpLocalName]; !ok || val == "" {
|
||||
envData[constants.EnvKeySmtpLocalName] = osSmtpLocalName
|
||||
}
|
||||
if osSmtpLocalName != "" && envData[constants.EnvKeySmtpLocalName] != osSmtpLocalName {
|
||||
envData[constants.EnvKeySmtpLocalName] = osSmtpLocalName
|
||||
}
|
||||
|
||||
if val, ok := envData[constants.EnvKeySmtpPassword]; !ok || val == "" {
|
||||
envData[constants.EnvKeySmtpPassword] = osSmtpPassword
|
||||
}
|
||||
|
@@ -3,40 +3,41 @@ module github.com/authorizerdev/authorizer/server
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
github.com/99designs/gqlgen v0.14.0
|
||||
github.com/99designs/gqlgen v0.17.20
|
||||
github.com/arangodb/go-driver v1.2.1
|
||||
github.com/aws/aws-sdk-go v1.44.109
|
||||
github.com/coreos/go-oidc/v3 v3.1.0
|
||||
github.com/gin-gonic/gin v1.7.2
|
||||
github.com/go-playground/validator/v10 v10.8.0 // indirect
|
||||
github.com/denisenkom/go-mssqldb v0.11.0 // indirect
|
||||
github.com/gin-gonic/gin v1.8.1
|
||||
github.com/glebarez/sqlite v1.5.0 // indirect
|
||||
github.com/go-playground/validator/v10 v10.11.1 // indirect
|
||||
github.com/go-redis/redis/v8 v8.11.0
|
||||
github.com/goccy/go-json v0.9.11 // indirect
|
||||
github.com/gocql/gocql v1.2.0
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/guregu/dynamo v1.16.0
|
||||
github.com/joho/godotenv v1.3.0
|
||||
github.com/json-iterator/go v1.1.11 // indirect
|
||||
github.com/mattn/go-isatty v0.0.13 // indirect
|
||||
github.com/mitchellh/mapstructure v1.1.2 // indirect
|
||||
github.com/mitchellh/gox v1.0.1 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.1 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.5 // indirect
|
||||
github.com/robertkrimen/otto v0.0.0-20211024170158-b87d35c0b86f
|
||||
github.com/sirupsen/logrus v1.8.1
|
||||
github.com/stretchr/testify v1.7.0
|
||||
github.com/ugorji/go v1.2.6 // indirect
|
||||
github.com/vektah/gqlparser/v2 v2.2.0
|
||||
github.com/stretchr/testify v1.8.0
|
||||
github.com/vektah/gqlparser/v2 v2.5.1
|
||||
go.mongodb.org/mongo-driver v1.8.1
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519
|
||||
golang.org/x/net v0.0.0-20210614182718-04defd469f4e // indirect
|
||||
golang.org/x/crypto v0.0.0-20221005025214-4161e89ecf1b
|
||||
golang.org/x/net v0.0.0-20220930213112-107f3e3c3b0b // indirect
|
||||
golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914
|
||||
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/protobuf v1.27.1 // indirect
|
||||
google.golang.org/protobuf v1.28.1 // indirect
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
||||
gopkg.in/mail.v2 v2.3.1
|
||||
gopkg.in/square/go-jose.v2 v2.6.0
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gorm.io/driver/mysql v1.2.1
|
||||
gorm.io/driver/postgres v1.2.3
|
||||
gorm.io/driver/sqlite v1.2.6
|
||||
gorm.io/driver/sqlserver v1.2.1
|
||||
gorm.io/gorm v1.22.4
|
||||
gorm.io/driver/mysql v1.4.3
|
||||
gorm.io/driver/postgres v1.4.5
|
||||
gorm.io/driver/sqlserver v1.4.1
|
||||
gorm.io/gorm v1.24.1
|
||||
)
|
||||
|
296
server/go.sum
296
server/go.sum
@@ -31,15 +31,20 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl
|
||||
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/99designs/gqlgen v0.14.0 h1:Wg8aNYQUjMR/4v+W3xD+7SizOy6lSvVeQ06AobNQAXI=
|
||||
github.com/99designs/gqlgen v0.14.0/go.mod h1:S7z4boV+Nx4VvzMUpVrY/YuHjFX4n7rDyuTqvAkuoRE=
|
||||
github.com/99designs/gqlgen v0.17.20 h1:O7WzccIhKB1dm+7g6dhQcULINftfiLSBg2l/mwbpJMw=
|
||||
github.com/99designs/gqlgen v0.17.20/go.mod h1:Mja2HI23kWT1VRH09hvWshFgOzKswpO20o4ScpJIES4=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.0.0/go.mod h1:uGG2W01BaETf0Ozp+QxxKJdMBNRWPdstHG0Fmdwn1/U=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.0.0/go.mod h1:+6sju8gk8FRmSajX3Oz4G5Gm7P+mbqE9FVaXXFYTkCM=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.0.0/go.mod h1:eWRD7oawr1Mu1sLCawqVc0CUiF43ia3qQMxLscsKQ9w=
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v0.4.0/go.mod h1:Vt9sXTKwMyGcOxSmLDMnGPgqsUg7m8pe215qMLrDXw4=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=
|
||||
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
|
||||
github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=
|
||||
github.com/agnivade/levenshtein v1.1.0 h1:n6qGwyHG61v3ABce1rPVZklEYRT8NFpCMrpZdBUbYGM=
|
||||
github.com/agnivade/levenshtein v1.1.0/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo=
|
||||
github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8=
|
||||
github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo=
|
||||
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ=
|
||||
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
|
||||
github.com/arangodb/go-driver v1.2.1 h1:HREDHhDmzdIWxHmfkfTESbYUnRjESjPh4WUuXq7FZa8=
|
||||
@@ -48,10 +53,15 @@ github.com/arangodb/go-velocypack v0.0.0-20200318135517-5af53c29c67e h1:Xg+hGrY2
|
||||
github.com/arangodb/go-velocypack v0.0.0-20200318135517-5af53c29c67e/go.mod h1:mq7Shfa/CaixoDxiyAAc5jZ6CVBAyPaNQCGS7mkj4Ho=
|
||||
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q=
|
||||
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE=
|
||||
github.com/aws/aws-sdk-go v1.42.47/go.mod h1:OGr6lGMAKGlG9CVrYnWYDKIyb829c6EVBRjxqjmPepc=
|
||||
github.com/aws/aws-sdk-go v1.44.109 h1:+Na5JPeS0kiEHoBp5Umcuuf+IDqXqD0lXnM920E31YI=
|
||||
github.com/aws/aws-sdk-go v1.44.109/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
|
||||
github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932 h1:mXoPYz/Ul5HYEDvkta6I8/rnYM5gSdSV2tJ6XbZuEtY=
|
||||
github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k=
|
||||
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY=
|
||||
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
|
||||
github.com/cenkalti/backoff/v4 v4.1.2 h1:6Yo7N8UP2K6LWZnW94DLVSSrbobcWdVzAYOisuDPIFo=
|
||||
github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
@@ -67,8 +77,10 @@ github.com/coreos/go-oidc/v3 v3.1.0 h1:6avEvcdvTa1qYsOZ6I5PRkSYHzpTNWgKYmaJfaYbr
|
||||
github.com/coreos/go-oidc/v3 v3.1.0/go.mod h1:rEJ/idjfUyfkBit1eI1fvyr+64/g9dcKpAm8MJMesvo=
|
||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.1 h1:r/myEWzV9lfsM1tFLgDyu0atFtJ1fXn261LKYj/3DxU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@@ -79,6 +91,9 @@ github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/r
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||
github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48 h1:fRzb/w+pyskVMQ+UbP35JkH8yB7MYb4q/qhBarqZE6g=
|
||||
github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA=
|
||||
github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko=
|
||||
github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
@@ -88,8 +103,12 @@ github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWo
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||
github.com/gin-gonic/gin v1.7.2 h1:Tg03T9yM2xa8j6I3Z3oqLaQRSmKvxPd6g/2HJ6zICFA=
|
||||
github.com/gin-gonic/gin v1.7.2/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY=
|
||||
github.com/gin-gonic/gin v1.8.1 h1:4+fr/el88TOO3ewCmQr8cx/CtZ/umlIRIs5M4NTNjf8=
|
||||
github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk=
|
||||
github.com/glebarez/go-sqlite v1.19.1 h1:o2XhjyR8CQ2m84+bVz10G0cabmG0tY4sIMiCbrcUTrY=
|
||||
github.com/glebarez/go-sqlite v1.19.1/go.mod h1:9AykawGIyIcxoSfpYWiX1SgTNHTNsa/FVc75cDkbp4M=
|
||||
github.com/glebarez/sqlite v1.5.0 h1:+8LAEpmywqresSoGlqjjT+I9m4PseIM3NcerIJ/V7mk=
|
||||
github.com/glebarez/sqlite v1.5.0/go.mod h1:0wzXzTvfVJIN2GqRhCdMbnYd+m+aH5/QV7B30rM6NgY=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
@@ -97,28 +116,37 @@ github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vb
|
||||
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||
github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
|
||||
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
|
||||
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
|
||||
github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
|
||||
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
|
||||
github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
|
||||
github.com/go-playground/validator/v10 v10.8.0 h1:1kAa0fCrnpv+QYdkdcRzrRM7AyYs5o8+jZdJCz9xj6k=
|
||||
github.com/go-playground/validator/v10 v10.8.0/go.mod h1:9JhgTzTaE31GZDpH/HSvHiRJrJ3iKAgqqH0Bl/Ocjdk=
|
||||
github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU=
|
||||
github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs=
|
||||
github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho=
|
||||
github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
|
||||
github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos=
|
||||
github.com/go-playground/validator/v10 v10.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJWXmqUsHwfTRRkQ=
|
||||
github.com/go-playground/validator/v10 v10.11.1/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU=
|
||||
github.com/go-redis/redis/v8 v8.11.0 h1:O1Td0mQ8UFChQ3N9zFQqo6kTU2cJ+/it88gDB+zg0wo=
|
||||
github.com/go-redis/redis/v8 v8.11.0/go.mod h1:DLomh7y2e3ggQXQLd1YgmvIfecPJoFl7WU5SOQ/r06M=
|
||||
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
|
||||
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/goccy/go-json v0.9.11 h1:/pAaQDLHEoCq/5FFmSKBswWmK6H0e8g4159Kc/X/nqk=
|
||||
github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/gocql/gocql v1.2.0 h1:TZhsCd7fRuye4VyHr3WCvWwIQaZUmjsqnSIXK9FcVCE=
|
||||
github.com/gocql/gocql v1.2.0/go.mod h1:3gM2c4D3AnkISwBxGnMMsS8Oy4y2lhbPRsH4xnJrHG8=
|
||||
github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw=
|
||||
github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/gofrs/uuid v4.2.0+incompatible h1:yyYWMnhkhrKwwr8gAOcOCYxOOscHgDS9yZgBrnJfGa0=
|
||||
github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||
github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
|
||||
github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
|
||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY=
|
||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
||||
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA=
|
||||
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
||||
github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A=
|
||||
github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
@@ -159,6 +187,7 @@ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
@@ -178,15 +207,18 @@ github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/gorilla/context v0.0.0-20160226214623-1ea25387ff6f/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
||||
github.com/gorilla/mux v1.6.1/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
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/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/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.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
|
||||
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/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0=
|
||||
@@ -202,6 +234,8 @@ github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8
|
||||
github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI=
|
||||
github.com/jackc/pgconn v1.10.1 h1:DzdIHIjG1AxGwoEEqS+mGsURyjt4enSmqzACXvVzOT8=
|
||||
github.com/jackc/pgconn v1.10.1/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI=
|
||||
github.com/jackc/pgconn v1.13.0 h1:3L1XMNV2Zvca/8BYhzcRFS70Lr0WlDg16Di6SFGAbys=
|
||||
github.com/jackc/pgconn v1.13.0/go.mod h1:AnowpAqO4CMIIJNZl2VJp+KrkAZciAkhEl0W0JIobpI=
|
||||
github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE=
|
||||
github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8=
|
||||
github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE=
|
||||
@@ -220,6 +254,8 @@ github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwX
|
||||
github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
|
||||
github.com/jackc/pgproto3/v2 v2.2.0 h1:r7JypeP2D3onoQTCxWdTpCtJ4D+qpKr0TxvoyMhZ5ns=
|
||||
github.com/jackc/pgproto3/v2 v2.2.0/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
|
||||
github.com/jackc/pgproto3/v2 v2.3.1 h1:nwj7qwf0S+Q7ISFfBndqeLwSwxs+4DPsbRFjECT1Y4Y=
|
||||
github.com/jackc/pgproto3/v2 v2.3.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
|
||||
github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b h1:C8S2+VttkHFdOOCXJe+YGfa4vHYwlt4Zx+IVXQ97jYg=
|
||||
github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E=
|
||||
github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg=
|
||||
@@ -228,41 +264,56 @@ github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrU
|
||||
github.com/jackc/pgtype v1.8.1-0.20210724151600-32e20a603178/go.mod h1:C516IlIV9NKqfsMCXTdChteoXmwgUceqaLfjg2e3NlM=
|
||||
github.com/jackc/pgtype v1.9.0 h1:/SH1RxEtltvJgsDqp3TbiTFApD3mey3iygpuEGeuBXk=
|
||||
github.com/jackc/pgtype v1.9.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4=
|
||||
github.com/jackc/pgtype v1.12.0 h1:Dlq8Qvcch7kiehm8wPGIW0W3KsCCHJnRacKW0UM8n5w=
|
||||
github.com/jackc/pgtype v1.12.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4=
|
||||
github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y=
|
||||
github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM=
|
||||
github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc=
|
||||
github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs=
|
||||
github.com/jackc/pgx/v4 v4.14.0 h1:TgdrmgnM7VY72EuSQzBbBd4JA1RLqJolrw9nQVZABVc=
|
||||
github.com/jackc/pgx/v4 v4.14.0/go.mod h1:jT3ibf/A0ZVCp89rtCIN0zCJxcE74ypROmHEZYsG/j8=
|
||||
github.com/jackc/pgx/v4 v4.17.2 h1:0Ut0rpeKwvIVbMQ1KbMBU4h6wxehBI535LK6Flheh8E=
|
||||
github.com/jackc/pgx/v4 v4.17.2/go.mod h1:lcxIZN44yMIrWI78a5CpucdD14hX0SBDbNRvjDBItsw=
|
||||
github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||
github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||
github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||
github.com/jackc/puddle v1.2.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||
github.com/jackc/puddle v1.3.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/jinzhu/now v1.1.2/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/jinzhu/now v1.1.3 h1:PlHq1bSCSZL9K0wUhbm2pGLoTWs2GwVhsP6emvGV/ZI=
|
||||
github.com/jinzhu/now v1.1.3/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
||||
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
|
||||
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
|
||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
|
||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
|
||||
github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc=
|
||||
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
|
||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ=
|
||||
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
||||
github.com/kevinmbeaulieu/eq-go v1.0.0/go.mod h1:G3S8ajA56gKBZm4UB9AOyoOS37JO3roToPzKNM8dtdM=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc=
|
||||
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
|
||||
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
|
||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
@@ -270,29 +321,37 @@ github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.10.2 h1:AqzbZs4ZoCBp+GtejcpCpcxM3zlSMx29dXbUSeVtJb8=
|
||||
github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
|
||||
github.com/matryer/moq v0.0.0-20200106131100-75d0ddfc0007/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ=
|
||||
github.com/logrusorgru/aurora/v3 v3.0.0/go.mod h1:vsR12bk5grlLvLXAYrBsb5Oc/N+LxAlxggSjiwMnCUc=
|
||||
github.com/matryer/moq v0.2.7/go.mod h1:kITsx543GOENm48TUAQyJ9+SAvFSr7iGQXPoth/VUBk=
|
||||
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
|
||||
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-isatty v0.0.13 h1:qdl+GuBjcsKKDco5BsxPJlId98mSWNKqYA+Co0SC1yA=
|
||||
github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
|
||||
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/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
github.com/mitchellh/mapstructure v0.0.0-20180203102830-a4e142e9c047/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI=
|
||||
github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||
github.com/microsoft/go-mssqldb v0.17.0 h1:Fto83dMZPnYv1Zwx5vHHxpNraeEaUlQ/hhHLgZiaenE=
|
||||
github.com/microsoft/go-mssqldb v0.17.0/go.mod h1:OkoNGhGEs8EZqchVTtochlXruEhEOaO4S0d2sB5aeGQ=
|
||||
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/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-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8=
|
||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
|
||||
github.com/montanaflynn/stats v0.6.6/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
|
||||
github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
@@ -303,32 +362,38 @@ github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7J
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/onsi/gomega v1.10.5 h1:7n6FEkpFmfCoo2t+YYqXH0evK+a9ICQz0xcAy9dYcaQ=
|
||||
github.com/onsi/gomega v1.10.5/go.mod h1:gza4q3jKQJijlu05nKWRCW/GavJumGt8aNRxWg7mt48=
|
||||
github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
|
||||
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo=
|
||||
github.com/pelletier/go-toml/v2 v2.0.5 h1:ipoSadvV8oGUjnUbMub59IDPPwfxF694nG/jwbMiyQg=
|
||||
github.com/pelletier/go-toml/v2 v2.0.5/go.mod h1:OMHamSCAODeSsVrwwvcJOaoN0LIUIaFVNZzmWyNfXas=
|
||||
github.com/pkg/browser v0.0.0-20210115035449-ce105d075bb4/go.mod h1:N6UoU20jOqggOuDwUaBQpluzLNDqif3kq9z2wpdYEfQ=
|
||||
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/robertkrimen/otto v0.0.0-20211024170158-b87d35c0b86f h1:a7clxaGmmqtdNTXyvrp/lVO/Gnkzlhc/+dLs5v965GM=
|
||||
github.com/robertkrimen/otto v0.0.0-20211024170158-b87d35c0b86f/go.mod h1:/mK7FZ3mFYEn9zvNPhpngTyatyehSwte5bJZ4ehL5Xw=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8=
|
||||
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
|
||||
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
|
||||
github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
|
||||
github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
|
||||
github.com/rs/zerolog v1.19.0/go.mod h1:IzD0RJ65iWH0w97OQQebJEvTZYvsCUm9WVLWBQrJRjo=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
|
||||
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
|
||||
github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ=
|
||||
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
||||
github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/shurcooL/vfsgen v0.0.0-20180121065927-ffb13db8def0/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw=
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
|
||||
@@ -336,38 +401,42 @@ github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||
github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
|
||||
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
|
||||
github.com/ugorji/go v1.2.6 h1:tGiWC9HENWE2tqYycIqFTNorMmFRVhNwCpDOpWqnk8E=
|
||||
github.com/ugorji/go v1.2.6/go.mod h1:anCg0y61KIhDlPZmnH+so+RQbysYVyDko0IMgJv0Nn0=
|
||||
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
|
||||
github.com/ugorji/go/codec v1.2.6 h1:7kbGefxLoDBuYXOms4yD7223OpNMMPNPZxXk5TvFcyQ=
|
||||
github.com/ugorji/go/codec v1.2.6/go.mod h1:V6TCNZ4PHqoHGFZuSG1W8nrCzzdgA2DozYxWFFpvxTw=
|
||||
github.com/urfave/cli/v2 v2.1.1/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ=
|
||||
github.com/vektah/dataloaden v0.2.1-0.20190515034641-a19b9a6e7c9e/go.mod h1:/HUdMve7rvxZma+2ZELQeNh88+003LL7Pf/CZ089j8U=
|
||||
github.com/vektah/gqlparser/v2 v2.2.0 h1:bAc3slekAAJW6sZTi07aGq0OrfaCjj4jxARAaC7g2EM=
|
||||
github.com/vektah/gqlparser/v2 v2.2.0/go.mod h1:i3mQIGIrbK2PD1RrCeMTlVbkF2FJ6WkU1KJlJlC+3F4=
|
||||
github.com/ugorji/go v1.2.7 h1:qYhyWUUd6WbiM+C6JZAUkIJt/1WrjzNHY9+KCIjVqTo=
|
||||
github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M=
|
||||
github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0=
|
||||
github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
|
||||
github.com/urfave/cli/v2 v2.8.1 h1:CGuYNZF9IKZY/rfBe3lJpccSoIY1ytfvmgQT90cNOl4=
|
||||
github.com/urfave/cli/v2 v2.8.1/go.mod h1:Z41J9TPoffeoqP0Iza0YbAhGvymRdZAd2uPmZ5JxRdY=
|
||||
github.com/vektah/gqlparser/v2 v2.5.1 h1:ZGu+bquAY23jsxDRcYpWjttRZrUz07LbiY77gUOHcr4=
|
||||
github.com/vektah/gqlparser/v2 v2.5.1/go.mod h1:mPgqFBu/woKTVYWyNk8cO3kh4S/f4aRFZrvOnp3hmCs=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
|
||||
github.com/xdg-go/scram v1.0.2 h1:akYIkZ28e6A96dkWNJQu3nmCzH3YfwMPQExUYDaRv7w=
|
||||
github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs=
|
||||
github.com/xdg-go/stringprep v1.0.2 h1:6iq84/ryjjeRmMJwxutI51F2GIPlP5BfTvXHeYjyhBc=
|
||||
github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM=
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
|
||||
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA=
|
||||
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
|
||||
go.mongodb.org/mongo-driver v1.8.1 h1:OZE4Wni/SJlrcmSIBRYNzunX5TKxjrTS4jKSnA99oKU=
|
||||
go.mongodb.org/mongo-driver v1.8.1/go.mod h1:0sQWfOeY63QTntERDJJ/0SuKK0T1uVSgKCuAROlKEPY=
|
||||
@@ -399,8 +468,14 @@ golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWP
|
||||
golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220511200225-c6db032c6c88/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be h1:fmw3UbQh+nxngCAHrDCCztao/kbYFnWjoqop8dHx05A=
|
||||
golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20221005025214-4161e89ecf1b h1:huxqepDufQpLLIRXiVkTvnxrzJlpwmIWAObmcCcUFr0=
|
||||
golang.org/x/crypto v0.0.0-20221005025214-4161e89ecf1b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
@@ -431,6 +506,9 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB
|
||||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@@ -461,11 +539,18 @@ golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210614182718-04defd469f4e h1:XpT3nA5TvE525Ne3hInMh6+GETgn27Zfm9dxsThnX2Q=
|
||||
golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.0.0-20220930213112-107f3e3c3b0b h1:uKO3Js8lXGjpjdc4J3rqs0/Ex5yDKUGfk43tTYWVLas=
|
||||
golang.org/x/net v0.0.0-20220930213112-107f3e3c3b0b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
@@ -481,8 +566,10 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@@ -522,12 +609,26 @@ golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I=
|
||||
golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220224120231-95c6836cb0e7/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec h1:BkDtF2Ih9xZ7le9ndzTA7KJow28VbQW3odyk/8drmuI=
|
||||
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@@ -543,7 +644,6 @@ golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxb
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
@@ -551,7 +651,6 @@ golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3
|
||||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190515012406-7d7faa4812bd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
@@ -587,12 +686,14 @@ golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roY
|
||||
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
|
||||
golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
@@ -677,14 +778,16 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
|
||||
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s=
|
||||
@@ -700,26 +803,41 @@ gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI
|
||||
gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gorm.io/driver/mysql v1.2.1 h1:h+3f1l9Ng2C072Y2tIiLgPpWN78r1KXL7bHJ0nTjlhU=
|
||||
gorm.io/driver/mysql v1.2.1/go.mod h1:qsiz+XcAyMrS6QY+X3M9R6b/lKM1imKmcuK9kac5LTo=
|
||||
gorm.io/driver/mysql v1.4.3 h1:/JhWJhO2v17d8hjApTltKNADm7K7YI2ogkR7avJUL3k=
|
||||
gorm.io/driver/mysql v1.4.3/go.mod h1:sSIebwZAVPiT+27jK9HIwvsqOGKx3YMPmrA3mBJR10c=
|
||||
gorm.io/driver/postgres v1.2.3 h1:f4t0TmNMy9gh3TU2PX+EppoA6YsgFnyq8Ojtddb42To=
|
||||
gorm.io/driver/postgres v1.2.3/go.mod h1:pJV6RgYQPG47aM1f0QeOzFH9HxQc8JcmAgjRCgS0wjs=
|
||||
gorm.io/driver/postgres v1.4.5 h1:mTeXTTtHAgnS9PgmhN2YeUbazYpLhUI1doLnw42XUZc=
|
||||
gorm.io/driver/postgres v1.4.5/go.mod h1:GKNQYSJ14qvWkvPwXljMGehpKrhlDNsqYRr5HnYGncg=
|
||||
gorm.io/driver/sqlite v1.2.6 h1:SStaH/b+280M7C8vXeZLz/zo9cLQmIGwwj3cSj7p6l4=
|
||||
gorm.io/driver/sqlite v1.2.6/go.mod h1:gyoX0vHiiwi0g49tv+x2E7l8ksauLK0U/gShcdUsjWY=
|
||||
gorm.io/driver/sqlserver v1.2.1 h1:KhGOjvPX7JZ5hPyQICTJfMuTz88zgJ2lk9bWiHVNHd8=
|
||||
gorm.io/driver/sqlserver v1.2.1/go.mod h1:nixq0OB3iLXZDiPv6JSOjWuPgpyaRpOIIevYtA4Ulb4=
|
||||
gorm.io/driver/sqlserver v1.4.1 h1:t4r4r6Jam5E6ejqP7N82qAJIJAht27EGT41HyPfXRw0=
|
||||
gorm.io/driver/sqlserver v1.4.1/go.mod h1:DJ4P+MeZbc5rvY58PnmN1Lnyvb5gw5NPzGshHDnJLig=
|
||||
gorm.io/gorm v1.22.2/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0=
|
||||
gorm.io/gorm v1.22.3/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0=
|
||||
gorm.io/gorm v1.22.4 h1:8aPcyEJhY0MAt8aY6Dc524Pn+pO29K+ydu+e/cXSpQM=
|
||||
gorm.io/gorm v1.22.4/go.mod h1:1aeVC+pe9ZmvKZban/gW4QPra7PRoTEssyc922qCAkk=
|
||||
gorm.io/gorm v1.23.8/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
|
||||
gorm.io/gorm v1.24.0 h1:j/CoiSm6xpRpmzbFJsQHYj+I8bGYWLXVHeYEyyKlF74=
|
||||
gorm.io/gorm v1.24.0/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA=
|
||||
gorm.io/gorm v1.24.1-0.20221019064659-5dd2bb482755/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA=
|
||||
gorm.io/gorm v1.24.1 h1:CgvzRniUdG67hBAzsxDGOAuq4Te1osVMYsa1eQbd4fs=
|
||||
gorm.io/gorm v1.24.1/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
@@ -727,8 +845,38 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
|
||||
modernc.org/cc/v3 v3.36.2/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI=
|
||||
modernc.org/cc/v3 v3.37.0/go.mod h1:vtL+3mdHx/wcj3iEGz84rQa8vEqR6XM84v5Lcvfph20=
|
||||
modernc.org/cc/v3 v3.38.1/go.mod h1:vtL+3mdHx/wcj3iEGz84rQa8vEqR6XM84v5Lcvfph20=
|
||||
modernc.org/ccgo/v3 v3.0.0-20220904174949-82d86e1b6d56/go.mod h1:YSXjPL62P2AMSxBphRHPn7IkzhVHqkvOnRKAKh+W6ZI=
|
||||
modernc.org/ccgo/v3 v3.0.0-20220910160915-348f15de615a/go.mod h1:8p47QxPkdugex9J4n9P2tLZ9bK01yngIVp00g4nomW0=
|
||||
modernc.org/ccgo/v3 v3.16.9/go.mod h1:zNMzC9A9xeNUepy6KuZBbugn3c0Mc9TeiJO4lgvkJDo=
|
||||
modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ=
|
||||
modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM=
|
||||
modernc.org/libc v1.17.0/go.mod h1:XsgLldpP4aWlPlsjqKRdHPqCxCjISdHfM/yeWC5GyW0=
|
||||
modernc.org/libc v1.17.4/go.mod h1:WNg2ZH56rDEwdropAJeZPQkXmDwh+JCA1s/htl6r2fA=
|
||||
modernc.org/libc v1.18.0/go.mod h1:vj6zehR5bfc98ipowQOM2nIDUZnVew/wNC/2tOGS+q0=
|
||||
modernc.org/libc v1.19.0 h1:bXyVhGQg6KIClTr8FMVIDPl7jtbcs7aS5WP7vLDaxPs=
|
||||
modernc.org/libc v1.19.0/go.mod h1:ZRfIaEkgrYgZDl6pa4W39HgN5G/yDW+NRmNKZBDFrk0=
|
||||
modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||
modernc.org/mathutil v1.4.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||
modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ=
|
||||
modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||
modernc.org/memory v1.2.0/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw=
|
||||
modernc.org/memory v1.3.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
|
||||
modernc.org/memory v1.4.0 h1:crykUfNSnMAXaOJnnxcSzbUGMqkLWjklJKkBK2nwZwk=
|
||||
modernc.org/memory v1.4.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
|
||||
modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
|
||||
modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
|
||||
modernc.org/sqlite v1.19.1 h1:8xmS5oLnZtAK//vnd4aTVj8VOeTAccEFOtUnIzfSw+4=
|
||||
modernc.org/sqlite v1.19.1/go.mod h1:UfQ83woKMaPW/ZBruK0T7YaFCrI+IE0LeWVY6pmnVms=
|
||||
modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw=
|
||||
modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw=
|
||||
modernc.org/tcl v1.14.0/go.mod h1:gQ7c1YPMvryCHCcmf8acB6VPabE59QBeuRQLL7cTUlM=
|
||||
modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
|
||||
modernc.org/token v1.0.1/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
|
||||
modernc.org/z v1.6.0/go.mod h1:hVdgNMh8ggTuRG1rGU8x+xGRFfiQUIAw0ZqlPy8+HyQ=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU=
|
||||
sourcegraph.com/sourcegraph/appdash-data v0.0.0-20151005221446-73f23eafcf67/go.mod h1:L5q+DGLGOQFpo1snNEkLOJT2d1YTW66rWNzatr3He1k=
|
||||
|
@@ -23,19 +23,26 @@ resolver:
|
||||
dir: graph
|
||||
package: graph
|
||||
|
||||
# Optional: turn on use `gqlgen:"fieldName"` tags in your models
|
||||
# Optional: turn on use ` + "`" + `gqlgen:"fieldName"` + "`" + ` tags in your models
|
||||
# struct_tag: json
|
||||
|
||||
# Optional: turn on to use []Thing instead of []*Thing
|
||||
# omit_slice_element_pointers: false
|
||||
|
||||
# Optional: turn off to make struct-type struct fields not use pointers
|
||||
# e.g. type Thing struct { FieldA OtherThing } instead of { FieldA *OtherThing }
|
||||
# struct_fields_always_pointers: true
|
||||
|
||||
# Optional: turn off to make resolvers return values instead of pointers for structs
|
||||
# resolvers_always_return_pointers: true
|
||||
|
||||
# Optional: set to speed up generation time by not performing a final validation pass.
|
||||
# skip_validation: true
|
||||
|
||||
# gqlgen will search for any type names in the schema in these go packages
|
||||
# if they match it will use them, otherwise it will generate them.
|
||||
autobind:
|
||||
- 'github.com/authorizerdev/authorizer/server/graph/model'
|
||||
# - "github.com/authorizerdev/authorizer/server/graph/model"
|
||||
|
||||
# This section declares type mapping between the GraphQL and go type systems
|
||||
#
|
||||
@@ -45,7 +52,6 @@ autobind:
|
||||
models:
|
||||
ID:
|
||||
model:
|
||||
# - github.com/99designs/gqlgen/graphql.IntID # An go integer
|
||||
- github.com/99designs/gqlgen/graphql.ID
|
||||
- github.com/99designs/gqlgen/graphql.Int
|
||||
- github.com/99designs/gqlgen/graphql.Int64
|
||||
@@ -55,11 +61,12 @@ models:
|
||||
- github.com/99designs/gqlgen/graphql.Int
|
||||
- github.com/99designs/gqlgen/graphql.Int64
|
||||
- github.com/99designs/gqlgen/graphql.Int32
|
||||
Float:
|
||||
model:
|
||||
- github.com/99designs/gqlgen/graphql.Float
|
||||
- github.com/99designs/gqlgen/graphql.Float64
|
||||
- github.com/99designs/gqlgen/graphql.Float32
|
||||
Int64:
|
||||
model:
|
||||
- github.com/99designs/gqlgen/graphql.Int64
|
||||
Map:
|
||||
model:
|
||||
- github.com/99designs/gqlgen/graphql.Map
|
||||
Any:
|
||||
model:
|
||||
- github.com/99designs/gqlgen/graphql.Any
|
File diff suppressed because it is too large
Load Diff
@@ -74,6 +74,7 @@ type Env struct {
|
||||
SMTPPort *string `json:"SMTP_PORT"`
|
||||
SMTPUsername *string `json:"SMTP_USERNAME"`
|
||||
SMTPPassword *string `json:"SMTP_PASSWORD"`
|
||||
SMTPLocalName *string `json:"SMTP_LOCAL_NAME"`
|
||||
SenderEmail *string `json:"SENDER_EMAIL"`
|
||||
JwtType *string `json:"JWT_TYPE"`
|
||||
JwtSecret *string `json:"JWT_SECRET"`
|
||||
@@ -110,6 +111,8 @@ type Env struct {
|
||||
TwitterClientSecret *string `json:"TWITTER_CLIENT_SECRET"`
|
||||
OrganizationName *string `json:"ORGANIZATION_NAME"`
|
||||
OrganizationLogo *string `json:"ORGANIZATION_LOGO"`
|
||||
AppCookieSecure bool `json:"APP_COOKIE_SECURE"`
|
||||
AdminCookieSecure bool `json:"ADMIN_COOKIE_SECURE"`
|
||||
}
|
||||
|
||||
type Error struct {
|
||||
@@ -269,6 +272,7 @@ type UpdateEnvInput struct {
|
||||
SMTPPort *string `json:"SMTP_PORT"`
|
||||
SMTPUsername *string `json:"SMTP_USERNAME"`
|
||||
SMTPPassword *string `json:"SMTP_PASSWORD"`
|
||||
SMTPLocalName *string `json:"SMTP_LOCAL_NAME"`
|
||||
SenderEmail *string `json:"SENDER_EMAIL"`
|
||||
JwtType *string `json:"JWT_TYPE"`
|
||||
JwtSecret *string `json:"JWT_SECRET"`
|
||||
@@ -277,6 +281,8 @@ type UpdateEnvInput struct {
|
||||
AllowedOrigins []string `json:"ALLOWED_ORIGINS"`
|
||||
AppURL *string `json:"APP_URL"`
|
||||
ResetPasswordURL *string `json:"RESET_PASSWORD_URL"`
|
||||
AppCookieSecure *bool `json:"APP_COOKIE_SECURE"`
|
||||
AdminCookieSecure *bool `json:"ADMIN_COOKIE_SECURE"`
|
||||
DisableEmailVerification *bool `json:"DISABLE_EMAIL_VERIFICATION"`
|
||||
DisableBasicAuthentication *bool `json:"DISABLE_BASIC_AUTHENTICATION"`
|
||||
DisableMagicLinkLogin *bool `json:"DISABLE_MAGIC_LINK_LOGIN"`
|
||||
@@ -380,7 +386,8 @@ type ValidateJWTTokenInput struct {
|
||||
}
|
||||
|
||||
type ValidateJWTTokenResponse struct {
|
||||
IsValid bool `json:"is_valid"`
|
||||
IsValid bool `json:"is_valid"`
|
||||
Claims map[string]interface{} `json:"claims"`
|
||||
}
|
||||
|
||||
type VerificationRequest struct {
|
||||
|
@@ -6,492 +6,499 @@ scalar Map
|
||||
scalar Any
|
||||
|
||||
type Pagination {
|
||||
limit: Int64!
|
||||
page: Int64!
|
||||
offset: Int64!
|
||||
total: Int64!
|
||||
limit: Int64!
|
||||
page: Int64!
|
||||
offset: Int64!
|
||||
total: Int64!
|
||||
}
|
||||
|
||||
type Meta {
|
||||
version: String!
|
||||
client_id: String!
|
||||
is_google_login_enabled: Boolean!
|
||||
is_facebook_login_enabled: Boolean!
|
||||
is_github_login_enabled: Boolean!
|
||||
is_linkedin_login_enabled: Boolean!
|
||||
is_apple_login_enabled: Boolean!
|
||||
is_twitter_login_enabled: Boolean!
|
||||
is_email_verification_enabled: Boolean!
|
||||
is_basic_authentication_enabled: Boolean!
|
||||
is_magic_link_login_enabled: Boolean!
|
||||
is_sign_up_enabled: Boolean!
|
||||
is_strong_password_enabled: Boolean!
|
||||
is_multi_factor_auth_enabled: Boolean!
|
||||
version: String!
|
||||
client_id: String!
|
||||
is_google_login_enabled: Boolean!
|
||||
is_facebook_login_enabled: Boolean!
|
||||
is_github_login_enabled: Boolean!
|
||||
is_linkedin_login_enabled: Boolean!
|
||||
is_apple_login_enabled: Boolean!
|
||||
is_twitter_login_enabled: Boolean!
|
||||
is_email_verification_enabled: Boolean!
|
||||
is_basic_authentication_enabled: Boolean!
|
||||
is_magic_link_login_enabled: Boolean!
|
||||
is_sign_up_enabled: Boolean!
|
||||
is_strong_password_enabled: Boolean!
|
||||
is_multi_factor_auth_enabled: Boolean!
|
||||
}
|
||||
|
||||
type User {
|
||||
id: ID!
|
||||
email: String!
|
||||
email_verified: Boolean!
|
||||
signup_methods: String!
|
||||
given_name: String
|
||||
family_name: String
|
||||
middle_name: String
|
||||
nickname: String
|
||||
# defaults to email
|
||||
preferred_username: String
|
||||
gender: String
|
||||
birthdate: String
|
||||
phone_number: String
|
||||
phone_number_verified: Boolean
|
||||
picture: String
|
||||
roles: [String!]!
|
||||
created_at: Int64
|
||||
updated_at: Int64
|
||||
revoked_timestamp: Int64
|
||||
is_multi_factor_auth_enabled: Boolean
|
||||
id: ID!
|
||||
email: String!
|
||||
email_verified: Boolean!
|
||||
signup_methods: String!
|
||||
given_name: String
|
||||
family_name: String
|
||||
middle_name: String
|
||||
nickname: String
|
||||
# defaults to email
|
||||
preferred_username: String
|
||||
gender: String
|
||||
birthdate: String
|
||||
phone_number: String
|
||||
phone_number_verified: Boolean
|
||||
picture: String
|
||||
roles: [String!]!
|
||||
created_at: Int64
|
||||
updated_at: Int64
|
||||
revoked_timestamp: Int64
|
||||
is_multi_factor_auth_enabled: Boolean
|
||||
}
|
||||
|
||||
type Users {
|
||||
pagination: Pagination!
|
||||
users: [User!]!
|
||||
pagination: Pagination!
|
||||
users: [User!]!
|
||||
}
|
||||
|
||||
type VerificationRequest {
|
||||
id: ID!
|
||||
identifier: String
|
||||
token: String
|
||||
email: String
|
||||
expires: Int64
|
||||
created_at: Int64
|
||||
updated_at: Int64
|
||||
nonce: String
|
||||
redirect_uri: String
|
||||
id: ID!
|
||||
identifier: String
|
||||
token: String
|
||||
email: String
|
||||
expires: Int64
|
||||
created_at: Int64
|
||||
updated_at: Int64
|
||||
nonce: String
|
||||
redirect_uri: String
|
||||
}
|
||||
|
||||
type VerificationRequests {
|
||||
pagination: Pagination!
|
||||
verification_requests: [VerificationRequest!]!
|
||||
pagination: Pagination!
|
||||
verification_requests: [VerificationRequest!]!
|
||||
}
|
||||
|
||||
type Error {
|
||||
message: String!
|
||||
reason: String!
|
||||
message: String!
|
||||
reason: String!
|
||||
}
|
||||
|
||||
type AuthResponse {
|
||||
message: String!
|
||||
should_show_otp_screen: Boolean
|
||||
access_token: String
|
||||
id_token: String
|
||||
refresh_token: String
|
||||
expires_in: Int64
|
||||
user: User
|
||||
message: String!
|
||||
should_show_otp_screen: Boolean
|
||||
access_token: String
|
||||
id_token: String
|
||||
refresh_token: String
|
||||
expires_in: Int64
|
||||
user: User
|
||||
}
|
||||
|
||||
type Response {
|
||||
message: String!
|
||||
message: String!
|
||||
}
|
||||
|
||||
type Env {
|
||||
ACCESS_TOKEN_EXPIRY_TIME: String
|
||||
ADMIN_SECRET: String
|
||||
DATABASE_NAME: String
|
||||
DATABASE_URL: String
|
||||
DATABASE_TYPE: String
|
||||
DATABASE_USERNAME: String
|
||||
DATABASE_PASSWORD: String
|
||||
DATABASE_HOST: String
|
||||
DATABASE_PORT: String
|
||||
CLIENT_ID: String!
|
||||
CLIENT_SECRET: String!
|
||||
CUSTOM_ACCESS_TOKEN_SCRIPT: String
|
||||
SMTP_HOST: String
|
||||
SMTP_PORT: String
|
||||
SMTP_USERNAME: String
|
||||
SMTP_PASSWORD: String
|
||||
SENDER_EMAIL: String
|
||||
JWT_TYPE: String
|
||||
JWT_SECRET: String
|
||||
JWT_PRIVATE_KEY: String
|
||||
JWT_PUBLIC_KEY: String
|
||||
ALLOWED_ORIGINS: [String!]
|
||||
APP_URL: String
|
||||
REDIS_URL: String
|
||||
RESET_PASSWORD_URL: String
|
||||
DISABLE_EMAIL_VERIFICATION: Boolean!
|
||||
DISABLE_BASIC_AUTHENTICATION: Boolean!
|
||||
DISABLE_MAGIC_LINK_LOGIN: Boolean!
|
||||
DISABLE_LOGIN_PAGE: Boolean!
|
||||
DISABLE_SIGN_UP: Boolean!
|
||||
DISABLE_REDIS_FOR_ENV: Boolean!
|
||||
DISABLE_STRONG_PASSWORD: Boolean!
|
||||
DISABLE_MULTI_FACTOR_AUTHENTICATION: Boolean!
|
||||
ENFORCE_MULTI_FACTOR_AUTHENTICATION: Boolean!
|
||||
ROLES: [String!]
|
||||
PROTECTED_ROLES: [String!]
|
||||
DEFAULT_ROLES: [String!]
|
||||
JWT_ROLE_CLAIM: String
|
||||
GOOGLE_CLIENT_ID: String
|
||||
GOOGLE_CLIENT_SECRET: String
|
||||
GITHUB_CLIENT_ID: String
|
||||
GITHUB_CLIENT_SECRET: String
|
||||
FACEBOOK_CLIENT_ID: String
|
||||
FACEBOOK_CLIENT_SECRET: String
|
||||
LINKEDIN_CLIENT_ID: String
|
||||
LINKEDIN_CLIENT_SECRET: String
|
||||
APPLE_CLIENT_ID: String
|
||||
APPLE_CLIENT_SECRET: String
|
||||
TWITTER_CLIENT_ID: String
|
||||
TWITTER_CLIENT_SECRET: String
|
||||
ORGANIZATION_NAME: String
|
||||
ORGANIZATION_LOGO: String
|
||||
ACCESS_TOKEN_EXPIRY_TIME: String
|
||||
ADMIN_SECRET: String
|
||||
DATABASE_NAME: String
|
||||
DATABASE_URL: String
|
||||
DATABASE_TYPE: String
|
||||
DATABASE_USERNAME: String
|
||||
DATABASE_PASSWORD: String
|
||||
DATABASE_HOST: String
|
||||
DATABASE_PORT: String
|
||||
CLIENT_ID: String!
|
||||
CLIENT_SECRET: String!
|
||||
CUSTOM_ACCESS_TOKEN_SCRIPT: String
|
||||
SMTP_HOST: String
|
||||
SMTP_PORT: String
|
||||
SMTP_USERNAME: String
|
||||
SMTP_PASSWORD: String
|
||||
SMTP_LOCAL_NAME: String
|
||||
SENDER_EMAIL: String
|
||||
JWT_TYPE: String
|
||||
JWT_SECRET: String
|
||||
JWT_PRIVATE_KEY: String
|
||||
JWT_PUBLIC_KEY: String
|
||||
ALLOWED_ORIGINS: [String!]
|
||||
APP_URL: String
|
||||
REDIS_URL: String
|
||||
RESET_PASSWORD_URL: String
|
||||
DISABLE_EMAIL_VERIFICATION: Boolean!
|
||||
DISABLE_BASIC_AUTHENTICATION: Boolean!
|
||||
DISABLE_MAGIC_LINK_LOGIN: Boolean!
|
||||
DISABLE_LOGIN_PAGE: Boolean!
|
||||
DISABLE_SIGN_UP: Boolean!
|
||||
DISABLE_REDIS_FOR_ENV: Boolean!
|
||||
DISABLE_STRONG_PASSWORD: Boolean!
|
||||
DISABLE_MULTI_FACTOR_AUTHENTICATION: Boolean!
|
||||
ENFORCE_MULTI_FACTOR_AUTHENTICATION: Boolean!
|
||||
ROLES: [String!]
|
||||
PROTECTED_ROLES: [String!]
|
||||
DEFAULT_ROLES: [String!]
|
||||
JWT_ROLE_CLAIM: String
|
||||
GOOGLE_CLIENT_ID: String
|
||||
GOOGLE_CLIENT_SECRET: String
|
||||
GITHUB_CLIENT_ID: String
|
||||
GITHUB_CLIENT_SECRET: String
|
||||
FACEBOOK_CLIENT_ID: String
|
||||
FACEBOOK_CLIENT_SECRET: String
|
||||
LINKEDIN_CLIENT_ID: String
|
||||
LINKEDIN_CLIENT_SECRET: String
|
||||
APPLE_CLIENT_ID: String
|
||||
APPLE_CLIENT_SECRET: String
|
||||
TWITTER_CLIENT_ID: String
|
||||
TWITTER_CLIENT_SECRET: String
|
||||
ORGANIZATION_NAME: String
|
||||
ORGANIZATION_LOGO: String
|
||||
APP_COOKIE_SECURE: Boolean!
|
||||
ADMIN_COOKIE_SECURE: Boolean!
|
||||
}
|
||||
|
||||
type ValidateJWTTokenResponse {
|
||||
is_valid: Boolean!
|
||||
is_valid: Boolean!
|
||||
claims: Map
|
||||
}
|
||||
|
||||
type GenerateJWTKeysResponse {
|
||||
secret: String
|
||||
public_key: String
|
||||
private_key: String
|
||||
secret: String
|
||||
public_key: String
|
||||
private_key: String
|
||||
}
|
||||
|
||||
type Webhook {
|
||||
id: ID!
|
||||
event_name: String
|
||||
endpoint: String
|
||||
enabled: Boolean
|
||||
headers: Map
|
||||
created_at: Int64
|
||||
updated_at: Int64
|
||||
id: ID!
|
||||
event_name: String
|
||||
endpoint: String
|
||||
enabled: Boolean
|
||||
headers: Map
|
||||
created_at: Int64
|
||||
updated_at: Int64
|
||||
}
|
||||
|
||||
type Webhooks {
|
||||
pagination: Pagination!
|
||||
webhooks: [Webhook!]!
|
||||
pagination: Pagination!
|
||||
webhooks: [Webhook!]!
|
||||
}
|
||||
|
||||
type WebhookLog {
|
||||
id: ID!
|
||||
http_status: Int64
|
||||
response: String
|
||||
request: String
|
||||
webhook_id: ID
|
||||
created_at: Int64
|
||||
updated_at: Int64
|
||||
id: ID!
|
||||
http_status: Int64
|
||||
response: String
|
||||
request: String
|
||||
webhook_id: ID
|
||||
created_at: Int64
|
||||
updated_at: Int64
|
||||
}
|
||||
|
||||
type TestEndpointResponse {
|
||||
http_status: Int64
|
||||
response: String
|
||||
http_status: Int64
|
||||
response: String
|
||||
}
|
||||
|
||||
type WebhookLogs {
|
||||
pagination: Pagination!
|
||||
webhook_logs: [WebhookLog!]!
|
||||
pagination: Pagination!
|
||||
webhook_logs: [WebhookLog!]!
|
||||
}
|
||||
|
||||
type EmailTemplate {
|
||||
id: ID!
|
||||
event_name: String!
|
||||
template: String!
|
||||
design: String!
|
||||
subject: String!
|
||||
created_at: Int64
|
||||
updated_at: Int64
|
||||
id: ID!
|
||||
event_name: String!
|
||||
template: String!
|
||||
design: String!
|
||||
subject: String!
|
||||
created_at: Int64
|
||||
updated_at: Int64
|
||||
}
|
||||
|
||||
type EmailTemplates {
|
||||
pagination: Pagination!
|
||||
email_templates: [EmailTemplate!]!
|
||||
pagination: Pagination!
|
||||
email_templates: [EmailTemplate!]!
|
||||
}
|
||||
|
||||
input UpdateEnvInput {
|
||||
ACCESS_TOKEN_EXPIRY_TIME: String
|
||||
ADMIN_SECRET: String
|
||||
CUSTOM_ACCESS_TOKEN_SCRIPT: String
|
||||
OLD_ADMIN_SECRET: String
|
||||
SMTP_HOST: String
|
||||
SMTP_PORT: String
|
||||
SMTP_USERNAME: String
|
||||
SMTP_PASSWORD: String
|
||||
SENDER_EMAIL: String
|
||||
JWT_TYPE: String
|
||||
JWT_SECRET: String
|
||||
JWT_PRIVATE_KEY: String
|
||||
JWT_PUBLIC_KEY: String
|
||||
ALLOWED_ORIGINS: [String!]
|
||||
APP_URL: String
|
||||
RESET_PASSWORD_URL: String
|
||||
DISABLE_EMAIL_VERIFICATION: Boolean
|
||||
DISABLE_BASIC_AUTHENTICATION: Boolean
|
||||
DISABLE_MAGIC_LINK_LOGIN: Boolean
|
||||
DISABLE_LOGIN_PAGE: Boolean
|
||||
DISABLE_SIGN_UP: Boolean
|
||||
DISABLE_REDIS_FOR_ENV: Boolean
|
||||
DISABLE_STRONG_PASSWORD: Boolean
|
||||
DISABLE_MULTI_FACTOR_AUTHENTICATION: Boolean
|
||||
ENFORCE_MULTI_FACTOR_AUTHENTICATION: Boolean
|
||||
ROLES: [String!]
|
||||
PROTECTED_ROLES: [String!]
|
||||
DEFAULT_ROLES: [String!]
|
||||
JWT_ROLE_CLAIM: String
|
||||
GOOGLE_CLIENT_ID: String
|
||||
GOOGLE_CLIENT_SECRET: String
|
||||
GITHUB_CLIENT_ID: String
|
||||
GITHUB_CLIENT_SECRET: String
|
||||
FACEBOOK_CLIENT_ID: String
|
||||
FACEBOOK_CLIENT_SECRET: String
|
||||
LINKEDIN_CLIENT_ID: String
|
||||
LINKEDIN_CLIENT_SECRET: String
|
||||
APPLE_CLIENT_ID: String
|
||||
APPLE_CLIENT_SECRET: String
|
||||
TWITTER_CLIENT_ID: String
|
||||
TWITTER_CLIENT_SECRET: String
|
||||
ORGANIZATION_NAME: String
|
||||
ORGANIZATION_LOGO: String
|
||||
ACCESS_TOKEN_EXPIRY_TIME: String
|
||||
ADMIN_SECRET: String
|
||||
CUSTOM_ACCESS_TOKEN_SCRIPT: String
|
||||
OLD_ADMIN_SECRET: String
|
||||
SMTP_HOST: String
|
||||
SMTP_PORT: String
|
||||
SMTP_USERNAME: String
|
||||
SMTP_PASSWORD: String
|
||||
SMTP_LOCAL_NAME: String
|
||||
SENDER_EMAIL: String
|
||||
JWT_TYPE: String
|
||||
JWT_SECRET: String
|
||||
JWT_PRIVATE_KEY: String
|
||||
JWT_PUBLIC_KEY: String
|
||||
ALLOWED_ORIGINS: [String!]
|
||||
APP_URL: String
|
||||
RESET_PASSWORD_URL: String
|
||||
APP_COOKIE_SECURE: Boolean
|
||||
ADMIN_COOKIE_SECURE: Boolean
|
||||
DISABLE_EMAIL_VERIFICATION: Boolean
|
||||
DISABLE_BASIC_AUTHENTICATION: Boolean
|
||||
DISABLE_MAGIC_LINK_LOGIN: Boolean
|
||||
DISABLE_LOGIN_PAGE: Boolean
|
||||
DISABLE_SIGN_UP: Boolean
|
||||
DISABLE_REDIS_FOR_ENV: Boolean
|
||||
DISABLE_STRONG_PASSWORD: Boolean
|
||||
DISABLE_MULTI_FACTOR_AUTHENTICATION: Boolean
|
||||
ENFORCE_MULTI_FACTOR_AUTHENTICATION: Boolean
|
||||
ROLES: [String!]
|
||||
PROTECTED_ROLES: [String!]
|
||||
DEFAULT_ROLES: [String!]
|
||||
JWT_ROLE_CLAIM: String
|
||||
GOOGLE_CLIENT_ID: String
|
||||
GOOGLE_CLIENT_SECRET: String
|
||||
GITHUB_CLIENT_ID: String
|
||||
GITHUB_CLIENT_SECRET: String
|
||||
FACEBOOK_CLIENT_ID: String
|
||||
FACEBOOK_CLIENT_SECRET: String
|
||||
LINKEDIN_CLIENT_ID: String
|
||||
LINKEDIN_CLIENT_SECRET: String
|
||||
APPLE_CLIENT_ID: String
|
||||
APPLE_CLIENT_SECRET: String
|
||||
TWITTER_CLIENT_ID: String
|
||||
TWITTER_CLIENT_SECRET: String
|
||||
ORGANIZATION_NAME: String
|
||||
ORGANIZATION_LOGO: String
|
||||
}
|
||||
|
||||
input AdminLoginInput {
|
||||
admin_secret: String!
|
||||
admin_secret: String!
|
||||
}
|
||||
|
||||
input AdminSignupInput {
|
||||
admin_secret: String!
|
||||
admin_secret: String!
|
||||
}
|
||||
|
||||
input SignUpInput {
|
||||
email: String!
|
||||
given_name: String
|
||||
family_name: String
|
||||
middle_name: String
|
||||
nickname: String
|
||||
gender: String
|
||||
birthdate: String
|
||||
phone_number: String
|
||||
picture: String
|
||||
password: String!
|
||||
confirm_password: String!
|
||||
roles: [String!]
|
||||
scope: [String!]
|
||||
redirect_uri: String
|
||||
is_multi_factor_auth_enabled: Boolean
|
||||
email: String!
|
||||
given_name: String
|
||||
family_name: String
|
||||
middle_name: String
|
||||
nickname: String
|
||||
gender: String
|
||||
birthdate: String
|
||||
phone_number: String
|
||||
picture: String
|
||||
password: String!
|
||||
confirm_password: String!
|
||||
roles: [String!]
|
||||
scope: [String!]
|
||||
redirect_uri: String
|
||||
is_multi_factor_auth_enabled: Boolean
|
||||
}
|
||||
|
||||
input LoginInput {
|
||||
email: String!
|
||||
password: String!
|
||||
roles: [String!]
|
||||
scope: [String!]
|
||||
email: String!
|
||||
password: String!
|
||||
roles: [String!]
|
||||
scope: [String!]
|
||||
}
|
||||
|
||||
input VerifyEmailInput {
|
||||
token: String!
|
||||
token: String!
|
||||
}
|
||||
|
||||
input ResendVerifyEmailInput {
|
||||
email: String!
|
||||
identifier: String!
|
||||
email: String!
|
||||
identifier: String!
|
||||
}
|
||||
|
||||
input UpdateProfileInput {
|
||||
old_password: String
|
||||
new_password: String
|
||||
confirm_new_password: String
|
||||
email: String
|
||||
given_name: String
|
||||
family_name: String
|
||||
middle_name: String
|
||||
nickname: String
|
||||
gender: String
|
||||
birthdate: String
|
||||
phone_number: String
|
||||
picture: String
|
||||
is_multi_factor_auth_enabled: Boolean
|
||||
old_password: String
|
||||
new_password: String
|
||||
confirm_new_password: String
|
||||
email: String
|
||||
given_name: String
|
||||
family_name: String
|
||||
middle_name: String
|
||||
nickname: String
|
||||
gender: String
|
||||
birthdate: String
|
||||
phone_number: String
|
||||
picture: String
|
||||
is_multi_factor_auth_enabled: Boolean
|
||||
}
|
||||
|
||||
input UpdateUserInput {
|
||||
id: ID!
|
||||
email: String
|
||||
email_verified: Boolean
|
||||
given_name: String
|
||||
family_name: String
|
||||
middle_name: String
|
||||
nickname: String
|
||||
gender: String
|
||||
birthdate: String
|
||||
phone_number: String
|
||||
picture: String
|
||||
roles: [String]
|
||||
is_multi_factor_auth_enabled: Boolean
|
||||
id: ID!
|
||||
email: String
|
||||
email_verified: Boolean
|
||||
given_name: String
|
||||
family_name: String
|
||||
middle_name: String
|
||||
nickname: String
|
||||
gender: String
|
||||
birthdate: String
|
||||
phone_number: String
|
||||
picture: String
|
||||
roles: [String]
|
||||
is_multi_factor_auth_enabled: Boolean
|
||||
}
|
||||
|
||||
input ForgotPasswordInput {
|
||||
email: String!
|
||||
state: String
|
||||
redirect_uri: String
|
||||
email: String!
|
||||
state: String
|
||||
redirect_uri: String
|
||||
}
|
||||
|
||||
input ResetPasswordInput {
|
||||
token: String!
|
||||
password: String!
|
||||
confirm_password: String!
|
||||
token: String!
|
||||
password: String!
|
||||
confirm_password: String!
|
||||
}
|
||||
|
||||
input DeleteUserInput {
|
||||
email: String!
|
||||
email: String!
|
||||
}
|
||||
|
||||
input MagicLinkLoginInput {
|
||||
email: String!
|
||||
roles: [String!]
|
||||
scope: [String!]
|
||||
state: String
|
||||
redirect_uri: String
|
||||
email: String!
|
||||
roles: [String!]
|
||||
scope: [String!]
|
||||
state: String
|
||||
redirect_uri: String
|
||||
}
|
||||
|
||||
input SessionQueryInput {
|
||||
roles: [String!]
|
||||
scope: [String!]
|
||||
roles: [String!]
|
||||
scope: [String!]
|
||||
}
|
||||
|
||||
input PaginationInput {
|
||||
limit: Int64
|
||||
page: Int64
|
||||
limit: Int64
|
||||
page: Int64
|
||||
}
|
||||
|
||||
input PaginatedInput {
|
||||
pagination: PaginationInput
|
||||
pagination: PaginationInput
|
||||
}
|
||||
|
||||
input OAuthRevokeInput {
|
||||
refresh_token: String!
|
||||
refresh_token: String!
|
||||
}
|
||||
|
||||
input InviteMemberInput {
|
||||
emails: [String!]!
|
||||
redirect_uri: String
|
||||
emails: [String!]!
|
||||
redirect_uri: String
|
||||
}
|
||||
|
||||
input UpdateAccessInput {
|
||||
user_id: String!
|
||||
user_id: String!
|
||||
}
|
||||
|
||||
input ValidateJWTTokenInput {
|
||||
token_type: String!
|
||||
token: String!
|
||||
roles: [String!]
|
||||
token_type: String!
|
||||
token: String!
|
||||
roles: [String!]
|
||||
}
|
||||
|
||||
input GenerateJWTKeysInput {
|
||||
type: String!
|
||||
type: String!
|
||||
}
|
||||
|
||||
input ListWebhookLogRequest {
|
||||
pagination: PaginationInput
|
||||
webhook_id: String
|
||||
pagination: PaginationInput
|
||||
webhook_id: String
|
||||
}
|
||||
|
||||
input AddWebhookRequest {
|
||||
event_name: String!
|
||||
endpoint: String!
|
||||
enabled: Boolean!
|
||||
headers: Map
|
||||
event_name: String!
|
||||
endpoint: String!
|
||||
enabled: Boolean!
|
||||
headers: Map
|
||||
}
|
||||
|
||||
input UpdateWebhookRequest {
|
||||
id: ID!
|
||||
event_name: String
|
||||
endpoint: String
|
||||
enabled: Boolean
|
||||
headers: Map
|
||||
id: ID!
|
||||
event_name: String
|
||||
endpoint: String
|
||||
enabled: Boolean
|
||||
headers: Map
|
||||
}
|
||||
|
||||
input WebhookRequest {
|
||||
id: ID!
|
||||
id: ID!
|
||||
}
|
||||
|
||||
input TestEndpointRequest {
|
||||
endpoint: String!
|
||||
event_name: String!
|
||||
headers: Map
|
||||
endpoint: String!
|
||||
event_name: String!
|
||||
headers: Map
|
||||
}
|
||||
|
||||
input AddEmailTemplateRequest {
|
||||
event_name: String!
|
||||
subject: String!
|
||||
template: String!
|
||||
design: String!
|
||||
event_name: String!
|
||||
subject: String!
|
||||
template: String!
|
||||
design: String!
|
||||
}
|
||||
|
||||
input UpdateEmailTemplateRequest {
|
||||
id: ID!
|
||||
event_name: String
|
||||
template: String
|
||||
subject: String
|
||||
design: String
|
||||
id: ID!
|
||||
event_name: String
|
||||
template: String
|
||||
subject: String
|
||||
design: String
|
||||
}
|
||||
|
||||
input DeleteEmailTemplateRequest {
|
||||
id: ID!
|
||||
id: ID!
|
||||
}
|
||||
|
||||
input VerifyOTPRequest {
|
||||
email: String!
|
||||
otp: String!
|
||||
email: String!
|
||||
otp: String!
|
||||
}
|
||||
|
||||
input ResendOTPRequest {
|
||||
email: String!
|
||||
email: String!
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
signup(params: SignUpInput!): AuthResponse!
|
||||
login(params: LoginInput!): AuthResponse!
|
||||
magic_link_login(params: MagicLinkLoginInput!): Response!
|
||||
logout: Response!
|
||||
update_profile(params: UpdateProfileInput!): Response!
|
||||
verify_email(params: VerifyEmailInput!): AuthResponse!
|
||||
resend_verify_email(params: ResendVerifyEmailInput!): Response!
|
||||
forgot_password(params: ForgotPasswordInput!): Response!
|
||||
reset_password(params: ResetPasswordInput!): Response!
|
||||
revoke(params: OAuthRevokeInput!): Response!
|
||||
verify_otp(params: VerifyOTPRequest!): AuthResponse!
|
||||
resend_otp(params: ResendOTPRequest!): Response!
|
||||
# admin only apis
|
||||
_delete_user(params: DeleteUserInput!): Response!
|
||||
_update_user(params: UpdateUserInput!): User!
|
||||
_admin_signup(params: AdminSignupInput!): Response!
|
||||
_admin_login(params: AdminLoginInput!): Response!
|
||||
_admin_logout: Response!
|
||||
_update_env(params: UpdateEnvInput!): Response!
|
||||
_invite_members(params: InviteMemberInput!): Response!
|
||||
_revoke_access(param: UpdateAccessInput!): Response!
|
||||
_enable_access(param: UpdateAccessInput!): Response!
|
||||
_generate_jwt_keys(params: GenerateJWTKeysInput!): GenerateJWTKeysResponse!
|
||||
_add_webhook(params: AddWebhookRequest!): Response!
|
||||
_update_webhook(params: UpdateWebhookRequest!): Response!
|
||||
_delete_webhook(params: WebhookRequest!): Response!
|
||||
_test_endpoint(params: TestEndpointRequest!): TestEndpointResponse!
|
||||
_add_email_template(params: AddEmailTemplateRequest!): Response!
|
||||
_update_email_template(params: UpdateEmailTemplateRequest!): Response!
|
||||
_delete_email_template(params: DeleteEmailTemplateRequest!): Response!
|
||||
signup(params: SignUpInput!): AuthResponse!
|
||||
login(params: LoginInput!): AuthResponse!
|
||||
magic_link_login(params: MagicLinkLoginInput!): Response!
|
||||
logout: Response!
|
||||
update_profile(params: UpdateProfileInput!): Response!
|
||||
verify_email(params: VerifyEmailInput!): AuthResponse!
|
||||
resend_verify_email(params: ResendVerifyEmailInput!): Response!
|
||||
forgot_password(params: ForgotPasswordInput!): Response!
|
||||
reset_password(params: ResetPasswordInput!): Response!
|
||||
revoke(params: OAuthRevokeInput!): Response!
|
||||
verify_otp(params: VerifyOTPRequest!): AuthResponse!
|
||||
resend_otp(params: ResendOTPRequest!): Response!
|
||||
# admin only apis
|
||||
_delete_user(params: DeleteUserInput!): Response!
|
||||
_update_user(params: UpdateUserInput!): User!
|
||||
_admin_signup(params: AdminSignupInput!): Response!
|
||||
_admin_login(params: AdminLoginInput!): Response!
|
||||
_admin_logout: Response!
|
||||
_update_env(params: UpdateEnvInput!): Response!
|
||||
_invite_members(params: InviteMemberInput!): Response!
|
||||
_revoke_access(param: UpdateAccessInput!): Response!
|
||||
_enable_access(param: UpdateAccessInput!): Response!
|
||||
_generate_jwt_keys(params: GenerateJWTKeysInput!): GenerateJWTKeysResponse!
|
||||
_add_webhook(params: AddWebhookRequest!): Response!
|
||||
_update_webhook(params: UpdateWebhookRequest!): Response!
|
||||
_delete_webhook(params: WebhookRequest!): Response!
|
||||
_test_endpoint(params: TestEndpointRequest!): TestEndpointResponse!
|
||||
_add_email_template(params: AddEmailTemplateRequest!): Response!
|
||||
_update_email_template(params: UpdateEmailTemplateRequest!): Response!
|
||||
_delete_email_template(params: DeleteEmailTemplateRequest!): Response!
|
||||
}
|
||||
|
||||
type Query {
|
||||
meta: Meta!
|
||||
session(params: SessionQueryInput): AuthResponse!
|
||||
profile: User!
|
||||
validate_jwt_token(params: ValidateJWTTokenInput!): ValidateJWTTokenResponse!
|
||||
# admin only apis
|
||||
_users(params: PaginatedInput): Users!
|
||||
_verification_requests(params: PaginatedInput): VerificationRequests!
|
||||
_admin_session: Response!
|
||||
_env: Env!
|
||||
_webhook(params: WebhookRequest!): Webhook!
|
||||
_webhooks(params: PaginatedInput): Webhooks!
|
||||
_webhook_logs(params: ListWebhookLogRequest): WebhookLogs!
|
||||
_email_templates(params: PaginatedInput): EmailTemplates!
|
||||
meta: Meta!
|
||||
session(params: SessionQueryInput): AuthResponse!
|
||||
profile: User!
|
||||
validate_jwt_token(params: ValidateJWTTokenInput!): ValidateJWTTokenResponse!
|
||||
# admin only apis
|
||||
_users(params: PaginatedInput): Users!
|
||||
_verification_requests(params: PaginatedInput): VerificationRequests!
|
||||
_admin_session: Response!
|
||||
_env: Env!
|
||||
_webhook(params: WebhookRequest!): Webhook!
|
||||
_webhooks(params: PaginatedInput): Webhooks!
|
||||
_webhook_logs(params: ListWebhookLogRequest): WebhookLogs!
|
||||
_email_templates(params: PaginatedInput): EmailTemplates!
|
||||
}
|
||||
|
@@ -11,166 +11,207 @@ import (
|
||||
"github.com/authorizerdev/authorizer/server/resolvers"
|
||||
)
|
||||
|
||||
// Signup is the resolver for the signup field.
|
||||
func (r *mutationResolver) Signup(ctx context.Context, params model.SignUpInput) (*model.AuthResponse, error) {
|
||||
return resolvers.SignupResolver(ctx, params)
|
||||
}
|
||||
|
||||
// Login is the resolver for the login field.
|
||||
func (r *mutationResolver) Login(ctx context.Context, params model.LoginInput) (*model.AuthResponse, error) {
|
||||
return resolvers.LoginResolver(ctx, params)
|
||||
}
|
||||
|
||||
// MagicLinkLogin is the resolver for the magic_link_login field.
|
||||
func (r *mutationResolver) MagicLinkLogin(ctx context.Context, params model.MagicLinkLoginInput) (*model.Response, error) {
|
||||
return resolvers.MagicLinkLoginResolver(ctx, params)
|
||||
}
|
||||
|
||||
// Logout is the resolver for the logout field.
|
||||
func (r *mutationResolver) Logout(ctx context.Context) (*model.Response, error) {
|
||||
return resolvers.LogoutResolver(ctx)
|
||||
}
|
||||
|
||||
// UpdateProfile is the resolver for the update_profile field.
|
||||
func (r *mutationResolver) UpdateProfile(ctx context.Context, params model.UpdateProfileInput) (*model.Response, error) {
|
||||
return resolvers.UpdateProfileResolver(ctx, params)
|
||||
}
|
||||
|
||||
// VerifyEmail is the resolver for the verify_email field.
|
||||
func (r *mutationResolver) VerifyEmail(ctx context.Context, params model.VerifyEmailInput) (*model.AuthResponse, error) {
|
||||
return resolvers.VerifyEmailResolver(ctx, params)
|
||||
}
|
||||
|
||||
// ResendVerifyEmail is the resolver for the resend_verify_email field.
|
||||
func (r *mutationResolver) ResendVerifyEmail(ctx context.Context, params model.ResendVerifyEmailInput) (*model.Response, error) {
|
||||
return resolvers.ResendVerifyEmailResolver(ctx, params)
|
||||
}
|
||||
|
||||
// ForgotPassword is the resolver for the forgot_password field.
|
||||
func (r *mutationResolver) ForgotPassword(ctx context.Context, params model.ForgotPasswordInput) (*model.Response, error) {
|
||||
return resolvers.ForgotPasswordResolver(ctx, params)
|
||||
}
|
||||
|
||||
// ResetPassword is the resolver for the reset_password field.
|
||||
func (r *mutationResolver) ResetPassword(ctx context.Context, params model.ResetPasswordInput) (*model.Response, error) {
|
||||
return resolvers.ResetPasswordResolver(ctx, params)
|
||||
}
|
||||
|
||||
// Revoke is the resolver for the revoke field.
|
||||
func (r *mutationResolver) Revoke(ctx context.Context, params model.OAuthRevokeInput) (*model.Response, error) {
|
||||
return resolvers.RevokeResolver(ctx, params)
|
||||
}
|
||||
|
||||
// VerifyOtp is the resolver for the verify_otp field.
|
||||
func (r *mutationResolver) VerifyOtp(ctx context.Context, params model.VerifyOTPRequest) (*model.AuthResponse, error) {
|
||||
return resolvers.VerifyOtpResolver(ctx, params)
|
||||
}
|
||||
|
||||
// ResendOtp is the resolver for the resend_otp field.
|
||||
func (r *mutationResolver) ResendOtp(ctx context.Context, params model.ResendOTPRequest) (*model.Response, error) {
|
||||
return resolvers.ResendOTPResolver(ctx, params)
|
||||
}
|
||||
|
||||
// DeleteUser is the resolver for the _delete_user field.
|
||||
func (r *mutationResolver) DeleteUser(ctx context.Context, params model.DeleteUserInput) (*model.Response, error) {
|
||||
return resolvers.DeleteUserResolver(ctx, params)
|
||||
}
|
||||
|
||||
// UpdateUser is the resolver for the _update_user field.
|
||||
func (r *mutationResolver) UpdateUser(ctx context.Context, params model.UpdateUserInput) (*model.User, error) {
|
||||
return resolvers.UpdateUserResolver(ctx, params)
|
||||
}
|
||||
|
||||
// AdminSignup is the resolver for the _admin_signup field.
|
||||
func (r *mutationResolver) AdminSignup(ctx context.Context, params model.AdminSignupInput) (*model.Response, error) {
|
||||
return resolvers.AdminSignupResolver(ctx, params)
|
||||
}
|
||||
|
||||
// AdminLogin is the resolver for the _admin_login field.
|
||||
func (r *mutationResolver) AdminLogin(ctx context.Context, params model.AdminLoginInput) (*model.Response, error) {
|
||||
return resolvers.AdminLoginResolver(ctx, params)
|
||||
}
|
||||
|
||||
// AdminLogout is the resolver for the _admin_logout field.
|
||||
func (r *mutationResolver) AdminLogout(ctx context.Context) (*model.Response, error) {
|
||||
return resolvers.AdminLogoutResolver(ctx)
|
||||
}
|
||||
|
||||
// UpdateEnv is the resolver for the _update_env field.
|
||||
func (r *mutationResolver) UpdateEnv(ctx context.Context, params model.UpdateEnvInput) (*model.Response, error) {
|
||||
return resolvers.UpdateEnvResolver(ctx, params)
|
||||
}
|
||||
|
||||
// InviteMembers is the resolver for the _invite_members field.
|
||||
func (r *mutationResolver) InviteMembers(ctx context.Context, params model.InviteMemberInput) (*model.Response, error) {
|
||||
return resolvers.InviteMembersResolver(ctx, params)
|
||||
}
|
||||
|
||||
// RevokeAccess is the resolver for the _revoke_access field.
|
||||
func (r *mutationResolver) RevokeAccess(ctx context.Context, param model.UpdateAccessInput) (*model.Response, error) {
|
||||
return resolvers.RevokeAccessResolver(ctx, param)
|
||||
}
|
||||
|
||||
// EnableAccess is the resolver for the _enable_access field.
|
||||
func (r *mutationResolver) EnableAccess(ctx context.Context, param model.UpdateAccessInput) (*model.Response, error) {
|
||||
return resolvers.EnableAccessResolver(ctx, param)
|
||||
}
|
||||
|
||||
// GenerateJwtKeys is the resolver for the _generate_jwt_keys field.
|
||||
func (r *mutationResolver) GenerateJwtKeys(ctx context.Context, params model.GenerateJWTKeysInput) (*model.GenerateJWTKeysResponse, error) {
|
||||
return resolvers.GenerateJWTKeysResolver(ctx, params)
|
||||
}
|
||||
|
||||
// AddWebhook is the resolver for the _add_webhook field.
|
||||
func (r *mutationResolver) AddWebhook(ctx context.Context, params model.AddWebhookRequest) (*model.Response, error) {
|
||||
return resolvers.AddWebhookResolver(ctx, params)
|
||||
}
|
||||
|
||||
// UpdateWebhook is the resolver for the _update_webhook field.
|
||||
func (r *mutationResolver) UpdateWebhook(ctx context.Context, params model.UpdateWebhookRequest) (*model.Response, error) {
|
||||
return resolvers.UpdateWebhookResolver(ctx, params)
|
||||
}
|
||||
|
||||
// DeleteWebhook is the resolver for the _delete_webhook field.
|
||||
func (r *mutationResolver) DeleteWebhook(ctx context.Context, params model.WebhookRequest) (*model.Response, error) {
|
||||
return resolvers.DeleteWebhookResolver(ctx, params)
|
||||
}
|
||||
|
||||
// TestEndpoint is the resolver for the _test_endpoint field.
|
||||
func (r *mutationResolver) TestEndpoint(ctx context.Context, params model.TestEndpointRequest) (*model.TestEndpointResponse, error) {
|
||||
return resolvers.TestEndpointResolver(ctx, params)
|
||||
}
|
||||
|
||||
// AddEmailTemplate is the resolver for the _add_email_template field.
|
||||
func (r *mutationResolver) AddEmailTemplate(ctx context.Context, params model.AddEmailTemplateRequest) (*model.Response, error) {
|
||||
return resolvers.AddEmailTemplateResolver(ctx, params)
|
||||
}
|
||||
|
||||
// UpdateEmailTemplate is the resolver for the _update_email_template field.
|
||||
func (r *mutationResolver) UpdateEmailTemplate(ctx context.Context, params model.UpdateEmailTemplateRequest) (*model.Response, error) {
|
||||
return resolvers.UpdateEmailTemplateResolver(ctx, params)
|
||||
}
|
||||
|
||||
// DeleteEmailTemplate is the resolver for the _delete_email_template field.
|
||||
func (r *mutationResolver) DeleteEmailTemplate(ctx context.Context, params model.DeleteEmailTemplateRequest) (*model.Response, error) {
|
||||
return resolvers.DeleteEmailTemplateResolver(ctx, params)
|
||||
}
|
||||
|
||||
// Meta is the resolver for the meta field.
|
||||
func (r *queryResolver) Meta(ctx context.Context) (*model.Meta, error) {
|
||||
return resolvers.MetaResolver(ctx)
|
||||
}
|
||||
|
||||
// Session is the resolver for the session field.
|
||||
func (r *queryResolver) Session(ctx context.Context, params *model.SessionQueryInput) (*model.AuthResponse, error) {
|
||||
return resolvers.SessionResolver(ctx, params)
|
||||
}
|
||||
|
||||
// Profile is the resolver for the profile field.
|
||||
func (r *queryResolver) Profile(ctx context.Context) (*model.User, error) {
|
||||
return resolvers.ProfileResolver(ctx)
|
||||
}
|
||||
|
||||
// ValidateJwtToken is the resolver for the validate_jwt_token field.
|
||||
func (r *queryResolver) ValidateJwtToken(ctx context.Context, params model.ValidateJWTTokenInput) (*model.ValidateJWTTokenResponse, error) {
|
||||
return resolvers.ValidateJwtTokenResolver(ctx, params)
|
||||
}
|
||||
|
||||
// Users is the resolver for the _users field.
|
||||
func (r *queryResolver) Users(ctx context.Context, params *model.PaginatedInput) (*model.Users, error) {
|
||||
return resolvers.UsersResolver(ctx, params)
|
||||
}
|
||||
|
||||
// VerificationRequests is the resolver for the _verification_requests field.
|
||||
func (r *queryResolver) VerificationRequests(ctx context.Context, params *model.PaginatedInput) (*model.VerificationRequests, error) {
|
||||
return resolvers.VerificationRequestsResolver(ctx, params)
|
||||
}
|
||||
|
||||
// AdminSession is the resolver for the _admin_session field.
|
||||
func (r *queryResolver) AdminSession(ctx context.Context) (*model.Response, error) {
|
||||
return resolvers.AdminSessionResolver(ctx)
|
||||
}
|
||||
|
||||
// Env is the resolver for the _env field.
|
||||
func (r *queryResolver) Env(ctx context.Context) (*model.Env, error) {
|
||||
return resolvers.EnvResolver(ctx)
|
||||
}
|
||||
|
||||
// Webhook is the resolver for the _webhook field.
|
||||
func (r *queryResolver) Webhook(ctx context.Context, params model.WebhookRequest) (*model.Webhook, error) {
|
||||
return resolvers.WebhookResolver(ctx, params)
|
||||
}
|
||||
|
||||
// Webhooks is the resolver for the _webhooks field.
|
||||
func (r *queryResolver) Webhooks(ctx context.Context, params *model.PaginatedInput) (*model.Webhooks, error) {
|
||||
return resolvers.WebhooksResolver(ctx, params)
|
||||
}
|
||||
|
||||
// WebhookLogs is the resolver for the _webhook_logs field.
|
||||
func (r *queryResolver) WebhookLogs(ctx context.Context, params *model.ListWebhookLogRequest) (*model.WebhookLogs, error) {
|
||||
return resolvers.WebhookLogsResolver(ctx, params)
|
||||
}
|
||||
|
||||
// EmailTemplates is the resolver for the _email_templates field.
|
||||
func (r *queryResolver) EmailTemplates(ctx context.Context, params *model.PaginatedInput) (*model.EmailTemplates, error) {
|
||||
return resolvers.EmailTemplatesResolver(ctx, params)
|
||||
}
|
||||
|
@@ -30,7 +30,7 @@ func AppHandler() gin.HandlerFunc {
|
||||
return
|
||||
}
|
||||
|
||||
redirect_uri := strings.TrimSpace(c.Query("redirect_uri"))
|
||||
redirectURI := strings.TrimSpace(c.Query("redirect_uri"))
|
||||
state := strings.TrimSpace(c.Query("state"))
|
||||
scopeString := strings.TrimSpace(c.Query("scope"))
|
||||
|
||||
@@ -41,11 +41,11 @@ func AppHandler() gin.HandlerFunc {
|
||||
scope = strings.Split(scopeString, " ")
|
||||
}
|
||||
|
||||
if redirect_uri == "" {
|
||||
redirect_uri = hostname + "/app"
|
||||
if redirectURI == "" {
|
||||
redirectURI = hostname + "/app"
|
||||
} else {
|
||||
// validate redirect url with allowed origins
|
||||
if !validators.IsValidOrigin(redirect_uri) {
|
||||
if !validators.IsValidOrigin(redirectURI) {
|
||||
log.Debug("Invalid redirect_uri")
|
||||
c.JSON(400, gin.H{"error": "invalid redirect url"})
|
||||
return
|
||||
@@ -75,7 +75,7 @@ func AppHandler() gin.HandlerFunc {
|
||||
c.HTML(http.StatusOK, "app.tmpl", gin.H{
|
||||
"data": map[string]interface{}{
|
||||
"authorizerURL": hostname,
|
||||
"redirectURL": redirect_uri,
|
||||
"redirectURL": redirectURI,
|
||||
"scope": scope,
|
||||
"state": state,
|
||||
"organizationName": orgName,
|
||||
|
@@ -2,7 +2,7 @@ package handlers
|
||||
|
||||
import (
|
||||
"github.com/99designs/gqlgen/graphql/handler"
|
||||
"github.com/authorizerdev/authorizer/server/graph"
|
||||
graph "github.com/authorizerdev/authorizer/server/graph"
|
||||
"github.com/authorizerdev/authorizer/server/graph/generated"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
@@ -17,14 +17,14 @@ func OpenIDConfigurationHandler() gin.HandlerFunc {
|
||||
c.JSON(200, gin.H{
|
||||
"issuer": issuer,
|
||||
"authorization_endpoint": issuer + "/authorize",
|
||||
"token_endpoint": issuer + "/token",
|
||||
"token_endpoint": issuer + "/oauth/token",
|
||||
"userinfo_endpoint": issuer + "/userinfo",
|
||||
"jwks_uri": issuer + "/.well-known/jwks.json",
|
||||
"response_types_supported": []string{"code", "token", "id_token", "code token", "code id_token", "token id_token", "code token id_token"},
|
||||
"response_types_supported": []string{"code", "token", "id_token"},
|
||||
"scopes_supported": []string{"openid", "email", "profile", "email_verified", "given_name", "family_name", "nick_name", "picture"},
|
||||
"response_modes_supported": []string{"query", "fragment", "form_post"},
|
||||
"response_modes_supported": []string{"query", "fragment", "form_post", "web_message"},
|
||||
"id_token_signing_alg_values_supported": []string{jwtType},
|
||||
"claims_supported": []string{"aud", "exp", "iss", "iat", "sub", "given_name", "family_name", "middle_name", "nickname", "preferred_username", "picture", "email", "email_verified", "roles", "gender", "birthdate", "phone_number", "phone_number_verified"},
|
||||
"claims_supported": []string{"aud", "exp", "iss", "iat", "sub", "given_name", "family_name", "middle_name", "nickname", "preferred_username", "picture", "email", "email_verified", "roles", "role", "gender", "birthdate", "phone_number", "phone_number_verified", "nonce", "updated_at", "created_at", "revoked_timestamp", "login_method", "signup_methods", "token_type"},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@@ -154,6 +154,7 @@ func TokenHandler() gin.HandlerFunc {
|
||||
"error": "invalid_refresh_token",
|
||||
"error_description": "The refresh token is invalid",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
claims, err := token.ValidateRefreshToken(gc, refreshToken)
|
||||
@@ -163,9 +164,10 @@ func TokenHandler() gin.HandlerFunc {
|
||||
"error": "unauthorized",
|
||||
"error_description": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
userID = claims["sub"].(string)
|
||||
loginMethod := claims["login_method"]
|
||||
claimLoginMethod := claims["login_method"]
|
||||
rolesInterface := claims["roles"].([]interface{})
|
||||
scopeInterface := claims["scope"].([]interface{})
|
||||
for _, v := range rolesInterface {
|
||||
@@ -176,9 +178,11 @@ func TokenHandler() gin.HandlerFunc {
|
||||
}
|
||||
|
||||
sessionKey = userID
|
||||
if loginMethod != nil && loginMethod != "" {
|
||||
sessionKey = loginMethod.(string) + ":" + sessionKey
|
||||
if claimLoginMethod != nil && claimLoginMethod != "" {
|
||||
sessionKey = claimLoginMethod.(string) + ":" + sessionKey
|
||||
loginMethod = claimLoginMethod.(string)
|
||||
}
|
||||
|
||||
// remove older refresh token and rotate it for security
|
||||
go memorystore.Provider.DeleteUserSession(sessionKey, claims["nonce"].(string))
|
||||
}
|
||||
@@ -211,6 +215,7 @@ func TokenHandler() gin.HandlerFunc {
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash)
|
||||
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token)
|
||||
cookie.SetSession(gc, authToken.FingerPrintHash)
|
||||
|
@@ -15,12 +15,15 @@ import (
|
||||
"github.com/authorizerdev/authorizer/server/routes"
|
||||
)
|
||||
|
||||
// VERSION is used to define the version of authorizer from build tags
|
||||
var VERSION string
|
||||
|
||||
// LogUTCFormatter hels in setting UTC time format for the logs
|
||||
type LogUTCFormatter struct {
|
||||
log.Formatter
|
||||
}
|
||||
|
||||
// Format helps fomratting time to UTC
|
||||
func (u LogUTCFormatter) Format(e *log.Entry) ([]byte, error) {
|
||||
e.Time = e.Time.UTC()
|
||||
return u.Formatter.Format(e)
|
||||
@@ -58,7 +61,10 @@ func main() {
|
||||
default:
|
||||
logLevel = logrus.InfoLevel
|
||||
}
|
||||
// set log level globally
|
||||
logrus.SetLevel(logLevel)
|
||||
|
||||
// set log level for go-gin middleware
|
||||
log.SetLevel(logLevel)
|
||||
|
||||
// show file path in log for debug or other log levels.
|
||||
|
@@ -57,7 +57,7 @@ func InitMemStore() error {
|
||||
}
|
||||
|
||||
redisURL := requiredEnvs.RedisURL
|
||||
if redisURL != "" && !requiredEnvs.disableRedisForEnv {
|
||||
if redisURL != "" && !requiredEnvs.DisableRedisForEnv {
|
||||
log.Info("Initializing Redis memory store")
|
||||
Provider, err = redis.NewRedisProvider(redisURL)
|
||||
if err != nil {
|
||||
|
@@ -27,7 +27,11 @@ type RequiredEnv struct {
|
||||
DatabaseCertKey string `json:"DATABASE_CERT_KEY"`
|
||||
DatabaseCACert string `json:"DATABASE_CA_CERT"`
|
||||
RedisURL string `json:"REDIS_URL"`
|
||||
disableRedisForEnv bool `json:"DISABLE_REDIS_FOR_ENV"`
|
||||
DisableRedisForEnv bool `json:"DISABLE_REDIS_FOR_ENV"`
|
||||
// AWS Related Envs
|
||||
AwsRegion string `json:"AWS_REGION"`
|
||||
AwsAccessKeyID string `json:"AWS_ACCESS_KEY_ID"`
|
||||
AwsSecretAccessKey string `json:"AWS_SECRET_ACCESS_KEY"`
|
||||
}
|
||||
|
||||
// RequiredEnvObj is a simple in-memory store for sessions.
|
||||
@@ -53,7 +57,8 @@ func (r *RequiredEnvStore) SetRequiredEnv(requiredEnv RequiredEnv) {
|
||||
|
||||
var RequiredEnvStoreObj *RequiredEnvStore
|
||||
|
||||
// InitRequiredEnv to initialize EnvData and through error if required env are not present
|
||||
// InitRequiredEnv to initialize EnvData and throw error if required env are not present
|
||||
// This includes env that only configurable via env vars and not the ui
|
||||
func InitRequiredEnv() error {
|
||||
envPath := os.Getenv(constants.EnvKeyEnvPath)
|
||||
|
||||
@@ -85,6 +90,9 @@ func InitRequiredEnv() error {
|
||||
dbCACert := os.Getenv(constants.EnvKeyDatabaseCACert)
|
||||
redisURL := os.Getenv(constants.EnvKeyRedisURL)
|
||||
disableRedisForEnv := os.Getenv(constants.EnvKeyDisableRedisForEnv) == "true"
|
||||
awsRegion := os.Getenv(constants.EnvAwsRegion)
|
||||
awsAccessKeyID := os.Getenv(constants.EnvAwsAccessKeyID)
|
||||
awsSecretAccessKey := os.Getenv(constants.EnvAwsSecretAccessKey)
|
||||
|
||||
if strings.TrimSpace(redisURL) == "" {
|
||||
if cli.ARG_REDIS_URL != nil && *cli.ARG_REDIS_URL != "" {
|
||||
@@ -113,7 +121,8 @@ func InitRequiredEnv() error {
|
||||
dbURL = strings.TrimSpace(*cli.ARG_DB_URL)
|
||||
}
|
||||
|
||||
if dbURL == "" && dbPort == "" && dbHost == "" && dbUsername == "" && dbPassword == "" {
|
||||
// In dynamoDB these field are not always mandatory
|
||||
if dbType != constants.DbTypeDynamoDB && dbURL == "" && dbPort == "" && dbHost == "" && dbUsername == "" && dbPassword == "" {
|
||||
log.Debug("DATABASE_URL is not set")
|
||||
return errors.New("invalid database url. DATABASE_URL is required")
|
||||
}
|
||||
@@ -138,7 +147,10 @@ func InitRequiredEnv() error {
|
||||
DatabaseCertKey: dbCertKey,
|
||||
DatabaseCACert: dbCACert,
|
||||
RedisURL: redisURL,
|
||||
disableRedisForEnv: disableRedisForEnv,
|
||||
DisableRedisForEnv: disableRedisForEnv,
|
||||
AwsRegion: awsRegion,
|
||||
AwsAccessKeyID: awsAccessKeyID,
|
||||
AwsSecretAccessKey: awsSecretAccessKey,
|
||||
}
|
||||
|
||||
RequiredEnvStoreObj = &RequiredEnvStore{
|
||||
|
@@ -11,8 +11,8 @@ import (
|
||||
)
|
||||
|
||||
// GetHost returns hostname from request context
|
||||
// if X-Authorizer-URL header is set it is given highest priority
|
||||
// if EnvKeyAuthorizerURL is set it is given second highest priority.
|
||||
// if EnvKeyAuthorizerURL is set it is given highest priority.
|
||||
// if X-Authorizer-URL header is set it is given second highest priority
|
||||
// if above 2 are not set the requesting host name is used
|
||||
func GetHost(c *gin.Context) string {
|
||||
authorizerURL, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAuthorizerURL)
|
||||
|
@@ -89,6 +89,9 @@ func EnvResolver(ctx context.Context) (*model.Env, error) {
|
||||
if val, ok := store[constants.EnvKeySenderEmail]; ok {
|
||||
res.SenderEmail = refs.NewStringRef(val.(string))
|
||||
}
|
||||
if val, ok := store[constants.EnvKeySmtpLocalName]; ok {
|
||||
res.SMTPLocalName = refs.NewStringRef(val.(string))
|
||||
}
|
||||
if val, ok := store[constants.EnvKeyJwtType]; ok {
|
||||
res.JwtType = refs.NewStringRef(val.(string))
|
||||
}
|
||||
@@ -179,6 +182,8 @@ func EnvResolver(ctx context.Context) (*model.Env, error) {
|
||||
res.DisableStrongPassword = store[constants.EnvKeyDisableStrongPassword].(bool)
|
||||
res.EnforceMultiFactorAuthentication = store[constants.EnvKeyEnforceMultiFactorAuthentication].(bool)
|
||||
res.DisableMultiFactorAuthentication = store[constants.EnvKeyDisableMultiFactorAuthentication].(bool)
|
||||
res.AdminCookieSecure = store[constants.EnvKeyAdminCookieSecure].(bool)
|
||||
res.AppCookieSecure = store[constants.EnvKeyAppCookieSecure].(bool)
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
@@ -62,12 +62,21 @@ func ForgotPasswordResolver(ctx context.Context, params model.ForgotPasswordInpu
|
||||
log.Debug("Failed to generate nonce: ", err)
|
||||
return res, err
|
||||
}
|
||||
redirectURL := parsers.GetAppURL(gc)
|
||||
|
||||
redirectURI := ""
|
||||
// give higher preference to params redirect uri
|
||||
if strings.TrimSpace(refs.StringValue(params.RedirectURI)) != "" {
|
||||
redirectURL = refs.StringValue(params.RedirectURI)
|
||||
redirectURI = refs.StringValue(params.RedirectURI)
|
||||
} else {
|
||||
redirectURI, err = memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyResetPasswordURL)
|
||||
if err != nil {
|
||||
log.Debug("ResetPasswordURL not found using default app url: ", err)
|
||||
redirectURI = hostname + "/app/reset-password"
|
||||
memorystore.Provider.UpdateEnvVariable(constants.EnvKeyResetPasswordURL, redirectURI)
|
||||
}
|
||||
}
|
||||
|
||||
verificationToken, err := token.CreateVerificationToken(params.Email, constants.VerificationTypeForgotPassword, hostname, nonceHash, redirectURL)
|
||||
verificationToken, err := token.CreateVerificationToken(params.Email, constants.VerificationTypeForgotPassword, hostname, nonceHash, redirectURI)
|
||||
if err != nil {
|
||||
log.Debug("Failed to create verification token", err)
|
||||
return res, err
|
||||
@@ -78,7 +87,7 @@ func ForgotPasswordResolver(ctx context.Context, params model.ForgotPasswordInpu
|
||||
ExpiresAt: time.Now().Add(time.Minute * 30).Unix(),
|
||||
Email: params.Email,
|
||||
Nonce: nonceHash,
|
||||
RedirectURI: redirectURL,
|
||||
RedirectURI: redirectURI,
|
||||
})
|
||||
if err != nil {
|
||||
log.Debug("Failed to add verification request", err)
|
||||
@@ -89,7 +98,7 @@ func ForgotPasswordResolver(ctx context.Context, params model.ForgotPasswordInpu
|
||||
go email.SendEmail([]string{params.Email}, constants.VerificationTypeForgotPassword, map[string]interface{}{
|
||||
"user": user.ToMap(),
|
||||
"organization": utils.GetOrganization(),
|
||||
"verification_url": utils.GetForgotPasswordURL(verificationToken, hostname),
|
||||
"verification_url": utils.GetForgotPasswordURL(verificationToken, redirectURI),
|
||||
})
|
||||
|
||||
res = &model.Response{
|
||||
|
@@ -93,5 +93,6 @@ func ValidateJwtTokenResolver(ctx context.Context, params model.ValidateJWTToken
|
||||
}
|
||||
return &model.ValidateJWTTokenResponse{
|
||||
IsValid: true,
|
||||
Claims: claims,
|
||||
}, nil
|
||||
}
|
||||
|
@@ -20,6 +20,7 @@ func TestResolvers(t *testing.T) {
|
||||
constants.DbTypeArangodb: "http://localhost:8529",
|
||||
constants.DbTypeMongodb: "mongodb://localhost:27017",
|
||||
constants.DbTypeScyllaDB: "127.0.0.1:9042",
|
||||
constants.DbTypeDynamoDB: "http://0.0.0.0:8000",
|
||||
}
|
||||
|
||||
testDBs := strings.Split(os.Getenv("TEST_DBS"), ",")
|
||||
@@ -51,25 +52,33 @@ func TestResolvers(t *testing.T) {
|
||||
os.Setenv(constants.EnvKeyDatabaseURL, dbURL)
|
||||
os.Setenv(constants.EnvKeyDatabaseType, dbType)
|
||||
os.Setenv(constants.EnvKeyDatabaseName, testDb)
|
||||
|
||||
if dbType == constants.DbTypeDynamoDB {
|
||||
memorystore.Provider.UpdateEnvVariable(constants.EnvAwsRegion, "ap-south-1")
|
||||
os.Setenv(constants.EnvAwsRegion, "ap-south-1")
|
||||
}
|
||||
|
||||
memorystore.InitRequiredEnv()
|
||||
|
||||
err := db.InitDB()
|
||||
if err != nil {
|
||||
t.Errorf("Error initializing database: %s", err.Error())
|
||||
t.Logf("Error initializing database: %s", err.Error())
|
||||
}
|
||||
|
||||
// clean the persisted config for test to use fresh config
|
||||
envData, err := db.Provider.GetEnv(ctx)
|
||||
if err == nil {
|
||||
if err == nil && envData.ID != "" {
|
||||
envData.EnvData = ""
|
||||
_, err = db.Provider.UpdateEnv(ctx, envData)
|
||||
if err != nil {
|
||||
t.Errorf("Error updating env: %s", err.Error())
|
||||
t.Logf("Error updating env: %s", err.Error())
|
||||
}
|
||||
} else if err != nil {
|
||||
t.Logf("Error getting env: %s", err.Error())
|
||||
}
|
||||
err = env.PersistEnv()
|
||||
if err != nil {
|
||||
t.Errorf("Error persisting env: %s", err.Error())
|
||||
t.Logf("Error persisting env: %s", err.Error())
|
||||
}
|
||||
|
||||
memorystore.Provider.UpdateEnvVariable(constants.EnvKeyEnv, "test")
|
||||
|
@@ -84,7 +84,7 @@ func testSetup() TestSetup {
|
||||
testData := TestData{
|
||||
Email: fmt.Sprintf("%d_authorizer_tester@yopmail.com", time.Now().Unix()),
|
||||
Password: "Test@123",
|
||||
WebhookEndpoint: "https://62cbc6738042b16aa7c22df2.mockapi.io/api/v1/webhook",
|
||||
WebhookEndpoint: "https://62f93101e05644803533cf36.mockapi.io/authorizer/webhook",
|
||||
TestWebhookEventTypes: []string{constants.UserAccessEnabledWebhookEvent, constants.UserAccessRevokedWebhookEvent, constants.UserCreatedWebhookEvent, constants.UserDeletedWebhookEvent, constants.UserLoginWebhookEvent, constants.UserSignUpWebhookEvent},
|
||||
TestEmailTemplateEventTypes: []string{constants.VerificationTypeBasicAuthSignup, constants.VerificationTypeForgotPassword, constants.VerificationTypeMagicLinkLogin, constants.VerificationTypeUpdateEmail},
|
||||
}
|
||||
|
@@ -93,5 +93,6 @@ func validateJwtTokenTest(t *testing.T, s TestSetup) {
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, res.IsValid)
|
||||
assert.Equal(t, user.Email, res.Claims["email"])
|
||||
})
|
||||
}
|
||||
|
@@ -114,16 +114,17 @@ func CreateRefreshToken(user models.User, roles, scopes []string, hostname, nonc
|
||||
return "", 0, err
|
||||
}
|
||||
customClaims := jwt.MapClaims{
|
||||
"iss": hostname,
|
||||
"aud": clientID,
|
||||
"sub": user.ID,
|
||||
"exp": expiresAt,
|
||||
"iat": time.Now().Unix(),
|
||||
"token_type": constants.TokenTypeRefreshToken,
|
||||
"roles": roles,
|
||||
"scope": scopes,
|
||||
"nonce": nonce,
|
||||
"login_method": loginMethod,
|
||||
"iss": hostname,
|
||||
"aud": clientID,
|
||||
"sub": user.ID,
|
||||
"exp": expiresAt,
|
||||
"iat": time.Now().Unix(),
|
||||
"token_type": constants.TokenTypeRefreshToken,
|
||||
"roles": roles,
|
||||
"scope": scopes,
|
||||
"nonce": nonce,
|
||||
"login_method": loginMethod,
|
||||
"allowed_roles": strings.Split(user.Roles, ","),
|
||||
}
|
||||
|
||||
token, err := SignJWTToken(customClaims)
|
||||
@@ -153,16 +154,17 @@ func CreateAccessToken(user models.User, roles, scopes []string, hostName, nonce
|
||||
return "", 0, err
|
||||
}
|
||||
customClaims := jwt.MapClaims{
|
||||
"iss": hostName,
|
||||
"aud": clientID,
|
||||
"nonce": nonce,
|
||||
"sub": user.ID,
|
||||
"exp": expiresAt,
|
||||
"iat": time.Now().Unix(),
|
||||
"token_type": constants.TokenTypeAccessToken,
|
||||
"scope": scopes,
|
||||
"roles": roles,
|
||||
"login_method": loginMethod,
|
||||
"iss": hostName,
|
||||
"aud": clientID,
|
||||
"nonce": nonce,
|
||||
"sub": user.ID,
|
||||
"exp": expiresAt,
|
||||
"iat": time.Now().Unix(),
|
||||
"token_type": constants.TokenTypeAccessToken,
|
||||
"scope": scopes,
|
||||
"roles": roles,
|
||||
"login_method": loginMethod,
|
||||
"allowed_roles": strings.Split(user.Roles, ","),
|
||||
}
|
||||
|
||||
token, err := SignJWTToken(customClaims)
|
||||
@@ -256,7 +258,6 @@ func ValidateRefreshToken(gc *gin.Context, refreshToken string) (map[string]inte
|
||||
if loginMethod != nil && loginMethod != "" {
|
||||
sessionKey = loginMethod.(string) + ":" + userID
|
||||
}
|
||||
|
||||
token, err := memorystore.Provider.GetUserSession(sessionKey, constants.TokenTypeRefreshToken+"_"+nonce)
|
||||
if nonce == "" || err != nil {
|
||||
return res, fmt.Errorf(`unauthorized`)
|
||||
|
8
server/tools.go
Normal file
8
server/tools.go
Normal file
@@ -0,0 +1,8 @@
|
||||
//go:build tools
|
||||
// +build tools
|
||||
|
||||
package tools
|
||||
|
||||
import (
|
||||
_ "github.com/99designs/gqlgen"
|
||||
)
|
@@ -81,17 +81,8 @@ func GetOrganization() map[string]interface{} {
|
||||
}
|
||||
|
||||
// GetForgotPasswordURL to get url for given token and hostname
|
||||
func GetForgotPasswordURL(token, hostname string) string {
|
||||
resetPasswordUrl, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyResetPasswordURL)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
if resetPasswordUrl == "" {
|
||||
if err := memorystore.Provider.UpdateEnvVariable(constants.EnvKeyResetPasswordURL, hostname+"/app/reset-password"); err != nil {
|
||||
return ""
|
||||
}
|
||||
}
|
||||
verificationURL := resetPasswordUrl + "?token=" + token
|
||||
func GetForgotPasswordURL(token, redirectURI string) string {
|
||||
verificationURL := redirectURI + "?token=" + token
|
||||
return verificationURL
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user