diff --git a/.dockerignore b/.dockerignore
index 5773072bc..0b168cd02 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -7,6 +7,12 @@ ROADMAP.md
build
.env
data.db
-app/node_modules
-app/build
+web/app/node_modules
+web/app/build
+web/app/.vite
+web/dashboard/node_modules
+web/dashboard/build
+web/dashboard/.vite
certs/
+*.log
+.DS_Store
diff --git a/.gitignore b/.gitignore
index 8009af8c0..9b21a6753 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,10 +1,10 @@
server/server
server/.env
data
-app/node_modules
-app/build
-dashboard/node_modules
-dashboard/build
+web/app/node_modules
+web/app/build
+web/dashboard/node_modules
+web/dashboard/build
build
.env
data.db
@@ -20,3 +20,4 @@ certs/
*-wal
.idea
*.iml
+node_modules/*
\ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
index 2c3aacba3..cc6fbe903 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,35 +1,54 @@
-FROM golang:1.21.3-alpine3.18 as go-builder
+FROM golang:1.25.5-alpine3.23 as go-builder
WORKDIR /authorizer
-COPY server server
-COPY Makefile .
+
+# Copy go mod files for dependency resolution
+COPY go.mod go.sum ./
+
+# Download dependencies
+RUN go mod download
+
+# Copy source code
+COPY main.go ./
+COPY cmd/ ./cmd/
+COPY internal/ ./internal/
+COPY gqlgen.yml ./
ARG VERSION="latest"
ENV VERSION="$VERSION"
RUN echo "$VERSION"
-RUN apk add build-base &&\
- make clean && make && \
+# Build the server binary
+RUN apk add build-base && \
+ go build -ldflags "-w -X main.VERSION=$(VERSION)" -o build/server . && \
chmod 777 build/server
-FROM node:20-alpine3.18 as node-builder
+FROM node:25-alpine3.22 as node-builder
WORKDIR /authorizer
-COPY app app
-COPY dashboard dashboard
-COPY Makefile .
-RUN apk add build-base &&\
- make build-app && \
- make build-dashboard
+# Copy package files first for better layer caching
+COPY web/app/package*.json web/app/
+COPY web/dashboard/package*.json web/dashboard/
+# Install dependencies
+RUN cd web/app && npm ci && \
+ cd ../dashboard && npm ci
+# Copy source files
+COPY web/app web/app
+COPY web/dashboard web/dashboard
+# Build applications
+RUN cd web/app && npm run build && \
+ cd ../dashboard && npm run build
-FROM alpine:3.18
+FROM alpine:3.23
RUN adduser -D -h /authorizer -u 1000 -k /dev/null authorizer
WORKDIR /authorizer
-RUN mkdir app dashboard
-COPY --from=node-builder --chown=nobody:nobody /authorizer/app/build app/build
-COPY --from=node-builder --chown=nobody:nobody /authorizer/app/favicon_io app/favicon_io
-COPY --from=node-builder --chown=nobody:nobody /authorizer/dashboard/build dashboard/build
-COPY --from=node-builder --chown=nobody:nobody /authorizer/dashboard/favicon_io dashboard/favicon_io
+RUN mkdir -p web/app web/dashboard
+COPY --from=node-builder --chown=nobody:nobody /authorizer/web/app/build web/app/build
+COPY --from=node-builder --chown=nobody:nobody /authorizer/web/app/favicon_io web/app/favicon_io
+COPY --from=node-builder --chown=nobody:nobody /authorizer/web/dashboard/build web/dashboard/build
+COPY --from=node-builder --chown=nobody:nobody /authorizer/web/dashboard/favicon_io web/dashboard/favicon_io
COPY --from=go-builder --chown=nobody:nobody /authorizer/build build
-COPY templates templates
-EXPOSE 8080
+COPY web/templates web/templates
+EXPOSE 8080 8081
USER authorizer
-CMD [ "./build/server" ]
+# Use ENTRYPOINT to allow passing CLI arguments
+ENTRYPOINT [ "./build/server" ]
+CMD []
diff --git a/Makefile b/Makefile
index e617e6157..a1946802b 100644
--- a/Makefile
+++ b/Makefile
@@ -10,13 +10,41 @@ build:
-output="../build/{{.OS}}/{{.Arch}}/server" \
./...
build-app:
- cd app && npm i && npm run build
+ cd web/app && npm ci && npm run build
build-dashboard:
- cd dashboard && npm i && npm run build
+ cd web/dashboard && npm ci && npm run build
clean:
rm -rf build
+dev:
+ go run main.go --database-type=sqlite --database-url=test.db --jwt-type=HS256 --jwt-secret=test --admin-secret=admin --client-id=123456 --client-secret=secret
+# 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:
- 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
+ docker rm -vf authorizer_postgres
+ docker rm -vf authorizer_scylla_db
+ docker rm -vf authorizer_mongodb_db
+ docker rm -vf authorizer_arangodb
+ docker rm -vf authorizer_dynamodb
+ docker rm -vf authorizer_couchbase
+ docker rm -vf authorizer_redis
+ docker run -d --name authorizer_redis -p 6380:6379 redis
+ docker run --name authorizer_postgres -p 5432:5432 -e POSTGRES_PASSWORD=postgres -e POSTGRES_DB=postgres -d postgres
+ 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.10.3
+ docker run -d --name authorizer_dynamodb -p 8000:8000 amazon/dynamodb-local:latest
+ docker run -d --name authorizer_couchbase -p 8091-8097:8091-8097 -p 11210:11210 -p 11207:11207 -p 18091-18095:18091-18095 -p 18096:18096 -p 18097:18097 couchbase:latest
+ sh scripts/couchbase-test.sh
+
+ go test -v ./...
+
+ docker rm -vf authorizer_postgres
+ docker rm -vf authorizer_scylla_db
+ docker rm -vf authorizer_mongodb_db
+ docker rm -vf authorizer_arangodb
+ docker rm -vf authorizer_dynamodb
+ docker rm -vf authorizer_couchbase
+ docker rm -vf authorizer_redis
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
@@ -53,7 +81,7 @@ test-all-db:
docker rm -vf dynamodb-local-test
docker rm -vf couchbase-local-test
generate-graphql:
- cd server && go run github.com/99designs/gqlgen generate && go mod tidy
+ go run github.com/99designs/gqlgen --verbose generate && go mod tidy
generate-db-template:
cp -rf server/db/providers/provider_template server/db/providers/${dbname}
find server/db/providers/${dbname} -type f -exec sed -i -e 's/provider_template/${dbname}/g' {} \;
diff --git a/ROADMAP.md b/ROADMAP.md
deleted file mode 100644
index 9ce680eae..000000000
--- a/ROADMAP.md
+++ /dev/null
@@ -1,55 +0,0 @@
-# Roadmap for authorizer
-
-This document contains detailed information about the project scope and future roadmap
-
-## V 0.1.0 [To be released by 20-August-2021]
-
-- [x] Create server
- - [x] Use golang as server side language
- - [x] Use [gorm](https://github.com/go-gorm/gorm) as ORM
- - [x] Configure https://github.com/99designs/gqlgen for generating graphql schemas
- - [x] Configure https://github.com/gin-gonic/gin for creating http server
- - [x] Define base schema for user
- - [x] Define the auth schemes and variables required for that
- - [x] Basic Auth (Username & Password based)
- - [x] Google Login
- - [x] Github Login
- - [ ] Twitter Login
- - [ ] Facebook Login
- - [ ] Login with magic link (Send magic link mail)
- - [x] Add [mailing server](https://github.com/emersion/go-smtp) to send the magic link
- - [x] Allow configuring the master password to access the console (If not set UI console can be accessed by anyone)
- - [x] Allow configuring mailing server
- - [x] Allow configuring HSA Keys for oauth
- - [ ] Allow configuring RSA keys for oauth
- - [x] Allow configuring the DB client
- - [x] Allow configuring the Secret
- - [x] Allow configuring callback urls
- - [x] Allow configuring redis, should be optional if not used use the memory to store session
-- [x] Create Graphql mutations and query for following
- - [x] Login mutation
- - [x] Logout muttion
- - [x] Token query :- Authorize [Currently checks for valid token & if token is present in session]
- - [x] Should authorize using cookies
- - [x] Should authorize using Authorization header
- - [ ] Role based access [Checks for particular role in JWT]
- - [x] Signup
- - [x] Forgot password
- - [x] Update profile
-- [ ] Create a UI console to configure the above parts [For now using graphql playground]
- - [ ] Create react app
- - [ ] Allow user to configure above mentioned envs
- - [ ] Allow user to add user
- - [ ] Allow user to view users
- - [ ] Allow user to define the JWT token field
-- [x] A component library for react
- - [x] Create AuthorizerProvider -> gives token, user, loading, setters
- - [x] Create Authorizer component -> Complete Login/Signup & Forgot password solution
- - [x] Create AuthorizerResetPassword component -> Component that can be used to verify forgot password token and reset the password
-- [ ] Create a sdks
- - [ ] NodeJS sdk which acts as a middleware and can be used to authenticate & authorize users
- - [ ] Golang sdk which acts as a middleware and can be used to authenticate & authorize users
-- [x] Create docker image
-- [x] Create docker-compose file to quickly start this
-- [x] Create heroku button
-- [ ] Create a website
diff --git a/TODO.md b/TODO.md
deleted file mode 100644
index c7a6cfa08..000000000
--- a/TODO.md
+++ /dev/null
@@ -1,49 +0,0 @@
-# Task List
-
-## Implement better way of handling jwt tokens
-
-Check: https://hasura.io/blog/best-practices-of-using-jwt-with-graphql/#server-side-rendering-ssr
-
-- [x] Set finger print in response cookie (https://github.com/hasura/jwt-guide/blob/60a7a86146d604fc48a799fffdee712be1c52cd0/lib/setFingerprintCookieAndSignJwt.ts#L8)
-- [x] Save refresh token in session store
-- [x] refresh token should be made more secure with the help of secure token rotation. Every time new token is requested new refresh token should be generated
-- [x] Return jwt in response
-- [x] To get session send finger print and refresh token [if they are valid -> a new access token is generated and sent to user]
-- [x] Refresh token should be long living token (refresh token + finger print hash should be verified)
-
-## Open ID compatible claims and schema
-
-- [x] Rename `schema.graphqls` and re generate schema
-- [x] Rename to snake case [files + schema]
-- [x] Refactor db models
-- [x] Check extra data in oauth profile and save accordingly
-- [x] Update all the resolver to make them compatible with schema changes
-- [x] Update JWT claims
-- [x] Write integration tests for all resolvers
-
-## Feature Multiple sessions
-
-- Multiple sessions for users to login use hMset from redis for this
- user_id access_token1 long_live_token1
- user_id access_token2 long_live_token2
-
-# Feature roles
-
-For the first version we will only support setting roles master list via env
-
-- [x] Support following ENV
- - [x] `ROLES` -> comma separated list of role names
- - [x] `DEFAULT_ROLE` -> default role to assign to users
-- [x] Add roles input for signup
-- [x] Add roles to update profile mutation
-- [x] Add roles input for login
-- [x] Return roles to user
-- [x] Return roles in users list for super admin
-- [x] Add roles to the JWT token generation
-- [x] Validate token should also validate the role, if roles to validate again is present in request
-
-# Misc
-
-- [x] Fix email template
-- [x] Add support for organization name in .env
-- [x] Add support for organization logo in .env
diff --git a/app/esbuild.config.js b/app/esbuild.config.js
deleted file mode 100644
index b018f0780..000000000
--- a/app/esbuild.config.js
+++ /dev/null
@@ -1,11 +0,0 @@
-const __is_prod__ = process.env.NODE_ENV === 'production';
-require('esbuild').build({
- entryPoints: ['src/index.tsx'],
- chunkNames: '[name]-[hash]',
- bundle: true,
- minify: __is_prod__,
- outdir: 'build',
- splitting: true,
- format: 'esm',
- watch: !__is_prod__,
-});
diff --git a/app/package-lock.json b/app/package-lock.json
deleted file mode 100644
index b0236f651..000000000
--- a/app/package-lock.json
+++ /dev/null
@@ -1,879 +0,0 @@
-{
- "name": "app",
- "version": "1.0.0",
- "lockfileVersion": 3,
- "requires": true,
- "packages": {
- "": {
- "name": "app",
- "version": "1.0.0",
- "license": "ISC",
- "dependencies": {
- "@authorizerdev/authorizer-react": "^1.3.2",
- "@types/react": "^17.0.15",
- "@types/react-dom": "^17.0.9",
- "esbuild": "^0.12.17",
- "react": "^17.0.2",
- "react-dom": "^17.0.2",
- "react-is": "^17.0.2",
- "react-router-dom": "^5.2.0",
- "styled-components": "^5.3.0",
- "typescript": "^4.3.5"
- },
- "devDependencies": {
- "@types/react-router-dom": "^5.1.8",
- "@types/styled-components": "^5.1.11",
- "prettier": "2.7.1"
- }
- },
- "node_modules/@authorizerdev/authorizer-js": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-2.0.3.tgz",
- "integrity": "sha512-uencwr3Ea8mwfxVKDFf2ITRCRSmzvua+O2voRuiWQORtRQTgZQjkN3M+IEkEj+WP9M1iFIl+NDgzECsp8ptC/A==",
- "dependencies": {
- "cross-fetch": "^3.1.5"
- },
- "engines": {
- "node": ">=16"
- },
- "funding": {
- "url": "https://github.com/sponsors/authorizerdev"
- }
- },
- "node_modules/@authorizerdev/authorizer-react": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-1.3.2.tgz",
- "integrity": "sha512-3kMAygHBCa8Fc9Oo0lz1k88r+Pd6kx1PSn3NMYLwxQXy2jRt4xWn7iuGn+SDGFs3DzofaN71I61gRwQ+6dO1rw==",
- "dependencies": {
- "@authorizerdev/authorizer-js": "^2.0.3",
- "validator": "^13.11.0"
- },
- "engines": {
- "node": ">=10"
- },
- "peerDependencies": {
- "react": ">=16"
- }
- },
- "node_modules/@babel/code-frame": {
- "version": "7.22.13",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz",
- "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==",
- "dependencies": {
- "@babel/highlight": "^7.22.13",
- "chalk": "^2.4.2"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/generator": {
- "version": "7.23.0",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz",
- "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==",
- "dependencies": {
- "@babel/types": "^7.23.0",
- "@jridgewell/gen-mapping": "^0.3.2",
- "@jridgewell/trace-mapping": "^0.3.17",
- "jsesc": "^2.5.1"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-annotate-as-pure": {
- "version": "7.16.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz",
- "integrity": "sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw==",
- "dependencies": {
- "@babel/types": "^7.16.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-environment-visitor": {
- "version": "7.22.20",
- "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz",
- "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-function-name": {
- "version": "7.23.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz",
- "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==",
- "dependencies": {
- "@babel/template": "^7.22.15",
- "@babel/types": "^7.23.0"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-hoist-variables": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz",
- "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==",
- "dependencies": {
- "@babel/types": "^7.22.5"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-module-imports": {
- "version": "7.16.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz",
- "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==",
- "dependencies": {
- "@babel/types": "^7.16.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-split-export-declaration": {
- "version": "7.22.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz",
- "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==",
- "dependencies": {
- "@babel/types": "^7.22.5"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-string-parser": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz",
- "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-validator-identifier": {
- "version": "7.22.20",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
- "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/highlight": {
- "version": "7.22.20",
- "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz",
- "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==",
- "dependencies": {
- "@babel/helper-validator-identifier": "^7.22.20",
- "chalk": "^2.4.2",
- "js-tokens": "^4.0.0"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/parser": {
- "version": "7.23.0",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz",
- "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==",
- "bin": {
- "parser": "bin/babel-parser.js"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@babel/runtime": {
- "version": "7.14.8",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.8.tgz",
- "integrity": "sha512-twj3L8Og5SaCRCErB4x4ajbvBIVV77CGeFglHpeg5WC5FF8TZzBWXtTJ4MqaD9QszLYTtr+IsaAL2rEUevb+eg==",
- "dependencies": {
- "regenerator-runtime": "^0.13.4"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/template": {
- "version": "7.22.15",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz",
- "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==",
- "dependencies": {
- "@babel/code-frame": "^7.22.13",
- "@babel/parser": "^7.22.15",
- "@babel/types": "^7.22.15"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/traverse": {
- "version": "7.23.2",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz",
- "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==",
- "dependencies": {
- "@babel/code-frame": "^7.22.13",
- "@babel/generator": "^7.23.0",
- "@babel/helper-environment-visitor": "^7.22.20",
- "@babel/helper-function-name": "^7.23.0",
- "@babel/helper-hoist-variables": "^7.22.5",
- "@babel/helper-split-export-declaration": "^7.22.6",
- "@babel/parser": "^7.23.0",
- "@babel/types": "^7.23.0",
- "debug": "^4.1.0",
- "globals": "^11.1.0"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/types": {
- "version": "7.23.0",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz",
- "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==",
- "dependencies": {
- "@babel/helper-string-parser": "^7.22.5",
- "@babel/helper-validator-identifier": "^7.22.20",
- "to-fast-properties": "^2.0.0"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@emotion/is-prop-valid": {
- "version": "0.8.8",
- "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz",
- "integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==",
- "dependencies": {
- "@emotion/memoize": "0.7.4"
- }
- },
- "node_modules/@emotion/memoize": {
- "version": "0.7.4",
- "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz",
- "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw=="
- },
- "node_modules/@emotion/stylis": {
- "version": "0.8.5",
- "resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz",
- "integrity": "sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ=="
- },
- "node_modules/@emotion/unitless": {
- "version": "0.7.5",
- "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz",
- "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg=="
- },
- "node_modules/@jridgewell/gen-mapping": {
- "version": "0.3.3",
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
- "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
- "dependencies": {
- "@jridgewell/set-array": "^1.0.1",
- "@jridgewell/sourcemap-codec": "^1.4.10",
- "@jridgewell/trace-mapping": "^0.3.9"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@jridgewell/resolve-uri": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz",
- "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==",
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@jridgewell/set-array": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
- "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@jridgewell/sourcemap-codec": {
- "version": "1.4.15",
- "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
- "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg=="
- },
- "node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.20",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz",
- "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==",
- "dependencies": {
- "@jridgewell/resolve-uri": "^3.1.0",
- "@jridgewell/sourcemap-codec": "^1.4.14"
- }
- },
- "node_modules/@types/history": {
- "version": "4.7.9",
- "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.9.tgz",
- "integrity": "sha512-MUc6zSmU3tEVnkQ78q0peeEjKWPUADMlC/t++2bI8WnAG2tvYRPIgHG8lWkXwqc8MsUF6Z2MOf+Mh5sazOmhiQ==",
- "dev": true
- },
- "node_modules/@types/hoist-non-react-statics": {
- "version": "3.3.1",
- "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz",
- "integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==",
- "dev": true,
- "dependencies": {
- "@types/react": "*",
- "hoist-non-react-statics": "^3.3.0"
- }
- },
- "node_modules/@types/prop-types": {
- "version": "15.7.4",
- "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.4.tgz",
- "integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ=="
- },
- "node_modules/@types/react": {
- "version": "17.0.15",
- "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.15.tgz",
- "integrity": "sha512-uTKHDK9STXFHLaKv6IMnwp52fm0hwU+N89w/p9grdUqcFA6WuqDyPhaWopbNyE1k/VhgzmHl8pu1L4wITtmlLw==",
- "dependencies": {
- "@types/prop-types": "*",
- "@types/scheduler": "*",
- "csstype": "^3.0.2"
- }
- },
- "node_modules/@types/react-dom": {
- "version": "17.0.9",
- "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.9.tgz",
- "integrity": "sha512-wIvGxLfgpVDSAMH5utdL9Ngm5Owu0VsGmldro3ORLXV8CShrL8awVj06NuEXFQ5xyaYfdca7Sgbk/50Ri1GdPg==",
- "dependencies": {
- "@types/react": "*"
- }
- },
- "node_modules/@types/react-router": {
- "version": "5.1.16",
- "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.16.tgz",
- "integrity": "sha512-8d7nR/fNSqlTFGHti0R3F9WwIertOaaA1UEB8/jr5l5mDMOs4CidEgvvYMw4ivqrBK+vtVLxyTj2P+Pr/dtgzg==",
- "dev": true,
- "dependencies": {
- "@types/history": "*",
- "@types/react": "*"
- }
- },
- "node_modules/@types/react-router-dom": {
- "version": "5.1.8",
- "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.1.8.tgz",
- "integrity": "sha512-03xHyncBzG0PmDmf8pf3rehtjY0NpUj7TIN46FrT5n1ZWHPZvXz32gUyNboJ+xsL8cpg8bQVLcllptcQHvocrw==",
- "dev": true,
- "dependencies": {
- "@types/history": "*",
- "@types/react": "*",
- "@types/react-router": "*"
- }
- },
- "node_modules/@types/scheduler": {
- "version": "0.16.2",
- "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz",
- "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew=="
- },
- "node_modules/@types/styled-components": {
- "version": "5.1.25",
- "resolved": "https://registry.npmjs.org/@types/styled-components/-/styled-components-5.1.25.tgz",
- "integrity": "sha512-fgwl+0Pa8pdkwXRoVPP9JbqF0Ivo9llnmsm+7TCI330kbPIFd9qv1Lrhr37shf4tnxCOSu+/IgqM7uJXLWZZNQ==",
- "dev": true,
- "dependencies": {
- "@types/hoist-non-react-statics": "*",
- "@types/react": "*",
- "csstype": "^3.0.2"
- }
- },
- "node_modules/ansi-styles": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
- "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
- "dependencies": {
- "color-convert": "^1.9.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/babel-plugin-styled-components": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-2.0.2.tgz",
- "integrity": "sha512-7eG5NE8rChnNTDxa6LQfynwgHTVOYYaHJbUYSlOhk8QBXIQiMBKq4gyfHBBKPrxUcVBXVJL61ihduCpCQbuNbw==",
- "dependencies": {
- "@babel/helper-annotate-as-pure": "^7.16.0",
- "@babel/helper-module-imports": "^7.16.0",
- "babel-plugin-syntax-jsx": "^6.18.0",
- "lodash": "^4.17.11"
- },
- "peerDependencies": {
- "styled-components": ">= 2"
- }
- },
- "node_modules/babel-plugin-syntax-jsx": {
- "version": "6.18.0",
- "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz",
- "integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY="
- },
- "node_modules/camelize": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz",
- "integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs="
- },
- "node_modules/chalk": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
- "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
- "dependencies": {
- "ansi-styles": "^3.2.1",
- "escape-string-regexp": "^1.0.5",
- "supports-color": "^5.3.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/color-convert": {
- "version": "1.9.3",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
- "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
- "dependencies": {
- "color-name": "1.1.3"
- }
- },
- "node_modules/color-name": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
- "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="
- },
- "node_modules/cross-fetch": {
- "version": "3.1.8",
- "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz",
- "integrity": "sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==",
- "dependencies": {
- "node-fetch": "^2.6.12"
- }
- },
- "node_modules/css-color-keywords": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz",
- "integrity": "sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU=",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/css-to-react-native": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.0.0.tgz",
- "integrity": "sha512-Ro1yETZA813eoyUp2GDBhG2j+YggidUmzO1/v9eYBKR2EHVEniE2MI/NqpTQ954BMpTPZFsGNPm46qFB9dpaPQ==",
- "dependencies": {
- "camelize": "^1.0.0",
- "css-color-keywords": "^1.0.0",
- "postcss-value-parser": "^4.0.2"
- }
- },
- "node_modules/csstype": {
- "version": "3.0.8",
- "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.8.tgz",
- "integrity": "sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw=="
- },
- "node_modules/debug": {
- "version": "4.3.3",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz",
- "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==",
- "dependencies": {
- "ms": "2.1.2"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "node_modules/esbuild": {
- "version": "0.12.17",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.12.17.tgz",
- "integrity": "sha512-GshKJyVYUnlSXIZj/NheC2O0Kblh42CS7P1wJyTbbIHevTG4jYMS9NNw8EOd8dDWD0dzydYHS01MpZoUcQXB4g==",
- "hasInstallScript": true,
- "bin": {
- "esbuild": "bin/esbuild"
- }
- },
- "node_modules/escape-string-regexp": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
- "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
- "engines": {
- "node": ">=0.8.0"
- }
- },
- "node_modules/globals": {
- "version": "11.12.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
- "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/has-flag": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
- "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/history": {
- "version": "4.10.1",
- "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz",
- "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==",
- "dependencies": {
- "@babel/runtime": "^7.1.2",
- "loose-envify": "^1.2.0",
- "resolve-pathname": "^3.0.0",
- "tiny-invariant": "^1.0.2",
- "tiny-warning": "^1.0.0",
- "value-equal": "^1.0.1"
- }
- },
- "node_modules/hoist-non-react-statics": {
- "version": "3.3.2",
- "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
- "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
- "dependencies": {
- "react-is": "^16.7.0"
- }
- },
- "node_modules/hoist-non-react-statics/node_modules/react-is": {
- "version": "16.13.1",
- "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
- "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
- },
- "node_modules/isarray": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
- "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
- },
- "node_modules/js-tokens": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
- "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
- },
- "node_modules/jsesc": {
- "version": "2.5.2",
- "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
- "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
- "bin": {
- "jsesc": "bin/jsesc"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/lodash": {
- "version": "4.17.21",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
- "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
- },
- "node_modules/loose-envify": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
- "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
- "dependencies": {
- "js-tokens": "^3.0.0 || ^4.0.0"
- },
- "bin": {
- "loose-envify": "cli.js"
- }
- },
- "node_modules/mini-create-react-context": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/mini-create-react-context/-/mini-create-react-context-0.4.1.tgz",
- "integrity": "sha512-YWCYEmd5CQeHGSAKrYvXgmzzkrvssZcuuQDDeqkT+PziKGMgE+0MCCtcKbROzocGBG1meBLl2FotlRwf4gAzbQ==",
- "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.",
- "dependencies": {
- "@babel/runtime": "^7.12.1",
- "tiny-warning": "^1.0.3"
- },
- "peerDependencies": {
- "prop-types": "^15.0.0",
- "react": "^0.14.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
- }
- },
- "node_modules/ms": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
- "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
- },
- "node_modules/node-fetch": {
- "version": "2.7.0",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
- "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
- "dependencies": {
- "whatwg-url": "^5.0.0"
- },
- "engines": {
- "node": "4.x || >=6.0.0"
- },
- "peerDependencies": {
- "encoding": "^0.1.0"
- },
- "peerDependenciesMeta": {
- "encoding": {
- "optional": true
- }
- }
- },
- "node_modules/object-assign": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
- "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/path-to-regexp": {
- "version": "1.8.0",
- "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz",
- "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==",
- "dependencies": {
- "isarray": "0.0.1"
- }
- },
- "node_modules/postcss-value-parser": {
- "version": "4.2.0",
- "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",
- "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==",
- "dependencies": {
- "loose-envify": "^1.4.0",
- "object-assign": "^4.1.1",
- "react-is": "^16.8.1"
- }
- },
- "node_modules/prop-types/node_modules/react-is": {
- "version": "16.13.1",
- "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
- "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
- },
- "node_modules/react": {
- "version": "17.0.2",
- "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz",
- "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==",
- "dependencies": {
- "loose-envify": "^1.1.0",
- "object-assign": "^4.1.1"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/react-dom": {
- "version": "17.0.2",
- "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz",
- "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==",
- "dependencies": {
- "loose-envify": "^1.1.0",
- "object-assign": "^4.1.1",
- "scheduler": "^0.20.2"
- },
- "peerDependencies": {
- "react": "17.0.2"
- }
- },
- "node_modules/react-is": {
- "version": "17.0.2",
- "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
- "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="
- },
- "node_modules/react-router": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.2.0.tgz",
- "integrity": "sha512-smz1DUuFHRKdcJC0jobGo8cVbhO3x50tCL4icacOlcwDOEQPq4TMqwx3sY1TP+DvtTgz4nm3thuo7A+BK2U0Dw==",
- "dependencies": {
- "@babel/runtime": "^7.1.2",
- "history": "^4.9.0",
- "hoist-non-react-statics": "^3.1.0",
- "loose-envify": "^1.3.1",
- "mini-create-react-context": "^0.4.0",
- "path-to-regexp": "^1.7.0",
- "prop-types": "^15.6.2",
- "react-is": "^16.6.0",
- "tiny-invariant": "^1.0.2",
- "tiny-warning": "^1.0.0"
- },
- "peerDependencies": {
- "react": ">=15"
- }
- },
- "node_modules/react-router-dom": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.2.0.tgz",
- "integrity": "sha512-gxAmfylo2QUjcwxI63RhQ5G85Qqt4voZpUXSEqCwykV0baaOTQDR1f0PmY8AELqIyVc0NEZUj0Gov5lNGcXgsA==",
- "dependencies": {
- "@babel/runtime": "^7.1.2",
- "history": "^4.9.0",
- "loose-envify": "^1.3.1",
- "prop-types": "^15.6.2",
- "react-router": "5.2.0",
- "tiny-invariant": "^1.0.2",
- "tiny-warning": "^1.0.0"
- },
- "peerDependencies": {
- "react": ">=15"
- }
- },
- "node_modules/react-router/node_modules/react-is": {
- "version": "16.13.1",
- "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
- "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
- },
- "node_modules/regenerator-runtime": {
- "version": "0.13.9",
- "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
- "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA=="
- },
- "node_modules/resolve-pathname": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz",
- "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng=="
- },
- "node_modules/scheduler": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz",
- "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==",
- "dependencies": {
- "loose-envify": "^1.1.0",
- "object-assign": "^4.1.1"
- }
- },
- "node_modules/shallowequal": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz",
- "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ=="
- },
- "node_modules/styled-components": {
- "version": "5.3.3",
- "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.3.3.tgz",
- "integrity": "sha512-++4iHwBM7ZN+x6DtPPWkCI4vdtwumQ+inA/DdAsqYd4SVgUKJie5vXyzotA00ttcFdQkCng7zc6grwlfIfw+lw==",
- "dependencies": {
- "@babel/helper-module-imports": "^7.0.0",
- "@babel/traverse": "^7.4.5",
- "@emotion/is-prop-valid": "^0.8.8",
- "@emotion/stylis": "^0.8.4",
- "@emotion/unitless": "^0.7.4",
- "babel-plugin-styled-components": ">= 1.12.0",
- "css-to-react-native": "^3.0.0",
- "hoist-non-react-statics": "^3.0.0",
- "shallowequal": "^1.1.0",
- "supports-color": "^5.5.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/styled-components"
- },
- "peerDependencies": {
- "react": ">= 16.8.0",
- "react-dom": ">= 16.8.0",
- "react-is": ">= 16.8.0"
- }
- },
- "node_modules/supports-color": {
- "version": "5.5.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
- "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
- "dependencies": {
- "has-flag": "^3.0.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/tiny-invariant": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.1.0.tgz",
- "integrity": "sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw=="
- },
- "node_modules/tiny-warning": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz",
- "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA=="
- },
- "node_modules/to-fast-properties": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
- "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/tr46": {
- "version": "0.0.3",
- "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
- "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
- },
- "node_modules/typescript": {
- "version": "4.3.5",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz",
- "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==",
- "bin": {
- "tsc": "bin/tsc",
- "tsserver": "bin/tsserver"
- },
- "engines": {
- "node": ">=4.2.0"
- }
- },
- "node_modules/validator": {
- "version": "13.11.0",
- "resolved": "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz",
- "integrity": "sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==",
- "engines": {
- "node": ">= 0.10"
- }
- },
- "node_modules/value-equal": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz",
- "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw=="
- },
- "node_modules/webidl-conversions": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
- "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
- },
- "node_modules/whatwg-url": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
- "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
- "dependencies": {
- "tr46": "~0.0.3",
- "webidl-conversions": "^3.0.0"
- }
- }
- }
-}
diff --git a/app/package.json b/app/package.json
deleted file mode 100644
index a3167c3e5..000000000
--- a/app/package.json
+++ /dev/null
@@ -1,31 +0,0 @@
-{
- "name": "app",
- "version": "1.0.0",
- "description": "",
- "main": "index.js",
- "scripts": {
- "build": "rm -rf build && NODE_ENV=production node ./esbuild.config.js",
- "start": "NODE_ENV=development node ./esbuild.config.js",
- "format": "prettier --write 'src/**/*.(ts|tsx|js|jsx)'"
- },
- "keywords": [],
- "author": "Lakhan Samani",
- "license": "ISC",
- "dependencies": {
- "@authorizerdev/authorizer-react": "^1.3.2",
- "@types/react": "^17.0.15",
- "@types/react-dom": "^17.0.9",
- "esbuild": "^0.12.17",
- "react": "^17.0.2",
- "react-dom": "^17.0.2",
- "react-is": "^17.0.2",
- "react-router-dom": "^5.2.0",
- "styled-components": "^5.3.0",
- "typescript": "^4.3.5"
- },
- "devDependencies": {
- "@types/react-router-dom": "^5.1.8",
- "@types/styled-components": "^5.1.11",
- "prettier": "2.7.1"
- }
-}
diff --git a/app/pnpm-lock.yaml b/app/pnpm-lock.yaml
deleted file mode 100644
index 87aacf458..000000000
--- a/app/pnpm-lock.yaml
+++ /dev/null
@@ -1,626 +0,0 @@
-lockfileVersion: 5.4
-
-specifiers:
- '@authorizerdev/authorizer-react': ^1.1.9
- '@types/react': ^17.0.15
- '@types/react-dom': ^17.0.9
- '@types/react-router-dom': ^5.1.8
- '@types/styled-components': ^5.1.11
- esbuild: ^0.12.17
- prettier: 2.7.1
- react: ^17.0.2
- react-dom: ^17.0.2
- react-is: ^17.0.2
- react-router-dom: ^5.2.0
- styled-components: ^5.3.0
- typescript: ^4.3.5
-
-dependencies:
- '@authorizerdev/authorizer-react': 1.1.9_react@17.0.2
- '@types/react': 17.0.53
- '@types/react-dom': 17.0.19
- esbuild: 0.12.29
- react: 17.0.2
- react-dom: 17.0.2_react@17.0.2
- react-is: 17.0.2
- react-router-dom: 5.3.4_react@17.0.2
- styled-components: 5.3.9_fane7jikarojcev26y27hpbhu4
- typescript: 4.9.5
-
-devDependencies:
- '@types/react-router-dom': 5.3.3
- '@types/styled-components': 5.1.26
- prettier: 2.7.1
-
-packages:
-
- /@authorizerdev/authorizer-js/1.2.1:
- resolution: {integrity: sha512-/nFARvsHyZUsGFKrcYi8hgpnbThYR/NMJ2BJdQpWy/x7QsBnfLeCChBYWncbYHSIjFCa5PPKKfvhXM56HqVqsw==}
- engines: {node: '>=10'}
- dependencies:
- cross-fetch: 3.1.5
- transitivePeerDependencies:
- - encoding
- dev: false
-
- /@authorizerdev/authorizer-react/1.1.9_react@17.0.2:
- resolution: {integrity: sha512-BlB4ixEm9nf+yjZ9OqIWbx5fMTmzeByEsNDAd5iYkt6HB+3Sk53DGiO5h6SgJznzPyqAwl8yg6y/QgbZreDTFA==}
- engines: {node: '>=10'}
- peerDependencies:
- react: '>=16'
- dependencies:
- '@authorizerdev/authorizer-js': 1.2.1
- react: 17.0.2
- transitivePeerDependencies:
- - encoding
- dev: false
-
- /@babel/code-frame/7.18.6:
- resolution: {integrity: sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==}
- engines: {node: '>=6.9.0'}
- dependencies:
- '@babel/highlight': 7.18.6
- dev: false
-
- /@babel/generator/7.21.3:
- resolution: {integrity: sha512-QS3iR1GYC/YGUnW7IdggFeN5c1poPUurnGttOV/bZgPGV+izC/D8HnD6DLwod0fsatNyVn1G3EVWMYIF0nHbeA==}
- engines: {node: '>=6.9.0'}
- dependencies:
- '@babel/types': 7.21.3
- '@jridgewell/gen-mapping': 0.3.2
- '@jridgewell/trace-mapping': 0.3.17
- jsesc: 2.5.2
- dev: false
-
- /@babel/helper-annotate-as-pure/7.18.6:
- resolution: {integrity: sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==}
- engines: {node: '>=6.9.0'}
- dependencies:
- '@babel/types': 7.21.3
- dev: false
-
- /@babel/helper-environment-visitor/7.18.9:
- resolution: {integrity: sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==}
- engines: {node: '>=6.9.0'}
- dev: false
-
- /@babel/helper-function-name/7.21.0:
- resolution: {integrity: sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==}
- engines: {node: '>=6.9.0'}
- dependencies:
- '@babel/template': 7.20.7
- '@babel/types': 7.21.3
- dev: false
-
- /@babel/helper-hoist-variables/7.18.6:
- resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==}
- engines: {node: '>=6.9.0'}
- dependencies:
- '@babel/types': 7.21.3
- dev: false
-
- /@babel/helper-module-imports/7.18.6:
- resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==}
- engines: {node: '>=6.9.0'}
- dependencies:
- '@babel/types': 7.21.3
- dev: false
-
- /@babel/helper-split-export-declaration/7.18.6:
- resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==}
- engines: {node: '>=6.9.0'}
- dependencies:
- '@babel/types': 7.21.3
- dev: false
-
- /@babel/helper-string-parser/7.19.4:
- resolution: {integrity: sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==}
- engines: {node: '>=6.9.0'}
- dev: false
-
- /@babel/helper-validator-identifier/7.19.1:
- resolution: {integrity: sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==}
- engines: {node: '>=6.9.0'}
- dev: false
-
- /@babel/highlight/7.18.6:
- resolution: {integrity: sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==}
- engines: {node: '>=6.9.0'}
- dependencies:
- '@babel/helper-validator-identifier': 7.19.1
- chalk: 2.4.2
- js-tokens: 4.0.0
- dev: false
-
- /@babel/parser/7.21.3:
- resolution: {integrity: sha512-lobG0d7aOfQRXh8AyklEAgZGvA4FShxo6xQbUrrT/cNBPUdIDojlokwJsQyCC/eKia7ifqM0yP+2DRZ4WKw2RQ==}
- engines: {node: '>=6.0.0'}
- hasBin: true
- dependencies:
- '@babel/types': 7.21.3
- dev: false
-
- /@babel/runtime/7.21.0:
- resolution: {integrity: sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==}
- engines: {node: '>=6.9.0'}
- dependencies:
- regenerator-runtime: 0.13.11
- dev: false
-
- /@babel/template/7.20.7:
- resolution: {integrity: sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==}
- engines: {node: '>=6.9.0'}
- dependencies:
- '@babel/code-frame': 7.18.6
- '@babel/parser': 7.21.3
- '@babel/types': 7.21.3
- dev: false
-
- /@babel/traverse/7.21.3_supports-color@5.5.0:
- resolution: {integrity: sha512-XLyopNeaTancVitYZe2MlUEvgKb6YVVPXzofHgqHijCImG33b/uTurMS488ht/Hbsb2XK3U2BnSTxKVNGV3nGQ==}
- engines: {node: '>=6.9.0'}
- dependencies:
- '@babel/code-frame': 7.18.6
- '@babel/generator': 7.21.3
- '@babel/helper-environment-visitor': 7.18.9
- '@babel/helper-function-name': 7.21.0
- '@babel/helper-hoist-variables': 7.18.6
- '@babel/helper-split-export-declaration': 7.18.6
- '@babel/parser': 7.21.3
- '@babel/types': 7.21.3
- debug: 4.3.4_supports-color@5.5.0
- globals: 11.12.0
- transitivePeerDependencies:
- - supports-color
- dev: false
-
- /@babel/types/7.21.3:
- resolution: {integrity: sha512-sBGdETxC+/M4o/zKC0sl6sjWv62WFR/uzxrJ6uYyMLZOUlPnwzw0tKgVHOXxaAd5l2g8pEDM5RZ495GPQI77kg==}
- engines: {node: '>=6.9.0'}
- dependencies:
- '@babel/helper-string-parser': 7.19.4
- '@babel/helper-validator-identifier': 7.19.1
- to-fast-properties: 2.0.0
- dev: false
-
- /@emotion/is-prop-valid/1.2.0:
- resolution: {integrity: sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg==}
- dependencies:
- '@emotion/memoize': 0.8.0
- dev: false
-
- /@emotion/memoize/0.8.0:
- resolution: {integrity: sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==}
- dev: false
-
- /@emotion/stylis/0.8.5:
- resolution: {integrity: sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==}
- dev: false
-
- /@emotion/unitless/0.7.5:
- resolution: {integrity: sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==}
- dev: false
-
- /@jridgewell/gen-mapping/0.3.2:
- resolution: {integrity: sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==}
- engines: {node: '>=6.0.0'}
- dependencies:
- '@jridgewell/set-array': 1.1.2
- '@jridgewell/sourcemap-codec': 1.4.14
- '@jridgewell/trace-mapping': 0.3.17
- dev: false
-
- /@jridgewell/resolve-uri/3.1.0:
- resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==}
- engines: {node: '>=6.0.0'}
- dev: false
-
- /@jridgewell/set-array/1.1.2:
- resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==}
- engines: {node: '>=6.0.0'}
- dev: false
-
- /@jridgewell/sourcemap-codec/1.4.14:
- resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==}
- dev: false
-
- /@jridgewell/trace-mapping/0.3.17:
- resolution: {integrity: sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==}
- dependencies:
- '@jridgewell/resolve-uri': 3.1.0
- '@jridgewell/sourcemap-codec': 1.4.14
- dev: false
-
- /@types/history/4.7.11:
- resolution: {integrity: sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==}
- dev: true
-
- /@types/hoist-non-react-statics/3.3.1:
- resolution: {integrity: sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==}
- dependencies:
- '@types/react': 17.0.53
- hoist-non-react-statics: 3.3.2
- dev: true
-
- /@types/prop-types/15.7.5:
- resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==}
-
- /@types/react-dom/17.0.19:
- resolution: {integrity: sha512-PiYG40pnQRdPHnlf7tZnp0aQ6q9tspYr72vD61saO6zFCybLfMqwUCN0va1/P+86DXn18ZWeW30Bk7xlC5eEAQ==}
- dependencies:
- '@types/react': 17.0.53
- dev: false
-
- /@types/react-router-dom/5.3.3:
- resolution: {integrity: sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==}
- dependencies:
- '@types/history': 4.7.11
- '@types/react': 17.0.53
- '@types/react-router': 5.1.20
- dev: true
-
- /@types/react-router/5.1.20:
- resolution: {integrity: sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==}
- dependencies:
- '@types/history': 4.7.11
- '@types/react': 17.0.53
- dev: true
-
- /@types/react/17.0.53:
- resolution: {integrity: sha512-1yIpQR2zdYu1Z/dc1OxC+MA6GR240u3gcnP4l6mvj/PJiVaqHsQPmWttsvHsfnhfPbU2FuGmo0wSITPygjBmsw==}
- dependencies:
- '@types/prop-types': 15.7.5
- '@types/scheduler': 0.16.3
- csstype: 3.1.1
-
- /@types/scheduler/0.16.3:
- resolution: {integrity: sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==}
-
- /@types/styled-components/5.1.26:
- resolution: {integrity: sha512-KuKJ9Z6xb93uJiIyxo/+ksS7yLjS1KzG6iv5i78dhVg/X3u5t1H7juRWqVmodIdz6wGVaIApo1u01kmFRdJHVw==}
- dependencies:
- '@types/hoist-non-react-statics': 3.3.1
- '@types/react': 17.0.53
- csstype: 3.1.1
- dev: true
-
- /ansi-styles/3.2.1:
- resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==}
- engines: {node: '>=4'}
- dependencies:
- color-convert: 1.9.3
- dev: false
-
- /babel-plugin-styled-components/2.0.7_styled-components@5.3.9:
- resolution: {integrity: sha512-i7YhvPgVqRKfoQ66toiZ06jPNA3p6ierpfUuEWxNF+fV27Uv5gxBkf8KZLHUCc1nFA9j6+80pYoIpqCeyW3/bA==}
- peerDependencies:
- styled-components: '>= 2'
- dependencies:
- '@babel/helper-annotate-as-pure': 7.18.6
- '@babel/helper-module-imports': 7.18.6
- babel-plugin-syntax-jsx: 6.18.0
- lodash: 4.17.21
- picomatch: 2.3.1
- styled-components: 5.3.9_fane7jikarojcev26y27hpbhu4
- dev: false
-
- /babel-plugin-syntax-jsx/6.18.0:
- resolution: {integrity: sha512-qrPaCSo9c8RHNRHIotaufGbuOBN8rtdC4QrrFFc43vyWCCz7Kl7GL1PGaXtMGQZUXrkCjNEgxDfmAuAabr/rlw==}
- dev: false
-
- /camelize/1.0.1:
- resolution: {integrity: sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==}
- dev: false
-
- /chalk/2.4.2:
- resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==}
- engines: {node: '>=4'}
- dependencies:
- ansi-styles: 3.2.1
- escape-string-regexp: 1.0.5
- supports-color: 5.5.0
- dev: false
-
- /color-convert/1.9.3:
- resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
- dependencies:
- color-name: 1.1.3
- dev: false
-
- /color-name/1.1.3:
- resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==}
- dev: false
-
- /cross-fetch/3.1.5:
- resolution: {integrity: sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==}
- dependencies:
- node-fetch: 2.6.7
- transitivePeerDependencies:
- - encoding
- dev: false
-
- /css-color-keywords/1.0.0:
- resolution: {integrity: sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==}
- engines: {node: '>=4'}
- dev: false
-
- /css-to-react-native/3.2.0:
- resolution: {integrity: sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==}
- dependencies:
- camelize: 1.0.1
- css-color-keywords: 1.0.0
- postcss-value-parser: 4.2.0
- dev: false
-
- /csstype/3.1.1:
- resolution: {integrity: sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==}
-
- /debug/4.3.4_supports-color@5.5.0:
- resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
- engines: {node: '>=6.0'}
- peerDependencies:
- supports-color: '*'
- peerDependenciesMeta:
- supports-color:
- optional: true
- dependencies:
- ms: 2.1.2
- supports-color: 5.5.0
- dev: false
-
- /esbuild/0.12.29:
- resolution: {integrity: sha512-w/XuoBCSwepyiZtIRsKsetiLDUVGPVw1E/R3VTFSecIy8UR7Cq3SOtwKHJMFoVqqVG36aGkzh4e8BvpO1Fdc7g==}
- hasBin: true
- requiresBuild: true
- dev: false
-
- /escape-string-regexp/1.0.5:
- resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==}
- engines: {node: '>=0.8.0'}
- dev: false
-
- /globals/11.12.0:
- resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==}
- engines: {node: '>=4'}
- dev: false
-
- /has-flag/3.0.0:
- resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==}
- engines: {node: '>=4'}
- dev: false
-
- /history/4.10.1:
- resolution: {integrity: sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==}
- dependencies:
- '@babel/runtime': 7.21.0
- loose-envify: 1.4.0
- resolve-pathname: 3.0.0
- tiny-invariant: 1.3.1
- tiny-warning: 1.0.3
- value-equal: 1.0.1
- dev: false
-
- /hoist-non-react-statics/3.3.2:
- resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==}
- dependencies:
- react-is: 16.13.1
-
- /isarray/0.0.1:
- resolution: {integrity: sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==}
- dev: false
-
- /js-tokens/4.0.0:
- resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
- dev: false
-
- /jsesc/2.5.2:
- resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==}
- engines: {node: '>=4'}
- hasBin: true
- dev: false
-
- /lodash/4.17.21:
- resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
- dev: false
-
- /loose-envify/1.4.0:
- resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
- hasBin: true
- dependencies:
- js-tokens: 4.0.0
- dev: false
-
- /ms/2.1.2:
- resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
- dev: false
-
- /node-fetch/2.6.7:
- resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==}
- engines: {node: 4.x || >=6.0.0}
- peerDependencies:
- encoding: ^0.1.0
- peerDependenciesMeta:
- encoding:
- optional: true
- dependencies:
- whatwg-url: 5.0.0
- dev: false
-
- /object-assign/4.1.1:
- resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
- engines: {node: '>=0.10.0'}
- dev: false
-
- /path-to-regexp/1.8.0:
- resolution: {integrity: sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==}
- dependencies:
- isarray: 0.0.1
- dev: false
-
- /picomatch/2.3.1:
- resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
- engines: {node: '>=8.6'}
- dev: false
-
- /postcss-value-parser/4.2.0:
- resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==}
- dev: false
-
- /prettier/2.7.1:
- resolution: {integrity: sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==}
- engines: {node: '>=10.13.0'}
- hasBin: true
- dev: true
-
- /prop-types/15.8.1:
- resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==}
- dependencies:
- loose-envify: 1.4.0
- object-assign: 4.1.1
- react-is: 16.13.1
- dev: false
-
- /react-dom/17.0.2_react@17.0.2:
- resolution: {integrity: sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==}
- peerDependencies:
- react: 17.0.2
- dependencies:
- loose-envify: 1.4.0
- object-assign: 4.1.1
- react: 17.0.2
- scheduler: 0.20.2
- dev: false
-
- /react-is/16.13.1:
- resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
-
- /react-is/17.0.2:
- resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==}
- dev: false
-
- /react-router-dom/5.3.4_react@17.0.2:
- resolution: {integrity: sha512-m4EqFMHv/Ih4kpcBCONHbkT68KoAeHN4p3lAGoNryfHi0dMy0kCzEZakiKRsvg5wHZ/JLrLW8o8KomWiz/qbYQ==}
- peerDependencies:
- react: '>=15'
- dependencies:
- '@babel/runtime': 7.21.0
- history: 4.10.1
- loose-envify: 1.4.0
- prop-types: 15.8.1
- react: 17.0.2
- react-router: 5.3.4_react@17.0.2
- tiny-invariant: 1.3.1
- tiny-warning: 1.0.3
- dev: false
-
- /react-router/5.3.4_react@17.0.2:
- resolution: {integrity: sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA==}
- peerDependencies:
- react: '>=15'
- dependencies:
- '@babel/runtime': 7.21.0
- history: 4.10.1
- hoist-non-react-statics: 3.3.2
- loose-envify: 1.4.0
- path-to-regexp: 1.8.0
- prop-types: 15.8.1
- react: 17.0.2
- react-is: 16.13.1
- tiny-invariant: 1.3.1
- tiny-warning: 1.0.3
- dev: false
-
- /react/17.0.2:
- resolution: {integrity: sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==}
- engines: {node: '>=0.10.0'}
- dependencies:
- loose-envify: 1.4.0
- object-assign: 4.1.1
- dev: false
-
- /regenerator-runtime/0.13.11:
- resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==}
- dev: false
-
- /resolve-pathname/3.0.0:
- resolution: {integrity: sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==}
- dev: false
-
- /scheduler/0.20.2:
- resolution: {integrity: sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==}
- dependencies:
- loose-envify: 1.4.0
- object-assign: 4.1.1
- dev: false
-
- /shallowequal/1.1.0:
- resolution: {integrity: sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==}
- dev: false
-
- /styled-components/5.3.9_fane7jikarojcev26y27hpbhu4:
- resolution: {integrity: sha512-Aj3kb13B75DQBo2oRwRa/APdB5rSmwUfN5exyarpX+x/tlM/rwZA2vVk2vQgVSP6WKaZJHWwiFrzgHt+CLtB4A==}
- engines: {node: '>=10'}
- peerDependencies:
- react: '>= 16.8.0'
- react-dom: '>= 16.8.0'
- react-is: '>= 16.8.0'
- dependencies:
- '@babel/helper-module-imports': 7.18.6
- '@babel/traverse': 7.21.3_supports-color@5.5.0
- '@emotion/is-prop-valid': 1.2.0
- '@emotion/stylis': 0.8.5
- '@emotion/unitless': 0.7.5
- babel-plugin-styled-components: 2.0.7_styled-components@5.3.9
- css-to-react-native: 3.2.0
- hoist-non-react-statics: 3.3.2
- react: 17.0.2
- react-dom: 17.0.2_react@17.0.2
- react-is: 17.0.2
- shallowequal: 1.1.0
- supports-color: 5.5.0
- dev: false
-
- /supports-color/5.5.0:
- resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==}
- engines: {node: '>=4'}
- dependencies:
- has-flag: 3.0.0
- dev: false
-
- /tiny-invariant/1.3.1:
- resolution: {integrity: sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==}
- dev: false
-
- /tiny-warning/1.0.3:
- resolution: {integrity: sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==}
- dev: false
-
- /to-fast-properties/2.0.0:
- resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==}
- engines: {node: '>=4'}
- dev: false
-
- /tr46/0.0.3:
- resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==}
- dev: false
-
- /typescript/4.9.5:
- resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==}
- engines: {node: '>=4.2.0'}
- hasBin: true
- dev: false
-
- /value-equal/1.0.1:
- resolution: {integrity: sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==}
- dev: false
-
- /webidl-conversions/3.0.1:
- resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==}
- dev: false
-
- /whatwg-url/5.0.0:
- resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==}
- dependencies:
- tr46: 0.0.3
- webidl-conversions: 3.0.1
- dev: false
diff --git a/app/src/index.tsx b/app/src/index.tsx
deleted file mode 100644
index 5d76a18a8..000000000
--- a/app/src/index.tsx
+++ /dev/null
@@ -1,6 +0,0 @@
-import React from 'react';
-import ReactDOM from 'react-dom';
-import App from './App';
-import './index.css';
-
-ReactDOM.render(, document.getElementById('root'));
diff --git a/app/tsconfig.json b/app/tsconfig.json
deleted file mode 100644
index 99dc84c6e..000000000
--- a/app/tsconfig.json
+++ /dev/null
@@ -1,72 +0,0 @@
-{
- "compilerOptions": {
- /* Visit https://aka.ms/tsconfig.json to read more about this file */
-
- /* Basic Options */
- // "incremental": true, /* Enable incremental compilation */
- "target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', 'ES2021', or 'ESNEXT'. */
- "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
- // "lib": ["es2018", "dom"], /* Specify library files to be included in the compilation. */
- // "allowJs": true, /* Allow javascript files to be compiled. */
- // "checkJs": true, /* Report errors in .js files. */
- "jsx": "react", /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */
- // "declaration": true, /* Generates corresponding '.d.ts' file. */
- // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
- // "sourceMap": true, /* Generates corresponding '.map' file. */
- // "outFile": "./", /* Concatenate and emit output to single file. */
- // "outDir": "./", /* Redirect output structure to the directory. */
- "rootDir": "src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
- // "composite": true, /* Enable project compilation */
- // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
- // "removeComments": true, /* Do not emit comments to output. */
- // "noEmit": true, /* Do not emit outputs. */
- // "importHelpers": true, /* Import emit helpers from 'tslib'. */
- // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
- // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
-
- /* Strict Type-Checking Options */
- "strict": true, /* Enable all strict type-checking options. */
- // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
- // "strictNullChecks": true, /* Enable strict null checks. */
- // "strictFunctionTypes": true, /* Enable strict checking of function types. */
- // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
- // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
- // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
- // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
-
- /* Additional Checks */
- // "noUnusedLocals": true, /* Report errors on unused locals. */
- // "noUnusedParameters": true, /* Report errors on unused parameters. */
- // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
- // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
- // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */
- // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an 'override' modifier. */
- // "noPropertyAccessFromIndexSignature": true, /* Require undeclared properties from index signatures to use element accesses. */
-
- /* Module Resolution Options */
- // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
- // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
- // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
- // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
- // "typeRoots": [], /* List of folders to include type definitions from. */
- // "types": [], /* Type declaration files to be included in compilation. */
- // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
- "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
- // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
- // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
-
- /* Source Map Options */
- // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
- // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
- // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
- // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
-
- /* Experimental Options */
- // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
- // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
-
- /* Advanced Options */
- "skipLibCheck": true, /* Skip type checking of declaration files. */
- "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
- }
-}
diff --git a/app/yarn.lock b/app/yarn.lock
deleted file mode 100644
index f09e1cfff..000000000
--- a/app/yarn.lock
+++ /dev/null
@@ -1,619 +0,0 @@
-# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
-# yarn lockfile v1
-
-
-"@authorizerdev/authorizer-js@^2.0.3":
- version "2.0.3"
- resolved "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-2.0.3.tgz"
- integrity sha512-uencwr3Ea8mwfxVKDFf2ITRCRSmzvua+O2voRuiWQORtRQTgZQjkN3M+IEkEj+WP9M1iFIl+NDgzECsp8ptC/A==
- dependencies:
- cross-fetch "^3.1.5"
-
-"@authorizerdev/authorizer-react@^1.3.2":
- version "1.3.2"
- resolved "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-1.3.2.tgz"
- integrity sha512-3kMAygHBCa8Fc9Oo0lz1k88r+Pd6kx1PSn3NMYLwxQXy2jRt4xWn7iuGn+SDGFs3DzofaN71I61gRwQ+6dO1rw==
- dependencies:
- "@authorizerdev/authorizer-js" "^2.0.3"
- validator "^13.11.0"
-
-"@babel/code-frame@^7.22.13":
- version "7.22.13"
- resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz"
- integrity sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==
- dependencies:
- "@babel/highlight" "^7.22.13"
- chalk "^2.4.2"
-
-"@babel/generator@^7.23.0":
- version "7.23.0"
- resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz"
- integrity sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==
- dependencies:
- "@babel/types" "^7.23.0"
- "@jridgewell/gen-mapping" "^0.3.2"
- "@jridgewell/trace-mapping" "^0.3.17"
- jsesc "^2.5.1"
-
-"@babel/helper-annotate-as-pure@^7.16.0":
- version "7.16.7"
- resolved "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz"
- integrity sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw==
- dependencies:
- "@babel/types" "^7.16.7"
-
-"@babel/helper-environment-visitor@^7.22.20":
- version "7.22.20"
- resolved "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz"
- integrity sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==
-
-"@babel/helper-function-name@^7.23.0":
- version "7.23.0"
- resolved "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz"
- integrity sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==
- dependencies:
- "@babel/template" "^7.22.15"
- "@babel/types" "^7.23.0"
-
-"@babel/helper-hoist-variables@^7.22.5":
- version "7.22.5"
- resolved "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz"
- integrity sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==
- dependencies:
- "@babel/types" "^7.22.5"
-
-"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.16.0":
- version "7.16.7"
- resolved "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz"
- integrity sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==
- dependencies:
- "@babel/types" "^7.16.7"
-
-"@babel/helper-split-export-declaration@^7.22.6":
- version "7.22.6"
- resolved "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz"
- integrity sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==
- dependencies:
- "@babel/types" "^7.22.5"
-
-"@babel/helper-string-parser@^7.22.5":
- version "7.22.5"
- resolved "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz"
- integrity sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==
-
-"@babel/helper-validator-identifier@^7.22.20":
- version "7.22.20"
- resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz"
- integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==
-
-"@babel/highlight@^7.22.13":
- version "7.22.20"
- resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz"
- integrity sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==
- dependencies:
- "@babel/helper-validator-identifier" "^7.22.20"
- chalk "^2.4.2"
- js-tokens "^4.0.0"
-
-"@babel/parser@^7.22.15", "@babel/parser@^7.23.0":
- version "7.23.0"
- resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz"
- integrity sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==
-
-"@babel/runtime@^7.1.2", "@babel/runtime@^7.12.1":
- version "7.14.8"
- resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.8.tgz"
- integrity sha512-twj3L8Og5SaCRCErB4x4ajbvBIVV77CGeFglHpeg5WC5FF8TZzBWXtTJ4MqaD9QszLYTtr+IsaAL2rEUevb+eg==
- dependencies:
- regenerator-runtime "^0.13.4"
-
-"@babel/template@^7.22.15":
- version "7.22.15"
- resolved "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz"
- integrity sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==
- dependencies:
- "@babel/code-frame" "^7.22.13"
- "@babel/parser" "^7.22.15"
- "@babel/types" "^7.22.15"
-
-"@babel/traverse@^7.4.5":
- version "7.23.2"
- resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz"
- integrity sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==
- dependencies:
- "@babel/code-frame" "^7.22.13"
- "@babel/generator" "^7.23.0"
- "@babel/helper-environment-visitor" "^7.22.20"
- "@babel/helper-function-name" "^7.23.0"
- "@babel/helper-hoist-variables" "^7.22.5"
- "@babel/helper-split-export-declaration" "^7.22.6"
- "@babel/parser" "^7.23.0"
- "@babel/types" "^7.23.0"
- debug "^4.1.0"
- globals "^11.1.0"
-
-"@babel/types@^7.16.7", "@babel/types@^7.22.15", "@babel/types@^7.22.5", "@babel/types@^7.23.0":
- version "7.23.0"
- resolved "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz"
- integrity sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==
- dependencies:
- "@babel/helper-string-parser" "^7.22.5"
- "@babel/helper-validator-identifier" "^7.22.20"
- to-fast-properties "^2.0.0"
-
-"@emotion/is-prop-valid@^0.8.8":
- version "0.8.8"
- resolved "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz"
- integrity sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==
- dependencies:
- "@emotion/memoize" "0.7.4"
-
-"@emotion/memoize@0.7.4":
- version "0.7.4"
- resolved "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz"
- integrity sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==
-
-"@emotion/stylis@^0.8.4":
- version "0.8.5"
- resolved "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz"
- integrity sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==
-
-"@emotion/unitless@^0.7.4":
- version "0.7.5"
- resolved "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz"
- integrity sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==
-
-"@jridgewell/gen-mapping@^0.3.2":
- version "0.3.3"
- resolved "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz"
- integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==
- dependencies:
- "@jridgewell/set-array" "^1.0.1"
- "@jridgewell/sourcemap-codec" "^1.4.10"
- "@jridgewell/trace-mapping" "^0.3.9"
-
-"@jridgewell/resolve-uri@^3.1.0":
- version "3.1.1"
- resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz"
- integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==
-
-"@jridgewell/set-array@^1.0.1":
- version "1.1.2"
- resolved "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz"
- integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==
-
-"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14":
- version "1.4.15"
- resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz"
- integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==
-
-"@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9":
- version "0.3.20"
- resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz"
- integrity sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==
- dependencies:
- "@jridgewell/resolve-uri" "^3.1.0"
- "@jridgewell/sourcemap-codec" "^1.4.14"
-
-"@types/history@*":
- version "4.7.9"
- resolved "https://registry.npmjs.org/@types/history/-/history-4.7.9.tgz"
- integrity sha512-MUc6zSmU3tEVnkQ78q0peeEjKWPUADMlC/t++2bI8WnAG2tvYRPIgHG8lWkXwqc8MsUF6Z2MOf+Mh5sazOmhiQ==
-
-"@types/hoist-non-react-statics@*":
- version "3.3.1"
- resolved "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz"
- integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==
- dependencies:
- "@types/react" "*"
- hoist-non-react-statics "^3.3.0"
-
-"@types/prop-types@*":
- version "15.7.4"
- resolved "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.4.tgz"
- integrity sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==
-
-"@types/react-dom@^17.0.9":
- version "17.0.9"
- resolved "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.9.tgz"
- integrity sha512-wIvGxLfgpVDSAMH5utdL9Ngm5Owu0VsGmldro3ORLXV8CShrL8awVj06NuEXFQ5xyaYfdca7Sgbk/50Ri1GdPg==
- dependencies:
- "@types/react" "*"
-
-"@types/react-router-dom@^5.1.8":
- version "5.1.8"
- resolved "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.1.8.tgz"
- integrity sha512-03xHyncBzG0PmDmf8pf3rehtjY0NpUj7TIN46FrT5n1ZWHPZvXz32gUyNboJ+xsL8cpg8bQVLcllptcQHvocrw==
- dependencies:
- "@types/history" "*"
- "@types/react" "*"
- "@types/react-router" "*"
-
-"@types/react-router@*":
- version "5.1.16"
- resolved "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.16.tgz"
- integrity sha512-8d7nR/fNSqlTFGHti0R3F9WwIertOaaA1UEB8/jr5l5mDMOs4CidEgvvYMw4ivqrBK+vtVLxyTj2P+Pr/dtgzg==
- dependencies:
- "@types/history" "*"
- "@types/react" "*"
-
-"@types/react@*", "@types/react@^17.0.15":
- version "17.0.15"
- resolved "https://registry.npmjs.org/@types/react/-/react-17.0.15.tgz"
- integrity sha512-uTKHDK9STXFHLaKv6IMnwp52fm0hwU+N89w/p9grdUqcFA6WuqDyPhaWopbNyE1k/VhgzmHl8pu1L4wITtmlLw==
- dependencies:
- "@types/prop-types" "*"
- "@types/scheduler" "*"
- csstype "^3.0.2"
-
-"@types/scheduler@*":
- version "0.16.2"
- resolved "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz"
- integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==
-
-"@types/styled-components@^5.1.11":
- version "5.1.25"
- resolved "https://registry.npmjs.org/@types/styled-components/-/styled-components-5.1.25.tgz"
- integrity sha512-fgwl+0Pa8pdkwXRoVPP9JbqF0Ivo9llnmsm+7TCI330kbPIFd9qv1Lrhr37shf4tnxCOSu+/IgqM7uJXLWZZNQ==
- dependencies:
- "@types/hoist-non-react-statics" "*"
- "@types/react" "*"
- csstype "^3.0.2"
-
-ansi-styles@^3.2.1:
- version "3.2.1"
- resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz"
- integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==
- dependencies:
- color-convert "^1.9.0"
-
-"babel-plugin-styled-components@>= 1.12.0":
- version "2.0.2"
- resolved "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-2.0.2.tgz"
- integrity sha512-7eG5NE8rChnNTDxa6LQfynwgHTVOYYaHJbUYSlOhk8QBXIQiMBKq4gyfHBBKPrxUcVBXVJL61ihduCpCQbuNbw==
- dependencies:
- "@babel/helper-annotate-as-pure" "^7.16.0"
- "@babel/helper-module-imports" "^7.16.0"
- babel-plugin-syntax-jsx "^6.18.0"
- lodash "^4.17.11"
-
-babel-plugin-syntax-jsx@^6.18.0:
- version "6.18.0"
- resolved "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz"
- integrity sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=
-
-camelize@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz"
- integrity sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs=
-
-chalk@^2.4.2:
- version "2.4.2"
- resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz"
- integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
- dependencies:
- ansi-styles "^3.2.1"
- escape-string-regexp "^1.0.5"
- supports-color "^5.3.0"
-
-color-convert@^1.9.0:
- version "1.9.3"
- resolved "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz"
- integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==
- dependencies:
- color-name "1.1.3"
-
-color-name@1.1.3:
- version "1.1.3"
- resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz"
- integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==
-
-cross-fetch@^3.1.5:
- version "3.1.8"
- resolved "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz"
- integrity sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==
- dependencies:
- node-fetch "^2.6.12"
-
-css-color-keywords@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz"
- integrity sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU=
-
-css-to-react-native@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.0.0.tgz"
- integrity sha512-Ro1yETZA813eoyUp2GDBhG2j+YggidUmzO1/v9eYBKR2EHVEniE2MI/NqpTQ954BMpTPZFsGNPm46qFB9dpaPQ==
- dependencies:
- camelize "^1.0.0"
- css-color-keywords "^1.0.0"
- postcss-value-parser "^4.0.2"
-
-csstype@^3.0.2:
- version "3.0.8"
- resolved "https://registry.npmjs.org/csstype/-/csstype-3.0.8.tgz"
- integrity sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw==
-
-debug@^4.1.0:
- version "4.3.3"
- resolved "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz"
- integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==
- dependencies:
- ms "2.1.2"
-
-esbuild@^0.12.17:
- version "0.12.17"
- resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.12.17.tgz"
- integrity sha512-GshKJyVYUnlSXIZj/NheC2O0Kblh42CS7P1wJyTbbIHevTG4jYMS9NNw8EOd8dDWD0dzydYHS01MpZoUcQXB4g==
-
-escape-string-regexp@^1.0.5:
- version "1.0.5"
- resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz"
- integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==
-
-globals@^11.1.0:
- version "11.12.0"
- resolved "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz"
- integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==
-
-has-flag@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz"
- integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0=
-
-history@^4.9.0:
- version "4.10.1"
- resolved "https://registry.npmjs.org/history/-/history-4.10.1.tgz"
- integrity sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==
- dependencies:
- "@babel/runtime" "^7.1.2"
- loose-envify "^1.2.0"
- resolve-pathname "^3.0.0"
- tiny-invariant "^1.0.2"
- tiny-warning "^1.0.0"
- value-equal "^1.0.1"
-
-hoist-non-react-statics@^3.0.0, hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.0:
- version "3.3.2"
- resolved "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz"
- integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==
- dependencies:
- react-is "^16.7.0"
-
-isarray@0.0.1:
- version "0.0.1"
- resolved "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz"
- integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=
-
-"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
- version "4.0.0"
- resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz"
- integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
-
-jsesc@^2.5.1:
- version "2.5.2"
- resolved "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz"
- integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==
-
-lodash@^4.17.11:
- version "4.17.21"
- resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz"
- integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
-
-loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.1, loose-envify@^1.4.0:
- version "1.4.0"
- resolved "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz"
- integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
- dependencies:
- js-tokens "^3.0.0 || ^4.0.0"
-
-mini-create-react-context@^0.4.0:
- version "0.4.1"
- resolved "https://registry.npmjs.org/mini-create-react-context/-/mini-create-react-context-0.4.1.tgz"
- integrity sha512-YWCYEmd5CQeHGSAKrYvXgmzzkrvssZcuuQDDeqkT+PziKGMgE+0MCCtcKbROzocGBG1meBLl2FotlRwf4gAzbQ==
- dependencies:
- "@babel/runtime" "^7.12.1"
- tiny-warning "^1.0.3"
-
-ms@2.1.2:
- version "2.1.2"
- resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz"
- integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
-
-node-fetch@^2.6.12:
- version "2.7.0"
- resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz"
- integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==
- dependencies:
- whatwg-url "^5.0.0"
-
-object-assign@^4.1.1:
- version "4.1.1"
- resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz"
- integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
-
-path-to-regexp@^1.7.0:
- version "1.8.0"
- resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz"
- integrity sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==
- dependencies:
- isarray "0.0.1"
-
-postcss-value-parser@^4.0.2:
- version "4.2.0"
- resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz"
- integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==
-
-prettier@2.7.1:
- version "2.7.1"
- resolved "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz"
- integrity sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==
-
-prop-types@^15.0.0, prop-types@^15.6.2:
- version "15.7.2"
- resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz"
- integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
- dependencies:
- loose-envify "^1.4.0"
- object-assign "^4.1.1"
- react-is "^16.8.1"
-
-react-dom@^17.0.2, "react-dom@>= 16.8.0":
- version "17.0.2"
- resolved "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz"
- integrity sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==
- dependencies:
- loose-envify "^1.1.0"
- object-assign "^4.1.1"
- scheduler "^0.20.2"
-
-react-is@^16.6.0:
- version "16.13.1"
- resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz"
- integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
-
-react-is@^16.7.0:
- version "16.13.1"
- resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz"
- integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
-
-react-is@^16.8.1:
- version "16.13.1"
- resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz"
- integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
-
-react-is@^17.0.2, "react-is@>= 16.8.0":
- version "17.0.2"
- resolved "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz"
- integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
-
-react-router-dom@^5.2.0:
- version "5.2.0"
- resolved "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.2.0.tgz"
- integrity sha512-gxAmfylo2QUjcwxI63RhQ5G85Qqt4voZpUXSEqCwykV0baaOTQDR1f0PmY8AELqIyVc0NEZUj0Gov5lNGcXgsA==
- dependencies:
- "@babel/runtime" "^7.1.2"
- history "^4.9.0"
- loose-envify "^1.3.1"
- prop-types "^15.6.2"
- react-router "5.2.0"
- tiny-invariant "^1.0.2"
- tiny-warning "^1.0.0"
-
-react-router@5.2.0:
- version "5.2.0"
- resolved "https://registry.npmjs.org/react-router/-/react-router-5.2.0.tgz"
- integrity sha512-smz1DUuFHRKdcJC0jobGo8cVbhO3x50tCL4icacOlcwDOEQPq4TMqwx3sY1TP+DvtTgz4nm3thuo7A+BK2U0Dw==
- dependencies:
- "@babel/runtime" "^7.1.2"
- history "^4.9.0"
- hoist-non-react-statics "^3.1.0"
- loose-envify "^1.3.1"
- mini-create-react-context "^0.4.0"
- path-to-regexp "^1.7.0"
- prop-types "^15.6.2"
- react-is "^16.6.0"
- tiny-invariant "^1.0.2"
- tiny-warning "^1.0.0"
-
-"react@^0.14.0 || ^15.0.0 || ^16.0.0 || ^17.0.0", react@^17.0.2, "react@>= 16.8.0", react@>=15, react@>=16, react@17.0.2:
- version "17.0.2"
- resolved "https://registry.npmjs.org/react/-/react-17.0.2.tgz"
- integrity sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==
- dependencies:
- loose-envify "^1.1.0"
- object-assign "^4.1.1"
-
-regenerator-runtime@^0.13.4:
- version "0.13.9"
- resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz"
- integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==
-
-resolve-pathname@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz"
- integrity sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==
-
-scheduler@^0.20.2:
- version "0.20.2"
- resolved "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz"
- integrity sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==
- dependencies:
- loose-envify "^1.1.0"
- object-assign "^4.1.1"
-
-shallowequal@^1.1.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz"
- integrity sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==
-
-styled-components@^5.3.0, "styled-components@>= 2":
- version "5.3.3"
- resolved "https://registry.npmjs.org/styled-components/-/styled-components-5.3.3.tgz"
- integrity sha512-++4iHwBM7ZN+x6DtPPWkCI4vdtwumQ+inA/DdAsqYd4SVgUKJie5vXyzotA00ttcFdQkCng7zc6grwlfIfw+lw==
- dependencies:
- "@babel/helper-module-imports" "^7.0.0"
- "@babel/traverse" "^7.4.5"
- "@emotion/is-prop-valid" "^0.8.8"
- "@emotion/stylis" "^0.8.4"
- "@emotion/unitless" "^0.7.4"
- babel-plugin-styled-components ">= 1.12.0"
- css-to-react-native "^3.0.0"
- hoist-non-react-statics "^3.0.0"
- shallowequal "^1.1.0"
- supports-color "^5.5.0"
-
-supports-color@^5.3.0, supports-color@^5.5.0:
- version "5.5.0"
- resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz"
- integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
- dependencies:
- has-flag "^3.0.0"
-
-tiny-invariant@^1.0.2:
- version "1.1.0"
- resolved "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.1.0.tgz"
- integrity sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw==
-
-tiny-warning@^1.0.0, tiny-warning@^1.0.3:
- version "1.0.3"
- resolved "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz"
- integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==
-
-to-fast-properties@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz"
- integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=
-
-tr46@~0.0.3:
- version "0.0.3"
- resolved "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz"
- integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==
-
-typescript@^4.3.5:
- version "4.3.5"
- resolved "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz"
- integrity sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==
-
-validator@^13.11.0:
- version "13.11.0"
- resolved "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz"
- integrity sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==
-
-value-equal@^1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz"
- integrity sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==
-
-webidl-conversions@^3.0.0:
- version "3.0.1"
- resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz"
- integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==
-
-whatwg-url@^5.0.0:
- version "5.0.0"
- resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz"
- integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==
- dependencies:
- tr46 "~0.0.3"
- webidl-conversions "^3.0.0"
diff --git a/cmd/root.go b/cmd/root.go
new file mode 100644
index 000000000..804ef31d7
--- /dev/null
+++ b/cmd/root.go
@@ -0,0 +1,334 @@
+package cmd
+
+import (
+ "context"
+ "os"
+ "os/signal"
+ "strings"
+ "time"
+
+ "github.com/rs/zerolog"
+ "github.com/spf13/cobra"
+ "golang.org/x/sync/errgroup"
+
+ "github.com/authorizerdev/authorizer/internal/authenticators"
+ "github.com/authorizerdev/authorizer/internal/config"
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/email"
+ "github.com/authorizerdev/authorizer/internal/events"
+ "github.com/authorizerdev/authorizer/internal/http_handlers"
+ "github.com/authorizerdev/authorizer/internal/memory_store"
+ "github.com/authorizerdev/authorizer/internal/oauth"
+ "github.com/authorizerdev/authorizer/internal/server"
+ "github.com/authorizerdev/authorizer/internal/sms"
+ "github.com/authorizerdev/authorizer/internal/storage"
+ "github.com/authorizerdev/authorizer/internal/token"
+)
+
+var (
+ RootCmd = cobra.Command{
+ Use: "authorizer",
+ Run: runRoot,
+ }
+ rootArgs struct {
+ logLevel string
+ config config.Config
+ server server.Config
+ }
+)
+
+func init() {
+ f := RootCmd.Flags()
+
+ // Server flags
+ f.StringVar(&rootArgs.server.Host, "host", "0.0.0.0", "Host address to listen on")
+ f.IntVar(&rootArgs.server.HTTPPort, "http-port", 8080, "Port to serve HTTP requests on")
+ f.IntVar(&rootArgs.server.MetricsPort, "metrics-port", 8081, "Port to serve metrics requests on")
+
+ // Logging flags
+ f.StringVar(&rootArgs.logLevel, "log-level", "debug", "Log level to use")
+
+ // Env
+ f.StringVar(&rootArgs.config.Env, "env", "", "Environment of the authorizer instance")
+
+ // Http routes
+ f.BoolVar(&rootArgs.config.EnableLoginPage, "enable-login-page", true, "Enable login page")
+ f.BoolVar(&rootArgs.config.EnablePlayground, "enable-playground", true, "Enable playground")
+
+ // Organization flags
+ f.StringVar(&rootArgs.config.OrganizationLogo, "organization-logo", "https://authorizer.dev/images/logo.png", "Logo of the organization")
+ f.StringVar(&rootArgs.config.OrganizationName, "organization-name", "Authorizer", "Name of the organization")
+
+ // OAuth flags
+ f.StringVar(&rootArgs.config.ClientID, "client-id", "", "Client ID for the OAuth")
+ f.StringVar(&rootArgs.config.ClientSecret, "client-secret", "", "Client secret for the OAuth")
+ f.StringVar(&rootArgs.config.DefaultAuthorizeResponseMode, "default-authorize-response-mode", constants.ResponseModeQuery, "Default response mode for the authorize endpoint")
+ f.StringVar(&rootArgs.config.DefaultAuthorizeResponseType, "default-authorize-response-type", constants.ResponseTypeToken, "Default response type for the authorize endpoint")
+
+ // Admin flags
+ f.StringVar(&rootArgs.config.AdminSecret, "admin-secret", "password", "Secret for the admin")
+
+ // Allowed origins
+ f.StringSliceVar(&rootArgs.config.AllowedOrigins, "allowed-origins", []string{"*"}, "Allowed origins")
+
+ // Database flags
+ f.StringVar(&rootArgs.config.DatabaseType, "database-type", "", "Type of database to use")
+ f.StringVar(&rootArgs.config.DatabaseURL, "database-url", "", "URL of the database")
+ f.StringVar(&rootArgs.config.DatabaseName, "database-name", "", "Name of the database")
+ f.StringVar(&rootArgs.config.DatabaseUsername, "database-username", "", "Username for the database")
+ f.StringVar(&rootArgs.config.DatabasePassword, "database-password", "", "Password for the database")
+ f.StringVar(&rootArgs.config.DatabaseHost, "database-host", "", "Host for the database")
+ f.IntVar(&rootArgs.config.DatabasePort, "database-port", 0, "Port for the database")
+ f.StringVar(&rootArgs.config.DatabaseCert, "database-cert", "", "Certificate for the database")
+ f.StringVar(&rootArgs.config.DatabaseCACert, "database-ca-cert", "", "CA certificate for the database")
+ f.StringVar(&rootArgs.config.DatabaseCertKey, "database-cert-key", "", "Certificate key for the database")
+ f.StringVar(&rootArgs.config.CouchBaseBucket, "couchbase-bucket", "", "Bucket for the database")
+ f.StringVar(&rootArgs.config.CouchBaseRamQuota, "couchbase-ram-quota", "", "RAM quota for the database")
+ f.StringVar(&rootArgs.config.CouchBaseScope, "couchbase-scope", "", "Scope for the database")
+ f.StringVar(&rootArgs.config.AWSRegion, "aws-region", "", "Region for the dynamodb database")
+ f.StringVar(&rootArgs.config.AWSAccessKeyID, "aws-access-key-id", "", "Access key ID for the dynamodb database")
+ f.StringVar(&rootArgs.config.AWSSecretAccessKey, "aws-secret-access-key", "", "Secret access key for the dynamodb database")
+
+ // Memory store flags
+ f.StringVar(&rootArgs.config.RedisURL, "redis-url", "", "URL of the redis server")
+
+ // Email flags
+ f.StringVar(&rootArgs.config.SMTPHost, "smtp-host", "", "Host for the SMTP server")
+ f.IntVar(&rootArgs.config.SMTPPort, "smtp-port", 0, "Port for the SMTP server")
+ f.StringVar(&rootArgs.config.SMTPUsername, "smtp-username", "", "Username for the SMTP server")
+ f.StringVar(&rootArgs.config.SMTPPassword, "smtp-password", "", "Password for the SMTP server")
+ f.StringVar(&rootArgs.config.SMTPSenderEmail, "smtp-sender-email", "", "Sender email for the SMTP server")
+ f.StringVar(&rootArgs.config.SMTPSenderName, "smtp-sender-name", "", "Sender name for the SMTP server")
+ f.StringVar(&rootArgs.config.SMTPLocalName, "smtp-local-name", "", "Local name for the SMTP server")
+ f.BoolVar(&rootArgs.config.SkipTLSVerification, "skip-tls-verification", false, "Skip TLS verification for the SMTP server")
+
+ // Auth flags
+ f.StringSliceVar(&rootArgs.config.DefaultRoles, "default-roles", []string{"user"}, "Default user roles to assign")
+ f.StringSliceVar(&rootArgs.config.Roles, "roles", []string{"user"}, "Roles to assign")
+ f.StringSliceVar(&rootArgs.config.ProtectedRoles, "protected-roles", []string{}, "Roles that cannot be deleted")
+ f.BoolVar(&rootArgs.config.EnableStrongPassword, "enable-strong-password", true, "Enable strong password requirement")
+ f.BoolVar(&rootArgs.config.EnableTOTPLogin, "enable-totp-login", false, "Enable TOTP login")
+ f.BoolVar(&rootArgs.config.EnableBasicAuthentication, "enable-basic-authentication", true, "Enable basic authentication")
+ f.BoolVar(&rootArgs.config.EnableEmailVerification, "enable-email-verification", false, "Enable email verification")
+ f.BoolVar(&rootArgs.config.EnableMobileBasicAuthentication, "enable-mobile-basic-authentication", true, "Enable mobile basic authentication")
+ f.BoolVar(&rootArgs.config.EnablePhoneVerification, "enable-phone-verification", false, "Enable phone verification")
+ f.BoolVar(&rootArgs.config.EnableMagicLinkLogin, "enable-magic-link-login", false, "Enable magic link login")
+ f.BoolVar(&rootArgs.config.EnforceMFA, "enforce-mfa", true, "Enforce MFA for all users")
+ f.BoolVar(&rootArgs.config.EnableMFA, "enable-mfa", false, "Enable MFA for all users")
+ f.BoolVar(&rootArgs.config.EnableEmailOTP, "enable-email-otp", false, "Enable email OTP")
+ f.BoolVar(&rootArgs.config.EnableSMSOTP, "enable-sms-otp", false, "Enable SMS OTP")
+ f.BoolVar(&rootArgs.config.EnableSignup, "enable-signup", true, "Enable signup")
+
+ // Cookies flags
+ f.BoolVar(&rootArgs.config.AppCookieSecure, "app-cookie-secure", true, "Application secure cookie flag")
+ f.BoolVar(&rootArgs.config.AdminCookieSecure, "admin-cookie-secure", true, "Admin secure cookie flag")
+
+ // JWT flags
+ f.StringVar(&rootArgs.config.JWTType, "jwt-type", "", "Type of JWT to use")
+ f.StringVar(&rootArgs.config.JWTSecret, "jwt-secret", "", "Secret for the JWT")
+ f.StringVar(&rootArgs.config.JWTPrivateKey, "jwt-private-key", "", "Private key for the JWT")
+ f.StringVar(&rootArgs.config.JWTPublicKey, "jwt-public-key", "", "Public key for the JWT")
+ f.StringVar(&rootArgs.config.JWTRoleClaim, "jwt-role-claim", "role", "Role claim for the JWT")
+ f.StringVar(&rootArgs.config.CustomAccessTokenScript, "custom-access-token-script", "", "Custom access token script")
+
+ // Twilio flags
+ f.StringVar(&rootArgs.config.TwilioAccountSID, "twilio-account-sid", "", "Account SID for Twilio")
+ f.StringVar(&rootArgs.config.TwilioAPIKey, "twilio-api-key", "", "API key for Twilio")
+ f.StringVar(&rootArgs.config.TwilioAPISecret, "twilio-api-secret", "", "API secret for Twilio")
+ f.StringVar(&rootArgs.config.TwilioSender, "twilio-sender", "", "Sender for Twilio")
+
+ // Oauth provider flags
+ f.StringVar(&rootArgs.config.GoogleClientID, "google-client-id", "", "Client ID for Google")
+ f.StringVar(&rootArgs.config.GoogleClientSecret, "google-client-secret", "", "Client secret for Google")
+ f.StringSliceVar(&rootArgs.config.GoogleScopes, "google-scopes", []string{"openid", "profile", "email"}, "Scopes for Google")
+ f.StringVar(&rootArgs.config.GithubClientID, "github-client-id", "", "Client ID for Github")
+ f.StringVar(&rootArgs.config.GithubClientSecret, "github-client-secret", "", "Client secret for Github")
+ f.StringSliceVar(&rootArgs.config.GithubScopes, "github-scopes", []string{"read:user", "user:email"}, "Scopes for Github")
+ f.StringVar(&rootArgs.config.FacebookClientID, "facebook-client-id", "", "Client ID for Facebook")
+ f.StringVar(&rootArgs.config.FacebookClientSecret, "facebook-client-secret", "", "Client secret for Facebook")
+ f.StringSliceVar(&rootArgs.config.FacebookScopes, "facebook-scopes", []string{"public_profile", "email"}, "Scopes for Facebook")
+ f.StringVar(&rootArgs.config.MicrosoftClientID, "microsoft-client-id", "", "Client ID for Microsoft")
+ f.StringVar(&rootArgs.config.MicrosoftClientSecret, "microsoft-client-secret", "", "Client secret for Microsoft")
+ f.StringVar(&rootArgs.config.MicrosoftTenantID, "microsoft-tenant-id", "common", "Tenant ID for Microsoft")
+ f.StringSliceVar(&rootArgs.config.MicrosoftScopes, "microsoft-scopes", []string{"openid", "profile", "email"}, "Scopes for Microsoft")
+ f.StringVar(&rootArgs.config.TwitchClientID, "twitch-client-id", "", "Client ID for Twitch")
+ f.StringVar(&rootArgs.config.TwitchClientSecret, "twitch-client-secret", "", "Client secret for Twitch")
+ f.StringSliceVar(&rootArgs.config.TwitchScopes, "twitch-scopes", []string{"openid", "user:read:email"}, "Scopes for Twitch")
+ f.StringVar(&rootArgs.config.LinkedinClientID, "linkedin-client-id", "", "Client ID for Linkedin")
+ f.StringVar(&rootArgs.config.LinkedinClientSecret, "linkedin-client-secret", "", "Client secret for Linkedin")
+ f.StringSliceVar(&rootArgs.config.LinkedinScopes, "linkedin-scopes", []string{"r_liteprofile", "r_emailaddress"}, "Scopes for Linkedin")
+ f.StringVar(&rootArgs.config.AppleClientID, "apple-client-id", "", "Client ID for Apple")
+ f.StringVar(&rootArgs.config.AppleClientSecret, "apple-client-secret", "", "Client secret for Apple")
+ f.StringSliceVar(&rootArgs.config.AppleScopes, "apple-scopes", []string{"email", "name"}, "Scopes for Apple")
+ f.StringVar(&rootArgs.config.DiscordClientID, "discord-client-id", "", "Client ID for Discord")
+ f.StringVar(&rootArgs.config.DiscordClientSecret, "discord-client-secret", "", "Client secret for Discord")
+ f.StringSliceVar(&rootArgs.config.DiscordScopes, "discord-scopes", []string{"identify", "email"}, "Scopes for Discord")
+ f.StringVar(&rootArgs.config.TwitterClientID, "twitter-client-id", "", "Client ID for Twitter")
+ f.StringVar(&rootArgs.config.TwitterClientSecret, "twitter-client-secret", "", "Client secret for Twitter")
+ f.StringSliceVar(&rootArgs.config.TwitterScopes, "twitter-scopes", []string{"tweet.read", "users.read"}, "Scopes for Twitter")
+ f.StringVar(&rootArgs.config.RobloxClientID, "roblox-client-id", "", "Client ID for Roblox")
+ f.StringVar(&rootArgs.config.RobloxClientSecret, "roblox-client-secret", "", "Client secret for Roblox")
+ f.StringSliceVar(&rootArgs.config.RobloxScopes, "roblox-scopes", []string{"openid", "profile"}, "Scopes for Roblox")
+
+ // URLs
+ f.StringVar(&rootArgs.config.ResetPasswordURL, "reset-password-url", "", "URL for reset password")
+
+ // Deprecated flags
+ f.MarkDeprecated("database_url", "use --database-url instead")
+ f.MarkDeprecated("database_type", "use --database-type instead")
+ f.MarkDeprecated("env_file", "no more supported")
+ f.MarkDeprecated("log_level", "use --log-level instead")
+ f.MarkDeprecated("redis_url", "use --redis-url instead")
+}
+
+// Run the service
+func runRoot(c *cobra.Command, args []string) {
+ // Prepare logger
+ ctx := context.Background()
+ // Parse the log level
+ zeroLogLevel, err := zerolog.ParseLevel(rootArgs.logLevel)
+ if err != nil {
+ // If the log level is invalid, set it to debug
+ zeroLogLevel = zerolog.DebugLevel
+ }
+ // Create a new console writer
+ // consoleWriter := zerolog.New(os.Stdout)
+ // consoleWriter.NoColor = true
+ // consoleWriter.TimeFormat = time.RFC3339
+ // consoleWriter.TimeLocation = time.UTC
+ zerolog.TimestampFunc = func() time.Time {
+ return time.Now().UTC()
+ }
+ log := zerolog.New(os.Stdout).
+ Level(zeroLogLevel).
+ With().Timestamp().Logger()
+
+ // Storage provider
+ storageProvider, err := storage.New(&rootArgs.config, &storage.Dependencies{
+ Log: &log,
+ })
+ if err != nil {
+ log.Fatal().Err(err).Msg("failed to create storage provider")
+ }
+
+ // Authenticator provider
+ authenticatorProvider, err := authenticators.New(&rootArgs.config, &authenticators.Dependencies{
+ Log: &log,
+ StorageProvider: storageProvider,
+ })
+ if err != nil {
+ log.Fatal().Err(err).Msg("failed to create authenticator provider")
+ }
+
+ // Email provider
+ emailProvider, err := email.New(&rootArgs.config, &email.Dependencies{
+ Log: &log,
+ StorageProvider: storageProvider,
+ })
+ if err != nil {
+ log.Fatal().Err(err).Msg("failed to create email provider")
+ }
+
+ // Events provider
+ eventsProvider, err := events.New(&rootArgs.config, &events.Dependencies{
+ Log: &log,
+ StorageProvider: storageProvider,
+ })
+ if err != nil {
+ log.Fatal().Err(err).Msg("failed to create events provider")
+ }
+
+ // Memory store provider
+ memoryStoreProvider, err := memory_store.New(&rootArgs.config, &memory_store.Dependencies{
+ Log: &log,
+ })
+ if err != nil {
+ log.Fatal().Err(err).Msg("failed to create memory store provider")
+ }
+
+ // SMS provider
+ smsProvider, err := sms.New(&rootArgs.config, &sms.Dependencies{
+ Log: &log,
+ })
+ if err != nil {
+ log.Fatal().Err(err).Msg("failed to create sms provider")
+ }
+
+ // Token provider
+ tokenProvider, err := token.New(&rootArgs.config, &token.Dependencies{
+ Log: &log,
+ MemoryStoreProvider: memoryStoreProvider,
+ })
+ if err != nil {
+ log.Fatal().Err(err).Msg("failed to create token provider")
+ }
+ // OAuth provider
+ oauthProvider, err := oauth.New(&rootArgs.config, &oauth.Dependencies{
+ Log: &log,
+ })
+ if err != nil {
+ log.Fatal().Err(err).Msg("failed to create oauth provider")
+ }
+
+ // Ensure client ID and secret are set for authorizer instance
+ if strings.TrimSpace(rootArgs.config.ClientID) == "" {
+ log.Fatal().Msg("client ID missing in rootArgs")
+ }
+
+ if strings.TrimSpace(rootArgs.config.ClientSecret) == "" {
+ log.Fatal().Msg("client secret missing in rootArgs")
+ }
+
+ httpProvider, err := http_handlers.New(&rootArgs.config, &http_handlers.Dependencies{
+ Log: &log,
+ AuthenticatorProvider: authenticatorProvider,
+ EmailProvider: emailProvider,
+ EventsProvider: eventsProvider,
+ MemoryStoreProvider: memoryStoreProvider,
+ SMSProvider: smsProvider,
+ StorageProvider: storageProvider,
+ TokenProvider: tokenProvider,
+ OAuthProvider: oauthProvider,
+ })
+ if err != nil {
+ log.Fatal().Err(err).Msg("failed to create http provider")
+ }
+ // Prepare server
+ deps := &server.Dependencies{
+ Log: &log,
+ HTTPProvider: httpProvider,
+ }
+ // Create the server
+ svr, err := server.New(&rootArgs.server, deps)
+ if err != nil {
+ log.Fatal().Err(err).Msg("failed to create server")
+ }
+
+ ctx, cancel := context.WithCancel(ctx)
+ defer cancel()
+ g, ctx := errgroup.WithContext(ctx)
+ g.Go(func() error {
+ return svr.Run(ctx)
+ })
+
+ // Setup signal handler to allow for graceful termination
+ sigCtx, stop := signal.NotifyContext(ctx, os.Interrupt)
+
+ // Wait for interrupt or failure in errgroup.
+ select {
+ case <-sigCtx.Done():
+ log.Info().Msg("Signal received, shutting down...")
+ // Unregister signal handlers.
+ // Next interrupt signal will kill us.
+ cancel()
+ stop()
+ case <-ctx.Done():
+ // Errgroup context canceled
+ }
+
+ // Wait for all routines to end
+ if err := g.Wait(); err != nil {
+ log.Fatal().Err(err).Msg("Application failed")
+ }
+ log.Info().Msg("Application terminated")
+}
diff --git a/dashboard/esbuild.config.js b/dashboard/esbuild.config.js
deleted file mode 100644
index 40fe8390f..000000000
--- a/dashboard/esbuild.config.js
+++ /dev/null
@@ -1,12 +0,0 @@
-const __is_prod__ = process.env.NODE_ENV === 'production';
-require('esbuild').build({
- entryPoints: ['src/index.tsx'],
- chunkNames: '[name]-[hash]',
- bundle: true,
- minify: __is_prod__,
- outdir: 'build',
- splitting: true,
- format: 'esm',
- watch: !__is_prod__,
- logLevel: 'info',
-});
diff --git a/dashboard/package-lock.json b/dashboard/package-lock.json
deleted file mode 100644
index 0e1bbfb49..000000000
--- a/dashboard/package-lock.json
+++ /dev/null
@@ -1,3092 +0,0 @@
-{
- "name": "dashboard",
- "version": "1.0.0",
- "lockfileVersion": 3,
- "requires": true,
- "packages": {
- "": {
- "name": "dashboard",
- "version": "1.0.0",
- "license": "ISC",
- "dependencies": {
- "@chakra-ui/react": "^1.7.3",
- "@emotion/core": "^11.0.0",
- "@emotion/react": "^11.7.1",
- "@emotion/styled": "^11.6.0",
- "@types/react": "^17.0.38",
- "@types/react-dom": "^17.0.11",
- "@types/react-router-dom": "^5.3.2",
- "dayjs": "^1.10.7",
- "esbuild": "^0.14.9",
- "focus-visible": "^5.2.0",
- "framer-motion": "^5.5.5",
- "graphql": "^16.2.0",
- "lodash": "^4.17.21",
- "react": "^17.0.2",
- "react-dom": "^17.0.2",
- "react-draft-wysiwyg": "^1.15.0",
- "react-dropzone": "^12.0.4",
- "react-email-editor": "^1.6.1",
- "react-icons": "^4.3.1",
- "react-router-dom": "^6.2.1",
- "typescript": "^4.5.4",
- "urql": "^2.0.6"
- },
- "devDependencies": {
- "@types/react-email-editor": "^1.1.7",
- "prettier": "2.7.1"
- }
- },
- "node_modules/@ampproject/remapping": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz",
- "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==",
- "peer": true,
- "dependencies": {
- "@jridgewell/gen-mapping": "^0.3.0",
- "@jridgewell/trace-mapping": "^0.3.9"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@babel/code-frame": {
- "version": "7.22.13",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz",
- "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==",
- "dependencies": {
- "@babel/highlight": "^7.22.13",
- "chalk": "^2.4.2"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/compat-data": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.3.tgz",
- "integrity": "sha512-BmR4bWbDIoFJmJ9z2cZ8Gmm2MXgEDgjdWgpKmKWUt54UGFJdlj31ECtbaDvCG/qVdG3AQ1SfpZEs01lUFbzLOQ==",
- "peer": true,
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/core": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.3.tgz",
- "integrity": "sha512-Jg+msLuNuCJDyBvFv5+OKOUjWMZgd85bKjbICd3zWrKAo+bJ49HJufi7CQE0q0uR8NGyO6xkCACScNqyjHSZew==",
- "peer": true,
- "dependencies": {
- "@ampproject/remapping": "^2.2.0",
- "@babel/code-frame": "^7.22.13",
- "@babel/generator": "^7.23.3",
- "@babel/helper-compilation-targets": "^7.22.15",
- "@babel/helper-module-transforms": "^7.23.3",
- "@babel/helpers": "^7.23.2",
- "@babel/parser": "^7.23.3",
- "@babel/template": "^7.22.15",
- "@babel/traverse": "^7.23.3",
- "@babel/types": "^7.23.3",
- "convert-source-map": "^2.0.0",
- "debug": "^4.1.0",
- "gensync": "^1.0.0-beta.2",
- "json5": "^2.2.3",
- "semver": "^6.3.1"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/babel"
- }
- },
- "node_modules/@babel/core/node_modules/convert-source-map": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
- "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
- "peer": true
- },
- "node_modules/@babel/generator": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.3.tgz",
- "integrity": "sha512-keeZWAV4LU3tW0qRi19HRpabC/ilM0HRBBzf9/k8FFiG4KVpiv0FIy4hHfLfFQZNhziCTPTmd59zoyv6DNISzg==",
- "peer": true,
- "dependencies": {
- "@babel/types": "^7.23.3",
- "@jridgewell/gen-mapping": "^0.3.2",
- "@jridgewell/trace-mapping": "^0.3.17",
- "jsesc": "^2.5.1"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-compilation-targets": {
- "version": "7.22.15",
- "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz",
- "integrity": "sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==",
- "peer": true,
- "dependencies": {
- "@babel/compat-data": "^7.22.9",
- "@babel/helper-validator-option": "^7.22.15",
- "browserslist": "^4.21.9",
- "lru-cache": "^5.1.1",
- "semver": "^6.3.1"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-environment-visitor": {
- "version": "7.22.20",
- "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz",
- "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==",
- "peer": true,
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-function-name": {
- "version": "7.23.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz",
- "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==",
- "peer": true,
- "dependencies": {
- "@babel/template": "^7.22.15",
- "@babel/types": "^7.23.0"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-hoist-variables": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz",
- "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==",
- "peer": true,
- "dependencies": {
- "@babel/types": "^7.22.5"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-module-imports": {
- "version": "7.22.15",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz",
- "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==",
- "dependencies": {
- "@babel/types": "^7.22.15"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-module-transforms": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz",
- "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==",
- "peer": true,
- "dependencies": {
- "@babel/helper-environment-visitor": "^7.22.20",
- "@babel/helper-module-imports": "^7.22.15",
- "@babel/helper-simple-access": "^7.22.5",
- "@babel/helper-split-export-declaration": "^7.22.6",
- "@babel/helper-validator-identifier": "^7.22.20"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0"
- }
- },
- "node_modules/@babel/helper-plugin-utils": {
- "version": "7.16.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.5.tgz",
- "integrity": "sha512-59KHWHXxVA9K4HNF4sbHCf+eJeFe0Te/ZFGqBT4OjXhrwvA04sGfaEGsVTdsjoszq0YTP49RC9UKe5g8uN2RwQ==",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-simple-access": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz",
- "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==",
- "peer": true,
- "dependencies": {
- "@babel/types": "^7.22.5"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-split-export-declaration": {
- "version": "7.22.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz",
- "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==",
- "peer": true,
- "dependencies": {
- "@babel/types": "^7.22.5"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-string-parser": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz",
- "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-validator-identifier": {
- "version": "7.22.20",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
- "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-validator-option": {
- "version": "7.22.15",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz",
- "integrity": "sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==",
- "peer": true,
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helpers": {
- "version": "7.23.2",
- "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.2.tgz",
- "integrity": "sha512-lzchcp8SjTSVe/fPmLwtWVBFC7+Tbn8LGHDVfDp9JGxpAY5opSaEFgt8UQvrnECWOTdji2mOWMz1rOhkHscmGQ==",
- "peer": true,
- "dependencies": {
- "@babel/template": "^7.22.15",
- "@babel/traverse": "^7.23.2",
- "@babel/types": "^7.23.0"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/highlight": {
- "version": "7.22.20",
- "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz",
- "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==",
- "dependencies": {
- "@babel/helper-validator-identifier": "^7.22.20",
- "chalk": "^2.4.2",
- "js-tokens": "^4.0.0"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/parser": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.3.tgz",
- "integrity": "sha512-uVsWNvlVsIninV2prNz/3lHCb+5CJ+e+IUBfbjToAHODtfGYLfCFuY4AU7TskI+dAKk+njsPiBjq1gKTvZOBaw==",
- "peer": true,
- "bin": {
- "parser": "bin/babel-parser.js"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@babel/plugin-syntax-jsx": {
- "version": "7.16.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.16.5.tgz",
- "integrity": "sha512-42OGssv9NPk4QHKVgIHlzeLgPOW5rGgfV5jzG90AhcXXIv6hu/eqj63w4VgvRxdvZY3AlYeDgPiSJ3BqAd1Y6Q==",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.16.5"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/runtime": {
- "version": "7.16.5",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.5.tgz",
- "integrity": "sha512-TXWihFIS3Pyv5hzR7j6ihmeLkZfrXGxAr5UfSl8CHf+6q/wpiYDkUau0czckpYG8QmnCIuPpdLtuA9VmuGGyMA==",
- "dependencies": {
- "regenerator-runtime": "^0.13.4"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/template": {
- "version": "7.22.15",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz",
- "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==",
- "peer": true,
- "dependencies": {
- "@babel/code-frame": "^7.22.13",
- "@babel/parser": "^7.22.15",
- "@babel/types": "^7.22.15"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/traverse": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.3.tgz",
- "integrity": "sha512-+K0yF1/9yR0oHdE0StHuEj3uTPzwwbrLGfNOndVJVV2TqA5+j3oljJUb4nmB954FLGjNem976+B+eDuLIjesiQ==",
- "peer": true,
- "dependencies": {
- "@babel/code-frame": "^7.22.13",
- "@babel/generator": "^7.23.3",
- "@babel/helper-environment-visitor": "^7.22.20",
- "@babel/helper-function-name": "^7.23.0",
- "@babel/helper-hoist-variables": "^7.22.5",
- "@babel/helper-split-export-declaration": "^7.22.6",
- "@babel/parser": "^7.23.3",
- "@babel/types": "^7.23.3",
- "debug": "^4.1.0",
- "globals": "^11.1.0"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/types": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.3.tgz",
- "integrity": "sha512-OZnvoH2l8PK5eUvEcUyCt/sXgr/h+UWpVuBbOljwcrAgUl6lpchoQ++PHGyQy1AtYnVA6CEq3y5xeEI10brpXw==",
- "dependencies": {
- "@babel/helper-string-parser": "^7.22.5",
- "@babel/helper-validator-identifier": "^7.22.20",
- "to-fast-properties": "^2.0.0"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@chakra-ui/accordion": {
- "version": "1.4.2",
- "resolved": "https://registry.npmjs.org/@chakra-ui/accordion/-/accordion-1.4.2.tgz",
- "integrity": "sha512-BAGMvcm2sFE5Ft7jwC9nF03/Yv7qztuhzwKBBy4iL0p1nCPh6kV54RBXUcoj3VWe+yrmNiAVYKRTdqQBTJFwOw==",
- "dependencies": {
- "@chakra-ui/descendant": "2.1.1",
- "@chakra-ui/hooks": "1.7.1",
- "@chakra-ui/icon": "2.0.0",
- "@chakra-ui/react-utils": "1.2.1",
- "@chakra-ui/transition": "1.4.2",
- "@chakra-ui/utils": "1.9.1"
- },
- "peerDependencies": {
- "@chakra-ui/system": ">=1.0.0",
- "react": ">=16.8.6"
- }
- },
- "node_modules/@chakra-ui/alert": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/@chakra-ui/alert/-/alert-1.3.2.tgz",
- "integrity": "sha512-+OMeVeGtydpj6nry0zH7qFDt36zEaxckRnufx1BGiCfWdUg6ahVwKXl8qX93Q8w82od7eAoBKMgGJz7IVL5NPw==",
- "dependencies": {
- "@chakra-ui/icon": "2.0.0",
- "@chakra-ui/react-utils": "1.2.1",
- "@chakra-ui/utils": "1.9.1"
- },
- "peerDependencies": {
- "@chakra-ui/system": ">=1.0.0",
- "react": ">=16.8.6"
- }
- },
- "node_modules/@chakra-ui/anatomy": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/@chakra-ui/anatomy/-/anatomy-1.2.1.tgz",
- "integrity": "sha512-kNS+FiEDTSnwpQUW4dEjZ5745xhkvB0XtmqjY1wpclUSpFfptLZM9QIHPTnBt2bzM9R+idmRRP+WkTt6kyTrLw==",
- "dependencies": {
- "@chakra-ui/theme-tools": "^1.3.1"
- }
- },
- "node_modules/@chakra-ui/avatar": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/@chakra-ui/avatar/-/avatar-1.3.1.tgz",
- "integrity": "sha512-WI0/kcpTJViOH093V0bz8EB+e/rc+gjF+T5DkOuh1YWFxRRG5v+4Yd3PdEJtQgzWtBVhlbGWmE7WvBizyKwFCA==",
- "dependencies": {
- "@chakra-ui/image": "1.1.1",
- "@chakra-ui/react-utils": "1.2.1",
- "@chakra-ui/utils": "1.9.1"
- },
- "peerDependencies": {
- "@chakra-ui/system": ">=1.0.0",
- "react": ">=16.8.6"
- }
- },
- "node_modules/@chakra-ui/breadcrumb": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/@chakra-ui/breadcrumb/-/breadcrumb-1.3.1.tgz",
- "integrity": "sha512-b1IoBmtr5FcP2fn5NRbdOdQo2c866OQ/WhcTcZ6UKae1jjik+36/qWE+X+RKzxC6FLfqo5qayV5zSgsnZym7Pg==",
- "dependencies": {
- "@chakra-ui/react-utils": "1.2.1",
- "@chakra-ui/utils": "1.9.1"
- },
- "peerDependencies": {
- "@chakra-ui/system": ">=1.0.0",
- "react": ">=16.8.6"
- }
- },
- "node_modules/@chakra-ui/button": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/@chakra-ui/button/-/button-1.5.1.tgz",
- "integrity": "sha512-BvP29quEhP6OTgDiRsugD6adgkeOTEQpoDsZUVEmHnNVrbFfdsICEKKQTtDJ2iPf+hmpFrtnpN50vCLdAANKcw==",
- "dependencies": {
- "@chakra-ui/hooks": "1.7.1",
- "@chakra-ui/react-utils": "1.2.1",
- "@chakra-ui/spinner": "1.2.1",
- "@chakra-ui/utils": "1.9.1"
- },
- "peerDependencies": {
- "@chakra-ui/system": ">=1.0.0",
- "react": ">=16.8.6"
- }
- },
- "node_modules/@chakra-ui/checkbox": {
- "version": "1.6.1",
- "resolved": "https://registry.npmjs.org/@chakra-ui/checkbox/-/checkbox-1.6.1.tgz",
- "integrity": "sha512-Z5ZMeUYIRjRbi/knhYhSQshZH7OnROA7ezl9a9oVSKRF7iLMNMibQSlQLXmqUWaTKSgrS37cpKAzfgEuemyiUQ==",
- "dependencies": {
- "@chakra-ui/hooks": "1.7.1",
- "@chakra-ui/react-utils": "1.2.1",
- "@chakra-ui/utils": "1.9.1",
- "@chakra-ui/visually-hidden": "1.1.1"
- },
- "peerDependencies": {
- "@chakra-ui/system": ">=1.0.0",
- "framer-motion": "3.x || 4.x || 5.x",
- "react": ">=16.8.6"
- }
- },
- "node_modules/@chakra-ui/clickable": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/@chakra-ui/clickable/-/clickable-1.2.1.tgz",
- "integrity": "sha512-B0CIbKzDMwzG1APeTpW9H2Jl8dkarI1Qstb3hDOy23O+N5TU6lpDdVnXQ7fpFJS6mu5JjFqtkwzGAVZnkkv1rw==",
- "dependencies": {
- "@chakra-ui/react-utils": "1.2.1",
- "@chakra-ui/utils": "1.9.1"
- },
- "peerDependencies": {
- "react": ">=16.8.6"
- }
- },
- "node_modules/@chakra-ui/close-button": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/@chakra-ui/close-button/-/close-button-1.2.2.tgz",
- "integrity": "sha512-SqeLib0qgMjK3OsO1g5OnAHUmdCC8GMjToNEea7TeSrA44bH9EXVhFTkMMu2PnDVHbQmi4Ee1cuulNJt0UhQ3g==",
- "dependencies": {
- "@chakra-ui/icon": "2.0.0",
- "@chakra-ui/utils": "1.9.1"
- },
- "peerDependencies": {
- "@chakra-ui/system": ">=1.0.0",
- "react": ">=16.8.6"
- }
- },
- "node_modules/@chakra-ui/color-mode": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/@chakra-ui/color-mode/-/color-mode-1.3.2.tgz",
- "integrity": "sha512-/rWcbrzbaWCyyUnT07Qjz0xf/ltHS31CHOKtVCWr2uTgfn2gOQpdxsKRbjrLYPOYZGTMdINUHNiAsqQjLoAoTQ==",
- "dependencies": {
- "@chakra-ui/hooks": "1.7.1",
- "@chakra-ui/react-env": "1.1.1",
- "@chakra-ui/utils": "1.9.1"
- },
- "peerDependencies": {
- "react": ">=16.8.6"
- }
- },
- "node_modules/@chakra-ui/control-box": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@chakra-ui/control-box/-/control-box-1.1.1.tgz",
- "integrity": "sha512-ZFbh85pzzZoiSjGnvLUzMB5BoA8Xm6TBMWvMtzLY5xiFGb9/mBeRDH2KFjr1GJzoqleWKkQwvFD6JM0kXcekpg==",
- "dependencies": {
- "@chakra-ui/utils": "1.9.1"
- },
- "peerDependencies": {
- "@chakra-ui/system": ">=1.0.0",
- "react": ">=16.8.6"
- }
- },
- "node_modules/@chakra-ui/counter": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/@chakra-ui/counter/-/counter-1.2.1.tgz",
- "integrity": "sha512-Gm4njMzEsDyAzdQtExn40TvmupzkPBrT5DiCu0DlxYqpLqCfqV49HgJHEG5oW3WV+WaC9mzg7VV+idKYh/d+Gg==",
- "dependencies": {
- "@chakra-ui/hooks": "1.7.1",
- "@chakra-ui/utils": "1.9.1"
- },
- "peerDependencies": {
- "react": ">=16.8.6"
- }
- },
- "node_modules/@chakra-ui/css-reset": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@chakra-ui/css-reset/-/css-reset-1.1.1.tgz",
- "integrity": "sha512-+KNNHL4OWqeKia5SL858K3Qbd8WxMij9mWIilBzLD4j2KFrl/+aWFw8syMKth3NmgIibrjsljo+PU3fy2o50dg==",
- "peerDependencies": {
- "@emotion/react": ">=10.0.35",
- "react": ">=16.8.6"
- }
- },
- "node_modules/@chakra-ui/descendant": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/@chakra-ui/descendant/-/descendant-2.1.1.tgz",
- "integrity": "sha512-JasdVaN4MjL7QFo1vMnADy6EtFAlPKT1kTJ1LwMtl9AaF9VFLBsfGxm0L+WQK+3NJMuCSDBXWJB8mV4AQ11Edg==",
- "dependencies": {
- "@chakra-ui/react-utils": "^1.2.1"
- },
- "peerDependencies": {
- "react": ">=16.8.6"
- }
- },
- "node_modules/@chakra-ui/editable": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/@chakra-ui/editable/-/editable-1.3.1.tgz",
- "integrity": "sha512-MwyTtsnHNqmKmHv9SH3KIHWa06D4gBwcuTawTiSnYBUJL6My8ry/Wdca1to9So2tD6hcjz3TPTzOJOlyv0eiZg==",
- "dependencies": {
- "@chakra-ui/hooks": "1.7.1",
- "@chakra-ui/react-utils": "1.2.1",
- "@chakra-ui/utils": "1.9.1"
- },
- "peerDependencies": {
- "@chakra-ui/system": ">=1.0.0",
- "react": ">=16.8.6"
- }
- },
- "node_modules/@chakra-ui/focus-lock": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/@chakra-ui/focus-lock/-/focus-lock-1.2.1.tgz",
- "integrity": "sha512-HYu39nvfaXUrBx+dIDJkFgebNCGEi9oZTfLUKzIJC+zPkmReTDSXV0dzSb/8vCAOq5fph1gFKsdbGy2U98P8GQ==",
- "dependencies": {
- "@chakra-ui/utils": "1.9.1",
- "react-focus-lock": "2.5.2"
- },
- "peerDependencies": {
- "react": ">=16.8.6"
- }
- },
- "node_modules/@chakra-ui/form-control": {
- "version": "1.5.2",
- "resolved": "https://registry.npmjs.org/@chakra-ui/form-control/-/form-control-1.5.2.tgz",
- "integrity": "sha512-uWv0/f+JEM0ZE5Hnj3TzCnJ09EB+A+DSs9QgyECOuxx9Ju6gnns2uaRki2BfxksQL9ZZomPCkMtXazY9Wa81ag==",
- "dependencies": {
- "@chakra-ui/hooks": "1.7.1",
- "@chakra-ui/icon": "2.0.0",
- "@chakra-ui/react-utils": "1.2.1",
- "@chakra-ui/utils": "1.9.1"
- },
- "peerDependencies": {
- "@chakra-ui/system": ">=1.0.0",
- "react": ">=16.8.6"
- }
- },
- "node_modules/@chakra-ui/hooks": {
- "version": "1.7.1",
- "resolved": "https://registry.npmjs.org/@chakra-ui/hooks/-/hooks-1.7.1.tgz",
- "integrity": "sha512-hgN19X6GUKQYAHczmFY+GAT8vl9h+X+nGWrIAnmvZ6BgUXxDajnTNhZeWhj0ZkR+7A7dCE6Y/3X44GafUgChMw==",
- "dependencies": {
- "@chakra-ui/react-utils": "1.2.1",
- "@chakra-ui/utils": "1.9.1",
- "compute-scroll-into-view": "1.0.14",
- "copy-to-clipboard": "3.3.1"
- },
- "peerDependencies": {
- "react": ">=16.8.6"
- }
- },
- "node_modules/@chakra-ui/icon": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@chakra-ui/icon/-/icon-2.0.0.tgz",
- "integrity": "sha512-/GuU+xIcOIy9uSUUUCu249ZJB/nLDbjWGkfpoSdBwqT4+ytJrKt+0Ckh3Ub14sz3BJD+Z6IiIt6ySOA9+7lbsA==",
- "dependencies": {
- "@chakra-ui/utils": "1.9.1"
- },
- "peerDependencies": {
- "@chakra-ui/system": ">=1.0.0",
- "react": ">=16.8.6"
- }
- },
- "node_modules/@chakra-ui/image": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@chakra-ui/image/-/image-1.1.1.tgz",
- "integrity": "sha512-bz1pn08XlXcO3r1KnpdjQgN3R2soiTx10sG2d5Pw9BdGdySf7Y73wiLh+Tan1xJHp6p2KH1hz4f7uKXXDn7Qmw==",
- "dependencies": {
- "@chakra-ui/hooks": "1.7.1",
- "@chakra-ui/utils": "1.9.1"
- },
- "peerDependencies": {
- "@chakra-ui/system": ">=1.0.0",
- "react": ">=16.8.6"
- }
- },
- "node_modules/@chakra-ui/input": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/@chakra-ui/input/-/input-1.3.2.tgz",
- "integrity": "sha512-VMxmQgFiQ2UnBlkgLX/336G0IfYfw8YWF2ZoEFj5WL9kDSrrL1FXSBgjFGxrper74G4W20tESBCfU1S891y6cg==",
- "dependencies": {
- "@chakra-ui/form-control": "1.5.2",
- "@chakra-ui/react-utils": "1.2.1",
- "@chakra-ui/utils": "1.9.1"
- },
- "peerDependencies": {
- "@chakra-ui/system": ">=1.0.0",
- "react": ">=16.8.6"
- }
- },
- "node_modules/@chakra-ui/layout": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/@chakra-ui/layout/-/layout-1.6.0.tgz",
- "integrity": "sha512-WUfQ104y1wNueU33/hPlZsMzYJGjO0dXMpVkQf5ZNhNX3IGDO+5+MO2x2xloP+j45yNPi3p8ti/HBnm3dXI+3Q==",
- "dependencies": {
- "@chakra-ui/icon": "2.0.0",
- "@chakra-ui/react-utils": "1.2.1",
- "@chakra-ui/utils": "1.9.1"
- },
- "peerDependencies": {
- "@chakra-ui/system": ">=1.0.0",
- "react": ">=16.8.6"
- }
- },
- "node_modules/@chakra-ui/live-region": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@chakra-ui/live-region/-/live-region-1.1.1.tgz",
- "integrity": "sha512-BSdI5gLIffNRETEp6W18kBNg9tL0ZLLzfWGRnuO9tEbox7NrcgqIeLF8mNKwhDOZz88NKHtUOPVzjAUKW1SryQ==",
- "dependencies": {
- "@chakra-ui/utils": "1.9.1"
- },
- "peerDependencies": {
- "react": ">=16.8.6"
- }
- },
- "node_modules/@chakra-ui/media-query": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/@chakra-ui/media-query/-/media-query-1.2.2.tgz",
- "integrity": "sha512-xSmDVleE1drWiGH/MX3RqyVm29x/8Vf6G0UGaI2kCpbNmon+Q1zHW/yDHvptIuctLrPHYO8LOBxuUjfnIXwC2g==",
- "dependencies": {
- "@chakra-ui/react-env": "1.1.1",
- "@chakra-ui/utils": "1.9.1"
- },
- "peerDependencies": {
- "@chakra-ui/system": ">=1.0.0",
- "@chakra-ui/theme": ">=1.0.0",
- "react": ">=16.8.6"
- }
- },
- "node_modules/@chakra-ui/menu": {
- "version": "1.8.2",
- "resolved": "https://registry.npmjs.org/@chakra-ui/menu/-/menu-1.8.2.tgz",
- "integrity": "sha512-u2GfkwTqbWa8L/7i/kOFbU3JANiT2HStR+gsYKuiuOPiuBcUb8OlgfJfP70OtVKegNKmVEMjvzXtld3wCCo/1g==",
- "dependencies": {
- "@chakra-ui/clickable": "1.2.1",
- "@chakra-ui/descendant": "2.1.1",
- "@chakra-ui/hooks": "1.7.1",
- "@chakra-ui/popper": "2.4.1",
- "@chakra-ui/react-utils": "1.2.1",
- "@chakra-ui/transition": "1.4.2",
- "@chakra-ui/utils": "1.9.1"
- },
- "peerDependencies": {
- "@chakra-ui/system": ">=1.0.0",
- "framer-motion": "3.x || 4.x || 5.x",
- "react": ">=16.8.6"
- }
- },
- "node_modules/@chakra-ui/modal": {
- "version": "1.10.2",
- "resolved": "https://registry.npmjs.org/@chakra-ui/modal/-/modal-1.10.2.tgz",
- "integrity": "sha512-ZlmYetPHwHW4CAM09j4/+Ui54dXR1nzU6mOwhWe4/IzLvEyoEU6fHJeKyGxVUpYTG/7wltG/wKFRJpYa77tiBg==",
- "dependencies": {
- "@chakra-ui/close-button": "1.2.2",
- "@chakra-ui/focus-lock": "1.2.1",
- "@chakra-ui/hooks": "1.7.1",
- "@chakra-ui/portal": "1.3.1",
- "@chakra-ui/react-utils": "1.2.1",
- "@chakra-ui/transition": "1.4.2",
- "@chakra-ui/utils": "1.9.1",
- "aria-hidden": "^1.1.1",
- "react-remove-scroll": "2.4.1"
- },
- "peerDependencies": {
- "@chakra-ui/system": ">=1.0.0",
- "framer-motion": "3.x || 4.x || 5.x",
- "react": ">=16.8.6",
- "react-dom": ">=16.8.6"
- }
- },
- "node_modules/@chakra-ui/number-input": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/@chakra-ui/number-input/-/number-input-1.3.2.tgz",
- "integrity": "sha512-7x7AoqwPXU1odyDcqIwjBwf0MJUwYMM2fa+6YZ52F941GKlvkDiiJOhK6xfhhBzkLUQD6DN8zgAmmGhaZ6UQXw==",
- "dependencies": {
- "@chakra-ui/counter": "1.2.1",
- "@chakra-ui/form-control": "1.5.2",
- "@chakra-ui/hooks": "1.7.1",
- "@chakra-ui/icon": "2.0.0",
- "@chakra-ui/react-utils": "1.2.1",
- "@chakra-ui/utils": "1.9.1"
- },
- "peerDependencies": {
- "@chakra-ui/system": ">=1.0.0",
- "react": ">=16.8.6"
- }
- },
- "node_modules/@chakra-ui/pin-input": {
- "version": "1.7.1",
- "resolved": "https://registry.npmjs.org/@chakra-ui/pin-input/-/pin-input-1.7.1.tgz",
- "integrity": "sha512-eFFc5sofiyion+NxELWfCzD23XHIBDrJcfKKbNxt8jdXg9Ek4mFpmvnxBVrK0DIz6cVYgKY8c364OmxNUf4IyA==",
- "dependencies": {
- "@chakra-ui/descendant": "2.1.1",
- "@chakra-ui/hooks": "1.7.1",
- "@chakra-ui/react-utils": "1.2.1",
- "@chakra-ui/utils": "1.9.1"
- },
- "peerDependencies": {
- "@chakra-ui/system": ">=1.0.0",
- "react": ">=16.8.6"
- }
- },
- "node_modules/@chakra-ui/popover": {
- "version": "1.11.0",
- "resolved": "https://registry.npmjs.org/@chakra-ui/popover/-/popover-1.11.0.tgz",
- "integrity": "sha512-cCHXAfhIRir+M0ehlYIjDw3mHpiCxDTJ9WV0H1zHQV8nDYVIlZw3nEntaq8oJrv0wpIzq2WCW5ss+bBR7nLZ1A==",
- "dependencies": {
- "@chakra-ui/close-button": "1.2.2",
- "@chakra-ui/hooks": "1.7.1",
- "@chakra-ui/popper": "2.4.1",
- "@chakra-ui/react-utils": "1.2.1",
- "@chakra-ui/utils": "1.9.1"
- },
- "peerDependencies": {
- "@chakra-ui/system": ">=1.0.0",
- "framer-motion": "3.x || 4.x || 5.x",
- "react": ">=16.8.6"
- }
- },
- "node_modules/@chakra-ui/popper": {
- "version": "2.4.1",
- "resolved": "https://registry.npmjs.org/@chakra-ui/popper/-/popper-2.4.1.tgz",
- "integrity": "sha512-cuwnwXx6RUXZGGynVOGG8fEIiMNBXUCy3UqWQD1eEd8200eWQobgNk4Z0YwzKuSzJwp0Auy+j5iKefi5FSkyog==",
- "dependencies": {
- "@chakra-ui/react-utils": "1.2.1",
- "@popperjs/core": "^2.9.3"
- },
- "peerDependencies": {
- "react": ">=16.8.6"
- }
- },
- "node_modules/@chakra-ui/portal": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/@chakra-ui/portal/-/portal-1.3.1.tgz",
- "integrity": "sha512-6UOGZCfujgdijcPs/JTEY5IB5WtKvUbfrSQYsG5CDa+guIwvnoP5qZ+rH6BR6DSSM8Wr/1n+WrtanhfFZShHKA==",
- "dependencies": {
- "@chakra-ui/hooks": "1.7.1",
- "@chakra-ui/react-utils": "1.2.1",
- "@chakra-ui/utils": "1.9.1"
- },
- "peerDependencies": {
- "react": ">=16.8.6",
- "react-dom": ">=16.8.6"
- }
- },
- "node_modules/@chakra-ui/progress": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/@chakra-ui/progress/-/progress-1.2.1.tgz",
- "integrity": "sha512-213nN8nbODvD/A23vAtg+r3bRKKatWQHafgmLzeznUcxa/+ac0eVurIS8XSYLRkY4EXQ505re3ZkLhDd98a7QA==",
- "dependencies": {
- "@chakra-ui/theme-tools": "1.3.1",
- "@chakra-ui/utils": "1.9.1"
- },
- "peerDependencies": {
- "@chakra-ui/system": ">=1.0.0",
- "react": ">=16.8.6"
- }
- },
- "node_modules/@chakra-ui/provider": {
- "version": "1.7.3",
- "resolved": "https://registry.npmjs.org/@chakra-ui/provider/-/provider-1.7.3.tgz",
- "integrity": "sha512-D1SrQ7do4yzAv9/OTF3yj/BkLm7kFo5DdeuOCyvXGpVJumnvbtjltRmC7rFQH4R+y9qXPvfQP4LKMNBqSxPNng==",
- "dependencies": {
- "@chakra-ui/css-reset": "1.1.1",
- "@chakra-ui/hooks": "1.7.1",
- "@chakra-ui/portal": "1.3.1",
- "@chakra-ui/react-env": "1.1.1",
- "@chakra-ui/system": "1.8.3",
- "@chakra-ui/utils": "1.9.1"
- },
- "peerDependencies": {
- "@emotion/react": "^11.0.0",
- "@emotion/styled": "^11.0.0",
- "react": ">=16.8.6",
- "react-dom": ">=16.8.6"
- }
- },
- "node_modules/@chakra-ui/radio": {
- "version": "1.4.3",
- "resolved": "https://registry.npmjs.org/@chakra-ui/radio/-/radio-1.4.3.tgz",
- "integrity": "sha512-TQdyfdUD3BLklOP67n82JN8ksQv1BYjvaYsK0m6WCa0LDJr9aCC+XtUPgVq/1L2t4HqHdiGOrGBooF4vvy/+BA==",
- "dependencies": {
- "@chakra-ui/form-control": "1.5.2",
- "@chakra-ui/hooks": "1.7.1",
- "@chakra-ui/react-utils": "1.2.1",
- "@chakra-ui/utils": "1.9.1",
- "@chakra-ui/visually-hidden": "1.1.1"
- },
- "peerDependencies": {
- "@chakra-ui/system": ">=1.0.0",
- "react": ">=16.8.6"
- }
- },
- "node_modules/@chakra-ui/react": {
- "version": "1.7.3",
- "resolved": "https://registry.npmjs.org/@chakra-ui/react/-/react-1.7.3.tgz",
- "integrity": "sha512-6mrfDUOa9MoQ44Xvi7xgdDq48jTTTjW9BupCGf2R3DI+z6RbUKIHzbcoDJZt2HGY6j9EarMVNRoQJzvzGUKpoQ==",
- "dependencies": {
- "@chakra-ui/accordion": "1.4.2",
- "@chakra-ui/alert": "1.3.2",
- "@chakra-ui/avatar": "1.3.1",
- "@chakra-ui/breadcrumb": "1.3.1",
- "@chakra-ui/button": "1.5.1",
- "@chakra-ui/checkbox": "1.6.1",
- "@chakra-ui/close-button": "1.2.2",
- "@chakra-ui/control-box": "1.1.1",
- "@chakra-ui/counter": "1.2.1",
- "@chakra-ui/css-reset": "1.1.1",
- "@chakra-ui/editable": "1.3.1",
- "@chakra-ui/form-control": "1.5.2",
- "@chakra-ui/hooks": "1.7.1",
- "@chakra-ui/icon": "2.0.0",
- "@chakra-ui/image": "1.1.1",
- "@chakra-ui/input": "1.3.2",
- "@chakra-ui/layout": "1.6.0",
- "@chakra-ui/live-region": "1.1.1",
- "@chakra-ui/media-query": "1.2.2",
- "@chakra-ui/menu": "1.8.2",
- "@chakra-ui/modal": "1.10.2",
- "@chakra-ui/number-input": "1.3.2",
- "@chakra-ui/pin-input": "1.7.1",
- "@chakra-ui/popover": "1.11.0",
- "@chakra-ui/popper": "2.4.1",
- "@chakra-ui/portal": "1.3.1",
- "@chakra-ui/progress": "1.2.1",
- "@chakra-ui/provider": "1.7.3",
- "@chakra-ui/radio": "1.4.3",
- "@chakra-ui/react-env": "1.1.1",
- "@chakra-ui/select": "1.2.2",
- "@chakra-ui/skeleton": "1.2.3",
- "@chakra-ui/slider": "1.5.2",
- "@chakra-ui/spinner": "1.2.1",
- "@chakra-ui/stat": "1.2.2",
- "@chakra-ui/switch": "1.3.1",
- "@chakra-ui/system": "1.8.3",
- "@chakra-ui/table": "1.3.1",
- "@chakra-ui/tabs": "1.6.1",
- "@chakra-ui/tag": "1.2.2",
- "@chakra-ui/textarea": "1.2.2",
- "@chakra-ui/theme": "1.12.2",
- "@chakra-ui/toast": "1.5.0",
- "@chakra-ui/tooltip": "1.4.2",
- "@chakra-ui/transition": "1.4.2",
- "@chakra-ui/utils": "1.9.1",
- "@chakra-ui/visually-hidden": "1.1.1"
- },
- "peerDependencies": {
- "@emotion/react": "^11.0.0",
- "@emotion/styled": "^11.0.0",
- "framer-motion": "3.x || 4.x || 5.x",
- "react": ">=16.8.6",
- "react-dom": ">=16.8.6"
- }
- },
- "node_modules/@chakra-ui/react-env": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@chakra-ui/react-env/-/react-env-1.1.1.tgz",
- "integrity": "sha512-Lgmb0y4kv0ffsGMelAOaYOd4tYZAv4FYWgV86ckGMjmYQWA8drv4v/lHTNltixxWMmBEpjcHALpJuS6yAZYHug==",
- "dependencies": {
- "@chakra-ui/utils": "1.9.1"
- },
- "peerDependencies": {
- "react": ">=16.8.6"
- }
- },
- "node_modules/@chakra-ui/react-utils": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/@chakra-ui/react-utils/-/react-utils-1.2.1.tgz",
- "integrity": "sha512-bV8FRaXiOgGxOg03iTNin/B02I+tHH9PQtqUTl3U7cJaoI+5AUYhrqXvl1Ya2/R7zxSFrb/gBVDTgbZiVkJ+Dg==",
- "dependencies": {
- "@chakra-ui/utils": "^1.9.1"
- },
- "peerDependencies": {
- "react": ">=16.8.6"
- }
- },
- "node_modules/@chakra-ui/select": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/@chakra-ui/select/-/select-1.2.2.tgz",
- "integrity": "sha512-EchJW3St1DtSWHe//DHwKjGsQYL2zbKcNCLnJWQKGMPZsQhAD2wsm4xjowFrV8AkY7jbVM/U2v68puN7YTC3hg==",
- "dependencies": {
- "@chakra-ui/form-control": "1.5.2",
- "@chakra-ui/utils": "1.9.1"
- },
- "peerDependencies": {
- "@chakra-ui/system": ">=1.0.0",
- "react": ">=16.8.6"
- }
- },
- "node_modules/@chakra-ui/skeleton": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/@chakra-ui/skeleton/-/skeleton-1.2.3.tgz",
- "integrity": "sha512-u5ASkzPiBjfvKxKuBienUfmyYDTHziSWQ8Ny6k83LbwLv9IcmBNGsSkmsp7hesgi9cMHGBQ3hY2GTqG9ljndIg==",
- "dependencies": {
- "@chakra-ui/hooks": "1.7.1",
- "@chakra-ui/media-query": "1.2.2",
- "@chakra-ui/system": "1.8.3",
- "@chakra-ui/utils": "1.9.1"
- },
- "peerDependencies": {
- "react": ">=16.8.6"
- }
- },
- "node_modules/@chakra-ui/slider": {
- "version": "1.5.2",
- "resolved": "https://registry.npmjs.org/@chakra-ui/slider/-/slider-1.5.2.tgz",
- "integrity": "sha512-zP07TMew61GkJe47Nu7zEg/SUEwPHpN4alW6VUM6Y8UaVpQaDx7InarbWTc/bXdTP03SfE+hQ6WD9Oy7noe4hQ==",
- "dependencies": {
- "@chakra-ui/hooks": "1.7.1",
- "@chakra-ui/react-utils": "1.2.1",
- "@chakra-ui/utils": "1.9.1"
- },
- "peerDependencies": {
- "@chakra-ui/system": ">=1.0.0",
- "react": ">=16.8.6"
- }
- },
- "node_modules/@chakra-ui/spinner": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/@chakra-ui/spinner/-/spinner-1.2.1.tgz",
- "integrity": "sha512-CQsUJNJWWSot1ku5Se41Nz1dXIDhk+/7FIhTbfRHSjtYZnAab3CPMHBkTGqwbJxQ9oHYgk9Rso3cfG+/ra6aTQ==",
- "dependencies": {
- "@chakra-ui/utils": "1.9.1",
- "@chakra-ui/visually-hidden": "1.1.1"
- },
- "peerDependencies": {
- "@chakra-ui/system": ">=1.0.0",
- "react": ">=16.8.6"
- }
- },
- "node_modules/@chakra-ui/stat": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/@chakra-ui/stat/-/stat-1.2.2.tgz",
- "integrity": "sha512-0StsPDC56MjzhdlBl0R8wU0uwj9L1tvhQzge/ELSDn4tQDI7VovrxpFzVH0qsj7EZDwZa0BRQaSrstzWvgmJ/Q==",
- "dependencies": {
- "@chakra-ui/icon": "2.0.0",
- "@chakra-ui/utils": "1.9.1",
- "@chakra-ui/visually-hidden": "1.1.1"
- },
- "peerDependencies": {
- "@chakra-ui/system": ">=1.0.0",
- "react": ">=16.8.6"
- }
- },
- "node_modules/@chakra-ui/styled-system": {
- "version": "1.15.0",
- "resolved": "https://registry.npmjs.org/@chakra-ui/styled-system/-/styled-system-1.15.0.tgz",
- "integrity": "sha512-LnsKeiYkUuJ+NMTwueiX0Mj8CW9XAMJrJxpQm/X3GY5L5PO7Hv6wW725Ovqdy4mhG3IK7S8444FthpsDv/luHw==",
- "dependencies": {
- "@chakra-ui/utils": "1.9.1",
- "csstype": "^3.0.9"
- }
- },
- "node_modules/@chakra-ui/switch": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/@chakra-ui/switch/-/switch-1.3.1.tgz",
- "integrity": "sha512-92hXJ2/ozj7B3cJNT259mFNoad7Ck892uHTuEQ/GIdXb25doE6F1wCp0TreOnGiEgU5YSaxpdrcZjA0QODP//w==",
- "dependencies": {
- "@chakra-ui/checkbox": "1.6.1",
- "@chakra-ui/utils": "1.9.1"
- },
- "peerDependencies": {
- "@chakra-ui/system": ">=1.0.0",
- "react": ">=16.8.6"
- }
- },
- "node_modules/@chakra-ui/system": {
- "version": "1.8.3",
- "resolved": "https://registry.npmjs.org/@chakra-ui/system/-/system-1.8.3.tgz",
- "integrity": "sha512-6MaevsT7A2ifgOGQQCQsfvzPVd0kEXqFrX1Oxd842bawaqthmbFdo2bBTdaia/+Ivq/8Xot2uAQSbU+3NuRiUA==",
- "dependencies": {
- "@chakra-ui/color-mode": "1.3.2",
- "@chakra-ui/react-utils": "1.2.1",
- "@chakra-ui/styled-system": "1.15.0",
- "@chakra-ui/utils": "1.9.1",
- "react-fast-compare": "3.2.0"
- },
- "peerDependencies": {
- "@emotion/react": "^11.0.0",
- "@emotion/styled": "^11.0.0",
- "react": ">=16.8.6"
- }
- },
- "node_modules/@chakra-ui/table": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/@chakra-ui/table/-/table-1.3.1.tgz",
- "integrity": "sha512-+ia/7zs7AGj01lon301EEx+mK4918yGc0K6e68Kxomex8tnxkwbskFWs6hX+6Kzbj56ZBm99eLlKpo2iGYX0HA==",
- "dependencies": {
- "@chakra-ui/utils": "1.9.1"
- },
- "peerDependencies": {
- "@chakra-ui/system": ">=1.0.0",
- "react": ">=16.8.6"
- }
- },
- "node_modules/@chakra-ui/tabs": {
- "version": "1.6.1",
- "resolved": "https://registry.npmjs.org/@chakra-ui/tabs/-/tabs-1.6.1.tgz",
- "integrity": "sha512-p7HdHcleJWNwteWYVPt2KF52YbS5pIIfs/IpgtnYZRsJbqvRVxSwgg5Wsn+vuxFXBKW0cA2rDGbyzsZ+ChtEXQ==",
- "dependencies": {
- "@chakra-ui/clickable": "1.2.1",
- "@chakra-ui/descendant": "2.1.1",
- "@chakra-ui/hooks": "1.7.1",
- "@chakra-ui/react-utils": "1.2.1",
- "@chakra-ui/utils": "1.9.1"
- },
- "peerDependencies": {
- "@chakra-ui/system": ">=1.0.0",
- "react": ">=16.8.6"
- }
- },
- "node_modules/@chakra-ui/tag": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/@chakra-ui/tag/-/tag-1.2.2.tgz",
- "integrity": "sha512-H25y9nEyUAUdwQDND9P4mMXKf1wf9UH4A3DyP237qVKIyYBpa4aCH8eJU4dunh2yIzASB0DWcr7lsul/HAHxmg==",
- "dependencies": {
- "@chakra-ui/icon": "2.0.0",
- "@chakra-ui/utils": "1.9.1"
- },
- "peerDependencies": {
- "@chakra-ui/system": ">=1.0.0",
- "react": ">=16.8.6"
- }
- },
- "node_modules/@chakra-ui/textarea": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/@chakra-ui/textarea/-/textarea-1.2.2.tgz",
- "integrity": "sha512-DoLdKxHk0DyrQDnj1la9wjl2AW3/SK62nfWDYLAm0ouFsw1VKPw9nU+Yyj0dPruQTzI19nLaYF26i97rtnT27g==",
- "dependencies": {
- "@chakra-ui/form-control": "1.5.2",
- "@chakra-ui/utils": "1.9.1"
- },
- "peerDependencies": {
- "@chakra-ui/system": ">=1.0.0",
- "react": ">=16.8.6"
- }
- },
- "node_modules/@chakra-ui/theme": {
- "version": "1.12.2",
- "resolved": "https://registry.npmjs.org/@chakra-ui/theme/-/theme-1.12.2.tgz",
- "integrity": "sha512-LVjSf16yYHD40ILrsDEd3idVQRvJSY7JY8lvTGWo2p6v+JQESWF+zXlYi9Le+TXRpZuFvJuuQ1SEvoqVwdcJ8Q==",
- "dependencies": {
- "@chakra-ui/anatomy": "1.2.1",
- "@chakra-ui/theme-tools": "1.3.1",
- "@chakra-ui/utils": "1.9.1"
- },
- "peerDependencies": {
- "@chakra-ui/system": ">=1.0.0"
- }
- },
- "node_modules/@chakra-ui/theme-tools": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/@chakra-ui/theme-tools/-/theme-tools-1.3.1.tgz",
- "integrity": "sha512-D8arJ5uFGuYZrrFGpXqgov8FhsJYWRyar5oBZY5TJR9gsVYBlJ8Ai91pwM/NflCFqzerTOgyt7bNSGQMdZ8ghA==",
- "dependencies": {
- "@chakra-ui/utils": "1.9.1",
- "@ctrl/tinycolor": "^3.4.0"
- },
- "peerDependencies": {
- "@chakra-ui/system": ">=1.0.0"
- }
- },
- "node_modules/@chakra-ui/toast": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/@chakra-ui/toast/-/toast-1.5.0.tgz",
- "integrity": "sha512-rTsFx/Qos5oVPN6aZMbT/wTxwZlFNSXQqrTpJYaRcRFQGzxIDDxmGkKYfPnyJjRP9i6EqynJhXEIyhMA0xO0dw==",
- "dependencies": {
- "@chakra-ui/alert": "1.3.2",
- "@chakra-ui/close-button": "1.2.2",
- "@chakra-ui/hooks": "1.7.1",
- "@chakra-ui/theme": "1.12.2",
- "@chakra-ui/transition": "1.4.2",
- "@chakra-ui/utils": "1.9.1",
- "@reach/alert": "0.13.2"
- },
- "peerDependencies": {
- "@chakra-ui/system": ">=1.0.0",
- "framer-motion": "3.x || 4.x || 5.x",
- "react": ">=16.8.6",
- "react-dom": ">=16.8.6"
- }
- },
- "node_modules/@chakra-ui/tooltip": {
- "version": "1.4.2",
- "resolved": "https://registry.npmjs.org/@chakra-ui/tooltip/-/tooltip-1.4.2.tgz",
- "integrity": "sha512-+wyYXG8qenKkFy2YSFfOBf3rlWADnu6S9EUxP+3Rmm78unOWXDuTJWzqy2QlXs2BwoQoifaz1LVwzmMb7WLVgQ==",
- "dependencies": {
- "@chakra-ui/hooks": "1.7.1",
- "@chakra-ui/popper": "2.4.1",
- "@chakra-ui/portal": "1.3.1",
- "@chakra-ui/react-utils": "1.2.1",
- "@chakra-ui/utils": "1.9.1",
- "@chakra-ui/visually-hidden": "1.1.1"
- },
- "peerDependencies": {
- "@chakra-ui/system": ">=1.0.0",
- "framer-motion": "3.x || 4.x || 5.x",
- "react": ">=16.8.6",
- "react-dom": ">=16.8.6"
- }
- },
- "node_modules/@chakra-ui/transition": {
- "version": "1.4.2",
- "resolved": "https://registry.npmjs.org/@chakra-ui/transition/-/transition-1.4.2.tgz",
- "integrity": "sha512-S+BNmpErHlntl//uaqv0sJegzMsQms0OnJapeZaRsvZL4s1SVYrR8kMrXigkdpeh4lAUqGsLpQHPKkzaKGbBOw==",
- "dependencies": {
- "@chakra-ui/utils": "1.9.1"
- },
- "peerDependencies": {
- "framer-motion": "3.x || 4.x || 5.x",
- "react": ">=16.8.6"
- }
- },
- "node_modules/@chakra-ui/utils": {
- "version": "1.9.1",
- "resolved": "https://registry.npmjs.org/@chakra-ui/utils/-/utils-1.9.1.tgz",
- "integrity": "sha512-Tue8JfpzOqeHd8vSqAnX1l/Y3Gg456+BXFP/TH6mCIeqMAMbrvv25vDskds0wlXRjMYdmpqHxCEzkalFrscGHA==",
- "dependencies": {
- "@types/lodash.mergewith": "4.6.6",
- "css-box-model": "1.2.1",
- "framesync": "5.3.0",
- "lodash.mergewith": "4.6.2"
- }
- },
- "node_modules/@chakra-ui/visually-hidden": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@chakra-ui/visually-hidden/-/visually-hidden-1.1.1.tgz",
- "integrity": "sha512-AGK9YBQS2FW/1e5tfivS8VVXn8y2uTyJ9ACOnGiLm9FNdth9pR0fGil9axlcmhZpEYcSRlnCuma3nkqaCjJnAA==",
- "dependencies": {
- "@chakra-ui/utils": "1.9.1"
- },
- "peerDependencies": {
- "@chakra-ui/system": ">=1.0.0",
- "react": ">=16.8.6"
- }
- },
- "node_modules/@ctrl/tinycolor": {
- "version": "3.4.0",
- "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.4.0.tgz",
- "integrity": "sha512-JZButFdZ1+/xAfpguQHoabIXkcqRRKpMrWKBkpEZZyxfY9C1DpADFB8PEqGSTeFr135SaTRfKqGKx5xSCLI7ZQ==",
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@emotion/babel-plugin": {
- "version": "11.7.2",
- "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.7.2.tgz",
- "integrity": "sha512-6mGSCWi9UzXut/ZAN6lGFu33wGR3SJisNl3c0tvlmb8XChH1b2SUvxvnOh7hvLpqyRdHHU9AiazV3Cwbk5SXKQ==",
- "dependencies": {
- "@babel/helper-module-imports": "^7.12.13",
- "@babel/plugin-syntax-jsx": "^7.12.13",
- "@babel/runtime": "^7.13.10",
- "@emotion/hash": "^0.8.0",
- "@emotion/memoize": "^0.7.5",
- "@emotion/serialize": "^1.0.2",
- "babel-plugin-macros": "^2.6.1",
- "convert-source-map": "^1.5.0",
- "escape-string-regexp": "^4.0.0",
- "find-root": "^1.1.0",
- "source-map": "^0.5.7",
- "stylis": "4.0.13"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0"
- }
- },
- "node_modules/@emotion/cache": {
- "version": "11.7.1",
- "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.7.1.tgz",
- "integrity": "sha512-r65Zy4Iljb8oyjtLeCuBH8Qjiy107dOYC6SJq7g7GV5UCQWMObY4SJDPGFjiiVpPrOJ2hmJOoBiYTC7hwx9E2A==",
- "dependencies": {
- "@emotion/memoize": "^0.7.4",
- "@emotion/sheet": "^1.1.0",
- "@emotion/utils": "^1.0.0",
- "@emotion/weak-memoize": "^0.2.5",
- "stylis": "4.0.13"
- }
- },
- "node_modules/@emotion/core": {
- "version": "11.0.0",
- "resolved": "https://registry.npmjs.org/@emotion/core/-/core-11.0.0.tgz",
- "integrity": "sha512-w4sE3AmHmyG6RDKf6mIbtHpgJUSJ2uGvPQb8VXFL7hFjMPibE8IiehG8cMX3Ztm4svfCQV6KqusQbeIOkurBcA=="
- },
- "node_modules/@emotion/hash": {
- "version": "0.8.0",
- "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz",
- "integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow=="
- },
- "node_modules/@emotion/is-prop-valid": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.1.1.tgz",
- "integrity": "sha512-bW1Tos67CZkOURLc0OalnfxtSXQJMrAMV0jZTVGJUPSOd4qgjF3+tTD5CwJM13PHA8cltGW1WGbbvV9NpvUZPw==",
- "dependencies": {
- "@emotion/memoize": "^0.7.4"
- }
- },
- "node_modules/@emotion/memoize": {
- "version": "0.7.5",
- "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.5.tgz",
- "integrity": "sha512-igX9a37DR2ZPGYtV6suZ6whr8pTFtyHL3K/oLUotxpSVO2ASaprmAe2Dkq7tBo7CRY7MMDrAa9nuQP9/YG8FxQ=="
- },
- "node_modules/@emotion/react": {
- "version": "11.7.1",
- "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.7.1.tgz",
- "integrity": "sha512-DV2Xe3yhkF1yT4uAUoJcYL1AmrnO5SVsdfvu+fBuS7IbByDeTVx9+wFmvx9Idzv7/78+9Mgx2Hcmr7Fex3tIyw==",
- "dependencies": {
- "@babel/runtime": "^7.13.10",
- "@emotion/cache": "^11.7.1",
- "@emotion/serialize": "^1.0.2",
- "@emotion/sheet": "^1.1.0",
- "@emotion/utils": "^1.0.0",
- "@emotion/weak-memoize": "^0.2.5",
- "hoist-non-react-statics": "^3.3.1"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0",
- "react": ">=16.8.0"
- },
- "peerDependenciesMeta": {
- "@babel/core": {
- "optional": true
- },
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/@emotion/serialize": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.0.2.tgz",
- "integrity": "sha512-95MgNJ9+/ajxU7QIAruiOAdYNjxZX7G2mhgrtDWswA21VviYIRP1R5QilZ/bDY42xiKsaktP4egJb3QdYQZi1A==",
- "dependencies": {
- "@emotion/hash": "^0.8.0",
- "@emotion/memoize": "^0.7.4",
- "@emotion/unitless": "^0.7.5",
- "@emotion/utils": "^1.0.0",
- "csstype": "^3.0.2"
- }
- },
- "node_modules/@emotion/sheet": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.1.0.tgz",
- "integrity": "sha512-u0AX4aSo25sMAygCuQTzS+HsImZFuS8llY8O7b9MDRzbJM0kVJlAz6KNDqcG7pOuQZJmj/8X/rAW+66kMnMW+g=="
- },
- "node_modules/@emotion/styled": {
- "version": "11.6.0",
- "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.6.0.tgz",
- "integrity": "sha512-mxVtVyIOTmCAkFbwIp+nCjTXJNgcz4VWkOYQro87jE2QBTydnkiYusMrRGFtzuruiGK4dDaNORk4gH049iiQuw==",
- "dependencies": {
- "@babel/runtime": "^7.13.10",
- "@emotion/babel-plugin": "^11.3.0",
- "@emotion/is-prop-valid": "^1.1.1",
- "@emotion/serialize": "^1.0.2",
- "@emotion/utils": "^1.0.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0",
- "@emotion/react": "^11.0.0-rc.0",
- "react": ">=16.8.0"
- },
- "peerDependenciesMeta": {
- "@babel/core": {
- "optional": true
- },
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/@emotion/unitless": {
- "version": "0.7.5",
- "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz",
- "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg=="
- },
- "node_modules/@emotion/utils": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.0.0.tgz",
- "integrity": "sha512-mQC2b3XLDs6QCW+pDQDiyO/EdGZYOygE8s5N5rrzjSI4M3IejPE/JPndCBwRT9z982aqQNi6beWs1UeayrQxxA=="
- },
- "node_modules/@emotion/weak-memoize": {
- "version": "0.2.5",
- "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz",
- "integrity": "sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA=="
- },
- "node_modules/@graphql-typed-document-node/core": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/@graphql-typed-document-node/core/-/core-3.1.1.tgz",
- "integrity": "sha512-NQ17ii0rK1b34VZonlmT2QMJFI70m0TRwbknO/ihlbatXyaktDhN/98vBiUU6kNBPljqGqyIrl2T4nY2RpFANg==",
- "peerDependencies": {
- "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0"
- }
- },
- "node_modules/@jridgewell/gen-mapping": {
- "version": "0.3.3",
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
- "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
- "peer": true,
- "dependencies": {
- "@jridgewell/set-array": "^1.0.1",
- "@jridgewell/sourcemap-codec": "^1.4.10",
- "@jridgewell/trace-mapping": "^0.3.9"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@jridgewell/resolve-uri": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz",
- "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==",
- "peer": true,
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@jridgewell/set-array": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
- "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
- "peer": true,
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@jridgewell/sourcemap-codec": {
- "version": "1.4.15",
- "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
- "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
- "peer": true
- },
- "node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.20",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz",
- "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==",
- "peer": true,
- "dependencies": {
- "@jridgewell/resolve-uri": "^3.1.0",
- "@jridgewell/sourcemap-codec": "^1.4.14"
- }
- },
- "node_modules/@popperjs/core": {
- "version": "2.11.0",
- "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.0.tgz",
- "integrity": "sha512-zrsUxjLOKAzdewIDRWy9nsV1GQsKBCWaGwsZQlCgr6/q+vjyZhFgqedLfFBuI9anTPEUT4APq9Mu0SZBTzIcGQ==",
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/popperjs"
- }
- },
- "node_modules/@reach/alert": {
- "version": "0.13.2",
- "resolved": "https://registry.npmjs.org/@reach/alert/-/alert-0.13.2.tgz",
- "integrity": "sha512-LDz83AXCrClyq/MWe+0vaZfHp1Ytqn+kgL5VxG7rirUvmluWaj/snxzfNPWn0Ma4K2YENmXXRC/iHt5X95SqIg==",
- "dependencies": {
- "@reach/utils": "0.13.2",
- "@reach/visually-hidden": "0.13.2",
- "prop-types": "^15.7.2",
- "tslib": "^2.1.0"
- },
- "peerDependencies": {
- "react": "^16.8.0 || 17.x",
- "react-dom": "^16.8.0 || 17.x"
- }
- },
- "node_modules/@reach/utils": {
- "version": "0.13.2",
- "resolved": "https://registry.npmjs.org/@reach/utils/-/utils-0.13.2.tgz",
- "integrity": "sha512-3ir6cN60zvUrwjOJu7C6jec/samqAeyAB12ZADK+qjnmQPdzSYldrFWwDVV5H0WkhbYXR3uh+eImu13hCetNPQ==",
- "dependencies": {
- "@types/warning": "^3.0.0",
- "tslib": "^2.1.0",
- "warning": "^4.0.3"
- },
- "peerDependencies": {
- "react": "^16.8.0 || 17.x",
- "react-dom": "^16.8.0 || 17.x"
- }
- },
- "node_modules/@reach/visually-hidden": {
- "version": "0.13.2",
- "resolved": "https://registry.npmjs.org/@reach/visually-hidden/-/visually-hidden-0.13.2.tgz",
- "integrity": "sha512-sPZwNS0/duOuG0mYwE5DmgEAzW9VhgU3aIt1+mrfT/xiT9Cdncqke+kRBQgU708q/Ttm9tWsoHni03nn/SuPTQ==",
- "dependencies": {
- "prop-types": "^15.7.2",
- "tslib": "^2.1.0"
- },
- "peerDependencies": {
- "react": "^16.8.0 || 17.x",
- "react-dom": "^16.8.0 || 17.x"
- }
- },
- "node_modules/@types/history": {
- "version": "4.7.9",
- "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.9.tgz",
- "integrity": "sha512-MUc6zSmU3tEVnkQ78q0peeEjKWPUADMlC/t++2bI8WnAG2tvYRPIgHG8lWkXwqc8MsUF6Z2MOf+Mh5sazOmhiQ=="
- },
- "node_modules/@types/lodash": {
- "version": "4.14.178",
- "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.178.tgz",
- "integrity": "sha512-0d5Wd09ItQWH1qFbEyQ7oTQ3GZrMfth5JkbN3EvTKLXcHLRDSXeLnlvlOn0wvxVIwK5o2M8JzP/OWz7T3NRsbw=="
- },
- "node_modules/@types/lodash.mergewith": {
- "version": "4.6.6",
- "resolved": "https://registry.npmjs.org/@types/lodash.mergewith/-/lodash.mergewith-4.6.6.tgz",
- "integrity": "sha512-RY/8IaVENjG19rxTZu9Nukqh0W2UrYgmBj5sdns4hWRZaV8PqR7wIKHFKzvOTjo4zVRV7sVI+yFhAJql12Kfqg==",
- "dependencies": {
- "@types/lodash": "*"
- }
- },
- "node_modules/@types/parse-json": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
- "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA=="
- },
- "node_modules/@types/prop-types": {
- "version": "15.7.4",
- "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.4.tgz",
- "integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ=="
- },
- "node_modules/@types/react": {
- "version": "17.0.38",
- "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.38.tgz",
- "integrity": "sha512-SI92X1IA+FMnP3qM5m4QReluXzhcmovhZnLNm3pyeQlooi02qI7sLiepEYqT678uNiyc25XfCqxREFpy3W7YhQ==",
- "dependencies": {
- "@types/prop-types": "*",
- "@types/scheduler": "*",
- "csstype": "^3.0.2"
- }
- },
- "node_modules/@types/react-dom": {
- "version": "17.0.11",
- "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.11.tgz",
- "integrity": "sha512-f96K3k+24RaLGVu/Y2Ng3e1EbZ8/cVJvypZWd7cy0ofCBaf2lcM46xNhycMZ2xGwbBjRql7hOlZ+e2WlJ5MH3Q==",
- "dependencies": {
- "@types/react": "*"
- }
- },
- "node_modules/@types/react-email-editor": {
- "version": "1.1.7",
- "resolved": "https://registry.npmjs.org/@types/react-email-editor/-/react-email-editor-1.1.7.tgz",
- "integrity": "sha512-OURTAgaE9pjA6KiU97k13fPdoglI1ZyowUuZ0nu5tTSyrw5PiZoYzYEf9y25YTjmw/ohxT5yqoP0tt+AjSh1qQ==",
- "dev": true,
- "dependencies": {
- "@types/react": "*"
- }
- },
- "node_modules/@types/react-router": {
- "version": "5.1.17",
- "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.17.tgz",
- "integrity": "sha512-RNSXOyb3VyRs/EOGmjBhhGKTbnN6fHWvy5FNLzWfOWOGjgVUKqJZXfpKzLmgoU8h6Hj8mpALj/mbXQASOb92wQ==",
- "dependencies": {
- "@types/history": "*",
- "@types/react": "*"
- }
- },
- "node_modules/@types/react-router-dom": {
- "version": "5.3.2",
- "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.3.2.tgz",
- "integrity": "sha512-ELEYRUie2czuJzaZ5+ziIp9Hhw+juEw8b7C11YNA4QdLCVbQ3qLi2l4aq8XnlqM7V31LZX8dxUuFUCrzHm6sqQ==",
- "dependencies": {
- "@types/history": "*",
- "@types/react": "*",
- "@types/react-router": "*"
- }
- },
- "node_modules/@types/scheduler": {
- "version": "0.16.2",
- "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz",
- "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew=="
- },
- "node_modules/@types/warning": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@types/warning/-/warning-3.0.0.tgz",
- "integrity": "sha1-DSUBJorY+ZYrdA04fEZU9fjiPlI="
- },
- "node_modules/@urql/core": {
- "version": "2.3.6",
- "resolved": "https://registry.npmjs.org/@urql/core/-/core-2.3.6.tgz",
- "integrity": "sha512-PUxhtBh7/8167HJK6WqBv6Z0piuiaZHQGYbhwpNL9aIQmLROPEdaUYkY4wh45wPQXcTpnd11l0q3Pw+TI11pdw==",
- "dependencies": {
- "@graphql-typed-document-node/core": "^3.1.0",
- "wonka": "^4.0.14"
- },
- "peerDependencies": {
- "graphql": "^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0"
- }
- },
- "node_modules/ansi-styles": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
- "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
- "dependencies": {
- "color-convert": "^1.9.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/aria-hidden": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.1.3.tgz",
- "integrity": "sha512-RhVWFtKH5BiGMycI72q2RAFMLQi8JP9bLuQXgR5a8Znp7P5KOIADSJeyfI8PCVxLEp067B2HbP5JIiI/PXIZeA==",
- "dependencies": {
- "tslib": "^1.0.0"
- },
- "engines": {
- "node": ">=8.5.0"
- }
- },
- "node_modules/aria-hidden/node_modules/tslib": {
- "version": "1.14.1",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
- "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
- },
- "node_modules/asap": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
- "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==",
- "peer": true
- },
- "node_modules/attr-accept": {
- "version": "2.2.2",
- "resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-2.2.2.tgz",
- "integrity": "sha512-7prDjvt9HmqiZ0cl5CRjtS84sEyhsHP2coDkaZKRKVfCDo9s7iw7ChVmar78Gu9pC4SoR/28wFu/G5JJhTnqEg==",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/babel-plugin-macros": {
- "version": "2.8.0",
- "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz",
- "integrity": "sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg==",
- "dependencies": {
- "@babel/runtime": "^7.7.2",
- "cosmiconfig": "^6.0.0",
- "resolve": "^1.12.0"
- }
- },
- "node_modules/browserslist": {
- "version": "4.22.1",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz",
- "integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==",
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/browserslist"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/browserslist"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "peer": true,
- "dependencies": {
- "caniuse-lite": "^1.0.30001541",
- "electron-to-chromium": "^1.4.535",
- "node-releases": "^2.0.13",
- "update-browserslist-db": "^1.0.13"
- },
- "bin": {
- "browserslist": "cli.js"
- },
- "engines": {
- "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
- }
- },
- "node_modules/callsites": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
- "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/caniuse-lite": {
- "version": "1.0.30001561",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001561.tgz",
- "integrity": "sha512-NTt0DNoKe958Q0BE0j0c1V9jbUzhBxHIEJy7asmGrpE0yG63KTV7PLHPnK2E1O9RsQrQ081I3NLuXGS6zht3cw==",
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/browserslist"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "peer": true
- },
- "node_modules/chalk": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
- "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
- "dependencies": {
- "ansi-styles": "^3.2.1",
- "escape-string-regexp": "^1.0.5",
- "supports-color": "^5.3.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/chalk/node_modules/escape-string-regexp": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
- "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
- "engines": {
- "node": ">=0.8.0"
- }
- },
- "node_modules/classnames": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz",
- "integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA=="
- },
- "node_modules/color-convert": {
- "version": "1.9.3",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
- "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
- "dependencies": {
- "color-name": "1.1.3"
- }
- },
- "node_modules/color-name": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
- "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="
- },
- "node_modules/compute-scroll-into-view": {
- "version": "1.0.14",
- "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-1.0.14.tgz",
- "integrity": "sha512-mKDjINe3tc6hGelUMNDzuhorIUZ7kS7BwyY0r2wQd2HOH2tRuJykiC06iSEX8y1TuhNzvz4GcJnK16mM2J1NMQ=="
- },
- "node_modules/convert-source-map": {
- "version": "1.8.0",
- "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz",
- "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==",
- "dependencies": {
- "safe-buffer": "~5.1.1"
- }
- },
- "node_modules/copy-to-clipboard": {
- "version": "3.3.1",
- "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.1.tgz",
- "integrity": "sha512-i13qo6kIHTTpCm8/Wup+0b1mVWETvu2kIMzKoK8FpkLkFxlt0znUAHcMzox+T8sPlqtZXq3CulEjQHsYiGFJUw==",
- "dependencies": {
- "toggle-selection": "^1.0.6"
- }
- },
- "node_modules/core-js": {
- "version": "3.33.2",
- "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.33.2.tgz",
- "integrity": "sha512-XeBzWI6QL3nJQiHmdzbAOiMYqjrb7hwU7A39Qhvd/POSa/t9E1AeZyEZx3fNvp/vtM8zXwhoL0FsiS0hD0pruQ==",
- "hasInstallScript": true,
- "peer": true,
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/core-js"
- }
- },
- "node_modules/cosmiconfig": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz",
- "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==",
- "dependencies": {
- "@types/parse-json": "^4.0.0",
- "import-fresh": "^3.1.0",
- "parse-json": "^5.0.0",
- "path-type": "^4.0.0",
- "yaml": "^1.7.2"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/cross-fetch": {
- "version": "3.1.8",
- "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz",
- "integrity": "sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==",
- "peer": true,
- "dependencies": {
- "node-fetch": "^2.6.12"
- }
- },
- "node_modules/css-box-model": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/css-box-model/-/css-box-model-1.2.1.tgz",
- "integrity": "sha512-a7Vr4Q/kd/aw96bnJG332W9V9LkJO69JRcaCYDUqjp6/z0w6VcZjgAcTbgFxEPfBgdnAwlh3iwu+hLopa+flJw==",
- "dependencies": {
- "tiny-invariant": "^1.0.6"
- }
- },
- "node_modules/csstype": {
- "version": "3.0.10",
- "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.10.tgz",
- "integrity": "sha512-2u44ZG2OcNUO9HDp/Jl8C07x6pU/eTR3ncV91SiK3dhG9TWvRVsCoJw14Ckx5DgWkzGA3waZWO3d7pgqpUI/XA=="
- },
- "node_modules/dayjs": {
- "version": "1.10.7",
- "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.10.7.tgz",
- "integrity": "sha512-P6twpd70BcPK34K26uJ1KT3wlhpuOAPoMwJzpsIWUxHZ7wpmbdZL/hQqBDfz7hGurYSa5PhzdhDHtt319hL3ig=="
- },
- "node_modules/debounce": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz",
- "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug=="
- },
- "node_modules/debug": {
- "version": "4.3.4",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
- "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
- "peer": true,
- "dependencies": {
- "ms": "2.1.2"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "node_modules/detect-node-es": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz",
- "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ=="
- },
- "node_modules/draft-js": {
- "version": "0.11.7",
- "resolved": "https://registry.npmjs.org/draft-js/-/draft-js-0.11.7.tgz",
- "integrity": "sha512-ne7yFfN4sEL82QPQEn80xnADR8/Q6ALVworbC5UOSzOvjffmYfFsr3xSZtxbIirti14R7Y33EZC5rivpLgIbsg==",
- "peer": true,
- "dependencies": {
- "fbjs": "^2.0.0",
- "immutable": "~3.7.4",
- "object-assign": "^4.1.1"
- },
- "peerDependencies": {
- "react": ">=0.14.0",
- "react-dom": ">=0.14.0"
- }
- },
- "node_modules/draft-js/node_modules/immutable": {
- "version": "3.7.6",
- "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.7.6.tgz",
- "integrity": "sha512-AizQPcaofEtO11RZhPPHBOJRdo/20MKQF9mBLnVkBoyHi1/zXK8fzVdnEpSV9gxqtnh6Qomfp3F0xT5qP/vThw==",
- "peer": true,
- "engines": {
- "node": ">=0.8.0"
- }
- },
- "node_modules/draftjs-utils": {
- "version": "0.10.2",
- "resolved": "https://registry.npmjs.org/draftjs-utils/-/draftjs-utils-0.10.2.tgz",
- "integrity": "sha512-EstHqr3R3JVcilJrBaO/A+01GvwwKmC7e4TCjC7S94ZeMh4IVmf60OuQXtHHpwItK8C2JCi3iljgN5KHkJboUg==",
- "peerDependencies": {
- "draft-js": "^0.11.x",
- "immutable": "3.x.x || 4.x.x"
- }
- },
- "node_modules/electron-to-chromium": {
- "version": "1.4.581",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.581.tgz",
- "integrity": "sha512-6uhqWBIapTJUxgPTCHH9sqdbxIMPt7oXl0VcAL1kOtlU6aECdcMncCrX5Z7sHQ/invtrC9jUQUef7+HhO8vVFw==",
- "peer": true
- },
- "node_modules/error-ex": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
- "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
- "dependencies": {
- "is-arrayish": "^0.2.1"
- }
- },
- "node_modules/esbuild": {
- "version": "0.14.9",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.9.tgz",
- "integrity": "sha512-uuT3kFsfUvzNW6I2RKKIHuCvutY/U9KFcAP6emUm98WvBhyhEr5vGkZLeN3r3vXfoykl+7xekAH8Ky09LXBd0Q==",
- "hasInstallScript": true,
- "bin": {
- "esbuild": "bin/esbuild"
- },
- "optionalDependencies": {
- "esbuild-android-arm64": "0.14.9",
- "esbuild-darwin-64": "0.14.9",
- "esbuild-darwin-arm64": "0.14.9",
- "esbuild-freebsd-64": "0.14.9",
- "esbuild-freebsd-arm64": "0.14.9",
- "esbuild-linux-32": "0.14.9",
- "esbuild-linux-64": "0.14.9",
- "esbuild-linux-arm": "0.14.9",
- "esbuild-linux-arm64": "0.14.9",
- "esbuild-linux-mips64le": "0.14.9",
- "esbuild-linux-ppc64le": "0.14.9",
- "esbuild-linux-s390x": "0.14.9",
- "esbuild-netbsd-64": "0.14.9",
- "esbuild-openbsd-64": "0.14.9",
- "esbuild-sunos-64": "0.14.9",
- "esbuild-windows-32": "0.14.9",
- "esbuild-windows-64": "0.14.9",
- "esbuild-windows-arm64": "0.14.9"
- }
- },
- "node_modules/esbuild-android-arm64": {
- "version": "0.14.9",
- "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.9.tgz",
- "integrity": "sha512-VpSCuUR07G4Re/5QzqtdxS5ZgxkCRyzu4Kf5SH1/EkXzRGeoWQt8xirkOMK58pfmg/FlS/fQNgwl3Txej4LoVg==",
- "cpu": [
- "arm64"
- ],
- "optional": true,
- "os": [
- "android"
- ]
- },
- "node_modules/esbuild-darwin-64": {
- "version": "0.14.9",
- "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.9.tgz",
- "integrity": "sha512-F/RcRHMG5ccAL8n9VIy8ZC4D0IHZrN/1IhHQbY4qPXrMlh42FucR0TW4lr3vdHF3caaId1jdDSQQJ7jXR+ZC5Q==",
- "cpu": [
- "x64"
- ],
- "optional": true,
- "os": [
- "darwin"
- ]
- },
- "node_modules/esbuild-darwin-arm64": {
- "version": "0.14.9",
- "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.9.tgz",
- "integrity": "sha512-3ue+1T4FR5TaAu4/V1eFMG8Uwn0pgAwQZb/WwL1X78d5Cy8wOVQ67KNH1lsjU+y/9AcwMKZ9x0GGNxBB4a1Rbw==",
- "cpu": [
- "arm64"
- ],
- "optional": true,
- "os": [
- "darwin"
- ]
- },
- "node_modules/esbuild-freebsd-64": {
- "version": "0.14.9",
- "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.9.tgz",
- "integrity": "sha512-0YEjWt6ijaf5Y3Q50YS1lZxuWZWMV/T7atQEuQnF8ioq5jamrVr8j1TZ9+rxcLgH1lBMsXj8IwW+6BleXredEg==",
- "cpu": [
- "x64"
- ],
- "optional": true,
- "os": [
- "freebsd"
- ]
- },
- "node_modules/esbuild-freebsd-arm64": {
- "version": "0.14.9",
- "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.9.tgz",
- "integrity": "sha512-82w5qMgEeYvf8+vX/2KE5TOZf8rv8VK4TFiK6lDzdgdwwmBU5C8kdT3rO5Llan2K2LKndrou1eyi/fHwFcwPJQ==",
- "cpu": [
- "arm64"
- ],
- "optional": true,
- "os": [
- "freebsd"
- ]
- },
- "node_modules/esbuild-linux-32": {
- "version": "0.14.9",
- "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.9.tgz",
- "integrity": "sha512-eu8J8HNpco7Mkd7T7djQRzGBeuve41kbXRxFHOwwbZXMNQojXjBqLuradi5i/Vsw+CA4G/yVpmJI2S75Cit2mQ==",
- "cpu": [
- "ia32"
- ],
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/esbuild-linux-64": {
- "version": "0.14.9",
- "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.9.tgz",
- "integrity": "sha512-WoEI+R6/PLZAxS7XagfQMFgRtLUi5cjqqU9VCfo3tnWmAXh/wt8QtUfCVVCcXVwZLS/RNvI19CtfjlrJU61nOg==",
- "cpu": [
- "x64"
- ],
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/esbuild-linux-arm": {
- "version": "0.14.9",
- "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.9.tgz",
- "integrity": "sha512-d3k1ZPREjaKYyhsS8x3jvc4ekjIZ8SmuihP60mrN1f6p5y07NKWw9i0OWD1p6hy+7g6cjMWq00tstMIikGB9Yg==",
- "cpu": [
- "arm"
- ],
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/esbuild-linux-arm64": {
- "version": "0.14.9",
- "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.9.tgz",
- "integrity": "sha512-joUE0yQgWMDkQqBx3+6SdNCVZ10F1O4+WM94moghvhdTzkYpECIc/WvfqMF/w0V8Hecw3QJ7vugO7jsFlXXd4Q==",
- "cpu": [
- "arm64"
- ],
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/esbuild-linux-mips64le": {
- "version": "0.14.9",
- "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.9.tgz",
- "integrity": "sha512-ZAuheiDRo2c4rxx8GUTEwPvos0zUwCYjP9K2WfCSmDL6m3RpaObCQhZghrDuoIUwvc/D6SWuABsKE9VzogsltQ==",
- "cpu": [
- "mips64el"
- ],
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/esbuild-linux-ppc64le": {
- "version": "0.14.9",
- "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.9.tgz",
- "integrity": "sha512-Pm8FeG5l314k3a2mbu3SAc5E2eLFuGUsGiSlw8V6xtA4whxJ7rit7951w9jBhz+1Vqqtqprg2IYTng3j2CGhVw==",
- "cpu": [
- "ppc64"
- ],
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/esbuild-linux-s390x": {
- "version": "0.14.9",
- "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.9.tgz",
- "integrity": "sha512-G8FNZygV82N1/LOfPD8ZX7Mn1dPpKKPrZc93ebSJ8/VgNIafOAhV5vaeK1lhcx6ZSu+jJU/UyQQMG1CIvHRIaw==",
- "cpu": [
- "s390x"
- ],
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/esbuild-netbsd-64": {
- "version": "0.14.9",
- "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.9.tgz",
- "integrity": "sha512-b7vPrn5XN0GRtNAQ3w+gq8AwUfWSRBkcPAdA5UUT5rkrw7wKFyMqi2/zREBc/Knu5YOsLmZPQSoM8QL6qy79cg==",
- "cpu": [
- "x64"
- ],
- "optional": true,
- "os": [
- "netbsd"
- ]
- },
- "node_modules/esbuild-openbsd-64": {
- "version": "0.14.9",
- "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.9.tgz",
- "integrity": "sha512-w95Rt/vmVhZWfzZmeoMIHxbFiOFDmxC7GEdnCbDTXX2vlwKu+CIDIKOgWW+R1T2JqTNo5tu9dRkngKZMfbUo/A==",
- "cpu": [
- "x64"
- ],
- "optional": true,
- "os": [
- "openbsd"
- ]
- },
- "node_modules/esbuild-sunos-64": {
- "version": "0.14.9",
- "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.9.tgz",
- "integrity": "sha512-mzgmQZAVGo+uLkQXTY0viqVSEQKesmR5OEMMq1jM/2jucbZUcyaq8dVKRIWJJEzwNgZ6MpeOpshUtOzGxxy8ag==",
- "cpu": [
- "x64"
- ],
- "optional": true,
- "os": [
- "sunos"
- ]
- },
- "node_modules/esbuild-windows-32": {
- "version": "0.14.9",
- "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.9.tgz",
- "integrity": "sha512-sYHEJLwdDJpjjSUyIGqPC1GRXl0Z/YT1K85Tcrv4iqZEXFR0rT7sTV+E0XC911FbTJHfuAdUJixkwAQeLMdrUg==",
- "cpu": [
- "ia32"
- ],
- "optional": true,
- "os": [
- "win32"
- ]
- },
- "node_modules/esbuild-windows-64": {
- "version": "0.14.9",
- "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.9.tgz",
- "integrity": "sha512-xJTpyFzpH51LGlVR2C3P+Gpnjujsx5kEtJj5V/x8TyD94VW+EpszyND/pay15CIF64pWywyQt2jmGUDl6kzkEw==",
- "cpu": [
- "x64"
- ],
- "optional": true,
- "os": [
- "win32"
- ]
- },
- "node_modules/esbuild-windows-arm64": {
- "version": "0.14.9",
- "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.9.tgz",
- "integrity": "sha512-NKPPsYVlHqdF0yMuMJrjuAzqS/BHrMXZ8TN1Du+Pgi8KkmxzNXRPDHQV0NPPJ+Z7Lp09joEHSz1zrvQRs1j6jw==",
- "cpu": [
- "arm64"
- ],
- "optional": true,
- "os": [
- "win32"
- ]
- },
- "node_modules/escalade": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
- "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
- "peer": true,
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/escape-string-regexp": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
- "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/fbjs": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-2.0.0.tgz",
- "integrity": "sha512-8XA8ny9ifxrAWlyhAbexXcs3rRMtxWcs3M0lctLfB49jRDHiaxj+Mo0XxbwE7nKZYzgCFoq64FS+WFd4IycPPQ==",
- "peer": true,
- "dependencies": {
- "core-js": "^3.6.4",
- "cross-fetch": "^3.0.4",
- "fbjs-css-vars": "^1.0.0",
- "loose-envify": "^1.0.0",
- "object-assign": "^4.1.0",
- "promise": "^7.1.1",
- "setimmediate": "^1.0.5",
- "ua-parser-js": "^0.7.18"
- }
- },
- "node_modules/fbjs-css-vars": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz",
- "integrity": "sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ==",
- "peer": true
- },
- "node_modules/file-selector": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/file-selector/-/file-selector-0.4.0.tgz",
- "integrity": "sha512-iACCiXeMYOvZqlF1kTiYINzgepRBymz1wwjiuup9u9nayhb6g4fSwiyJ/6adli+EPwrWtpgQAh2PoS7HukEGEg==",
- "dependencies": {
- "tslib": "^2.0.3"
- },
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/find-root": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz",
- "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng=="
- },
- "node_modules/focus-lock": {
- "version": "0.9.2",
- "resolved": "https://registry.npmjs.org/focus-lock/-/focus-lock-0.9.2.tgz",
- "integrity": "sha512-YtHxjX7a0IC0ZACL5wsX8QdncXofWpGPNoVMuI/nZUrPGp6LmNI6+D5j0pPj+v8Kw5EpweA+T5yImK0rnWf7oQ==",
- "dependencies": {
- "tslib": "^2.0.3"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/focus-visible": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/focus-visible/-/focus-visible-5.2.0.tgz",
- "integrity": "sha512-Rwix9pBtC1Nuy5wysTmKy+UjbDJpIfg8eHjw0rjZ1mX4GNLz1Bmd16uDpI3Gk1i70Fgcs8Csg2lPm8HULFg9DQ=="
- },
- "node_modules/framer-motion": {
- "version": "5.5.5",
- "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-5.5.5.tgz",
- "integrity": "sha512-+LPAF5ddo02qKh+MK4h1ChwqUFvrLkK1NDWwrHy+MuCVmQDGgiFNHvwqOSklTDGkEtbio3dCOEDy23+ZyNAa9g==",
- "dependencies": {
- "framesync": "6.0.1",
- "hey-listen": "^1.0.8",
- "popmotion": "11.0.3",
- "react-merge-refs": "^1.1.0",
- "react-use-measure": "^2.1.1",
- "style-value-types": "5.0.0",
- "tslib": "^2.1.0"
- },
- "optionalDependencies": {
- "@emotion/is-prop-valid": "^0.8.2"
- },
- "peerDependencies": {
- "@react-three/fiber": "*",
- "react": ">=16.8 || ^17.0.0",
- "react-dom": ">=16.8 || ^17.0.0",
- "three": "^0.135.0"
- },
- "peerDependenciesMeta": {
- "@react-three/fiber": {
- "optional": true
- },
- "three": {
- "optional": true
- }
- }
- },
- "node_modules/framer-motion/node_modules/@emotion/is-prop-valid": {
- "version": "0.8.8",
- "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz",
- "integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==",
- "optional": true,
- "dependencies": {
- "@emotion/memoize": "0.7.4"
- }
- },
- "node_modules/framer-motion/node_modules/@emotion/memoize": {
- "version": "0.7.4",
- "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz",
- "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==",
- "optional": true
- },
- "node_modules/framer-motion/node_modules/framesync": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/framesync/-/framesync-6.0.1.tgz",
- "integrity": "sha512-fUY88kXvGiIItgNC7wcTOl0SNRCVXMKSWW2Yzfmn7EKNc+MpCzcz9DhdHcdjbrtN3c6R4H5dTY2jiCpPdysEjA==",
- "dependencies": {
- "tslib": "^2.1.0"
- }
- },
- "node_modules/framesync": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/framesync/-/framesync-5.3.0.tgz",
- "integrity": "sha512-oc5m68HDO/tuK2blj7ZcdEBRx3p1PjrgHazL8GYEpvULhrtGIFbQArN6cQS2QhW8mitffaB+VYzMjDqBxxQeoA==",
- "dependencies": {
- "tslib": "^2.1.0"
- }
- },
- "node_modules/function-bind": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
- "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
- },
- "node_modules/gensync": {
- "version": "1.0.0-beta.2",
- "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
- "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
- "peer": true,
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/get-nonce": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz",
- "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/globals": {
- "version": "11.12.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
- "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
- "peer": true,
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/graphql": {
- "version": "16.2.0",
- "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.2.0.tgz",
- "integrity": "sha512-MuQd7XXrdOcmfwuLwC2jNvx0n3rxIuNYOxUtiee5XOmfrWo613ar2U8pE7aHAKh8VwfpifubpD9IP+EdEAEOsA==",
- "engines": {
- "node": "^12.22.0 || ^14.16.0 || >=16.0.0"
- }
- },
- "node_modules/has": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
- "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
- "dependencies": {
- "function-bind": "^1.1.1"
- },
- "engines": {
- "node": ">= 0.4.0"
- }
- },
- "node_modules/has-flag": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
- "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/hey-listen": {
- "version": "1.0.8",
- "resolved": "https://registry.npmjs.org/hey-listen/-/hey-listen-1.0.8.tgz",
- "integrity": "sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q=="
- },
- "node_modules/history": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/history/-/history-5.2.0.tgz",
- "integrity": "sha512-uPSF6lAJb3nSePJ43hN3eKj1dTWpN9gMod0ZssbFTIsen+WehTmEadgL+kg78xLJFdRfrrC//SavDzmRVdE+Ig==",
- "dependencies": {
- "@babel/runtime": "^7.7.6"
- }
- },
- "node_modules/hoist-non-react-statics": {
- "version": "3.3.2",
- "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
- "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
- "dependencies": {
- "react-is": "^16.7.0"
- }
- },
- "node_modules/html-to-draftjs": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/html-to-draftjs/-/html-to-draftjs-1.5.0.tgz",
- "integrity": "sha512-kggLXBNciKDwKf+KYsuE+V5gw4dZ7nHyGMX9m0wy7urzWjKGWyNFetmArRLvRV0VrxKN70WylFsJvMTJx02OBQ==",
- "peerDependencies": {
- "draft-js": "^0.10.x || ^0.11.x",
- "immutable": "3.x.x || 4.x.x"
- }
- },
- "node_modules/immutable": {
- "version": "4.3.4",
- "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.4.tgz",
- "integrity": "sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==",
- "peer": true
- },
- "node_modules/import-fresh": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
- "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
- "dependencies": {
- "parent-module": "^1.0.0",
- "resolve-from": "^4.0.0"
- },
- "engines": {
- "node": ">=6"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/invariant": {
- "version": "2.2.4",
- "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
- "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
- "dependencies": {
- "loose-envify": "^1.0.0"
- }
- },
- "node_modules/is-arrayish": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
- "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0="
- },
- "node_modules/is-core-module": {
- "version": "2.8.0",
- "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz",
- "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==",
- "dependencies": {
- "has": "^1.0.3"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/js-tokens": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
- "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
- },
- "node_modules/jsesc": {
- "version": "2.5.2",
- "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
- "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
- "peer": true,
- "bin": {
- "jsesc": "bin/jsesc"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/json-parse-even-better-errors": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
- "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w=="
- },
- "node_modules/json5": {
- "version": "2.2.3",
- "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
- "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
- "peer": true,
- "bin": {
- "json5": "lib/cli.js"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/lines-and-columns": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
- "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="
- },
- "node_modules/linkify-it": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz",
- "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==",
- "dependencies": {
- "uc.micro": "^1.0.1"
- }
- },
- "node_modules/lodash": {
- "version": "4.17.21",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
- "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
- },
- "node_modules/lodash.mergewith": {
- "version": "4.6.2",
- "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz",
- "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ=="
- },
- "node_modules/loose-envify": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
- "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
- "dependencies": {
- "js-tokens": "^3.0.0 || ^4.0.0"
- },
- "bin": {
- "loose-envify": "cli.js"
- }
- },
- "node_modules/lru-cache": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
- "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
- "peer": true,
- "dependencies": {
- "yallist": "^3.0.2"
- }
- },
- "node_modules/ms": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
- "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
- "peer": true
- },
- "node_modules/node-fetch": {
- "version": "2.7.0",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
- "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
- "peer": true,
- "dependencies": {
- "whatwg-url": "^5.0.0"
- },
- "engines": {
- "node": "4.x || >=6.0.0"
- },
- "peerDependencies": {
- "encoding": "^0.1.0"
- },
- "peerDependenciesMeta": {
- "encoding": {
- "optional": true
- }
- }
- },
- "node_modules/node-releases": {
- "version": "2.0.13",
- "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz",
- "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==",
- "peer": true
- },
- "node_modules/object-assign": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
- "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/parent-module": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
- "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
- "dependencies": {
- "callsites": "^3.0.0"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/parse-json": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
- "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
- "dependencies": {
- "@babel/code-frame": "^7.0.0",
- "error-ex": "^1.3.1",
- "json-parse-even-better-errors": "^2.3.0",
- "lines-and-columns": "^1.1.6"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/path-parse": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
- "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
- },
- "node_modules/path-type": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
- "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/picocolors": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
- "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
- "peer": true
- },
- "node_modules/popmotion": {
- "version": "11.0.3",
- "resolved": "https://registry.npmjs.org/popmotion/-/popmotion-11.0.3.tgz",
- "integrity": "sha512-Y55FLdj3UxkR7Vl3s7Qr4e9m0onSnP8W7d/xQLsoJM40vs6UKHFdygs6SWryasTZYqugMjm3BepCF4CWXDiHgA==",
- "dependencies": {
- "framesync": "6.0.1",
- "hey-listen": "^1.0.8",
- "style-value-types": "5.0.0",
- "tslib": "^2.1.0"
- }
- },
- "node_modules/popmotion/node_modules/framesync": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/framesync/-/framesync-6.0.1.tgz",
- "integrity": "sha512-fUY88kXvGiIItgNC7wcTOl0SNRCVXMKSWW2Yzfmn7EKNc+MpCzcz9DhdHcdjbrtN3c6R4H5dTY2jiCpPdysEjA==",
- "dependencies": {
- "tslib": "^2.1.0"
- }
- },
- "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/promise": {
- "version": "7.3.1",
- "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
- "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
- "peer": true,
- "dependencies": {
- "asap": "~2.0.3"
- }
- },
- "node_modules/prop-types": {
- "version": "15.8.1",
- "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
- "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
- "dependencies": {
- "loose-envify": "^1.4.0",
- "object-assign": "^4.1.1",
- "react-is": "^16.13.1"
- }
- },
- "node_modules/react": {
- "version": "17.0.2",
- "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz",
- "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==",
- "dependencies": {
- "loose-envify": "^1.1.0",
- "object-assign": "^4.1.1"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/react-clientside-effect": {
- "version": "1.2.5",
- "resolved": "https://registry.npmjs.org/react-clientside-effect/-/react-clientside-effect-1.2.5.tgz",
- "integrity": "sha512-2bL8qFW1TGBHozGGbVeyvnggRpMjibeZM2536AKNENLECutp2yfs44IL8Hmpn8qjFQ2K7A9PnYf3vc7aQq/cPA==",
- "dependencies": {
- "@babel/runtime": "^7.12.13"
- },
- "peerDependencies": {
- "react": "^15.3.0 || ^16.0.0 || ^17.0.0"
- }
- },
- "node_modules/react-dom": {
- "version": "17.0.2",
- "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz",
- "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==",
- "dependencies": {
- "loose-envify": "^1.1.0",
- "object-assign": "^4.1.1",
- "scheduler": "^0.20.2"
- },
- "peerDependencies": {
- "react": "17.0.2"
- }
- },
- "node_modules/react-draft-wysiwyg": {
- "version": "1.15.0",
- "resolved": "https://registry.npmjs.org/react-draft-wysiwyg/-/react-draft-wysiwyg-1.15.0.tgz",
- "integrity": "sha512-p1cYZcWc6/ALFBVksbFoCM3b29fGQDlZLIMrXng0TU/UElxIOF2/AWWo4L5auIYVhmqKTZ0NkNjnXOzGGuxyeA==",
- "dependencies": {
- "classnames": "^2.2.6",
- "draftjs-utils": "^0.10.2",
- "html-to-draftjs": "^1.5.0",
- "linkify-it": "^2.2.0",
- "prop-types": "^15.7.2"
- },
- "peerDependencies": {
- "draft-js": "^0.10.x || ^0.11.x",
- "immutable": "3.x.x || 4.x.x",
- "react": "0.13.x || 0.14.x || ^15.0.0-0 || 15.x.x || ^16.0.0-0 || ^16.x.x || ^17.x.x || ^18.x.x",
- "react-dom": "0.13.x || 0.14.x || ^15.0.0-0 || 15.x.x || ^16.0.0-0 || ^16.x.x || ^17.x.x || ^18.x.x"
- }
- },
- "node_modules/react-dropzone": {
- "version": "12.0.4",
- "resolved": "https://registry.npmjs.org/react-dropzone/-/react-dropzone-12.0.4.tgz",
- "integrity": "sha512-fcqHEYe1MzAghU6/Hz86lHDlBNsA+lO48nAcm7/wA+kIzwS6uuJbUG33tBZjksj7GAZ1iUQ6NHwjUURPmSGang==",
- "dependencies": {
- "attr-accept": "^2.2.2",
- "file-selector": "^0.4.0",
- "prop-types": "^15.8.1"
- },
- "engines": {
- "node": ">= 10.13"
- },
- "peerDependencies": {
- "react": ">= 16.8"
- }
- },
- "node_modules/react-email-editor": {
- "version": "1.6.1",
- "resolved": "https://registry.npmjs.org/react-email-editor/-/react-email-editor-1.6.1.tgz",
- "integrity": "sha512-pEWpRmTY0ok03cwTGqEOoEldnzThhuRGTrcMnv8W3/jc5MTfcr9USU/IQ9HrVvFStLKoxYBIQnSKY+iCYWOtSQ==",
- "peerDependencies": {
- "react": "15.x || 16.x || 17.x"
- }
- },
- "node_modules/react-fast-compare": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz",
- "integrity": "sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA=="
- },
- "node_modules/react-focus-lock": {
- "version": "2.5.2",
- "resolved": "https://registry.npmjs.org/react-focus-lock/-/react-focus-lock-2.5.2.tgz",
- "integrity": "sha512-WzpdOnEqjf+/A3EH9opMZWauag7gV0BxFl+EY4ElA4qFqYsUsBLnmo2sELbN5OC30S16GAWMy16B9DLPpdJKAQ==",
- "dependencies": {
- "@babel/runtime": "^7.0.0",
- "focus-lock": "^0.9.1",
- "prop-types": "^15.6.2",
- "react-clientside-effect": "^1.2.5",
- "use-callback-ref": "^1.2.5",
- "use-sidecar": "^1.0.5"
- },
- "peerDependencies": {
- "react": "^16.8.0 || ^17.0.0"
- }
- },
- "node_modules/react-icons": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.3.1.tgz",
- "integrity": "sha512-cB10MXLTs3gVuXimblAdI71jrJx8njrJZmNMEMC+sQu5B/BIOmlsAjskdqpn81y8UBVEGuHODd7/ci5DvoSzTQ==",
- "peerDependencies": {
- "react": "*"
- }
- },
- "node_modules/react-is": {
- "version": "16.13.1",
- "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
- "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
- },
- "node_modules/react-merge-refs": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/react-merge-refs/-/react-merge-refs-1.1.0.tgz",
- "integrity": "sha512-alTKsjEL0dKH/ru1Iyn7vliS2QRcBp9zZPGoWxUOvRGWPUYgjo+V01is7p04It6KhgrzhJGnIj9GgX8W4bZoCQ==",
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/gregberge"
- }
- },
- "node_modules/react-remove-scroll": {
- "version": "2.4.1",
- "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.4.1.tgz",
- "integrity": "sha512-K7XZySEzOHMTq7dDwcHsZA6Y7/1uX5RsWhRXVYv8rdh+y9Qz2nMwl9RX/Mwnj/j7JstCGmxyfyC0zbVGXYh3mA==",
- "dependencies": {
- "react-remove-scroll-bar": "^2.1.0",
- "react-style-singleton": "^2.1.0",
- "tslib": "^1.0.0",
- "use-callback-ref": "^1.2.3",
- "use-sidecar": "^1.0.1"
- },
- "engines": {
- "node": ">=8.5.0"
- },
- "peerDependencies": {
- "@types/react": "^16.8.0 || ^17.0.0",
- "react": "^16.8.0 || ^17.0.0"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/react-remove-scroll-bar": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.2.0.tgz",
- "integrity": "sha512-UU9ZBP1wdMR8qoUs7owiVcpaPwsQxUDC2lypP6mmixaGlARZa7ZIBx1jcuObLdhMOvCsnZcvetOho0wzPa9PYg==",
- "dependencies": {
- "react-style-singleton": "^2.1.0",
- "tslib": "^1.0.0"
- },
- "engines": {
- "node": ">=8.5.0"
- },
- "peerDependencies": {
- "@types/react": "^16.8.0 || ^17.0.0",
- "react": "^16.8.0 || ^17.0.0"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/react-remove-scroll-bar/node_modules/tslib": {
- "version": "1.14.1",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
- "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
- },
- "node_modules/react-remove-scroll/node_modules/tslib": {
- "version": "1.14.1",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
- "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
- },
- "node_modules/react-router": {
- "version": "6.2.1",
- "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.2.1.tgz",
- "integrity": "sha512-2fG0udBtxou9lXtK97eJeET2ki5//UWfQSl1rlJ7quwe6jrktK9FCCc8dQb5QY6jAv3jua8bBQRhhDOM/kVRsg==",
- "dependencies": {
- "history": "^5.2.0"
- },
- "peerDependencies": {
- "react": ">=16.8"
- }
- },
- "node_modules/react-router-dom": {
- "version": "6.2.1",
- "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.2.1.tgz",
- "integrity": "sha512-I6Zax+/TH/cZMDpj3/4Fl2eaNdcvoxxHoH1tYOREsQ22OKDYofGebrNm6CTPUcvLvZm63NL/vzCYdjf9CUhqmA==",
- "dependencies": {
- "history": "^5.2.0",
- "react-router": "6.2.1"
- },
- "peerDependencies": {
- "react": ">=16.8",
- "react-dom": ">=16.8"
- }
- },
- "node_modules/react-style-singleton": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.1.1.tgz",
- "integrity": "sha512-jNRp07Jza6CBqdRKNgGhT3u9umWvils1xsuMOjZlghBDH2MU0PL2WZor4PGYjXpnRCa9DQSlHMs/xnABWOwYbA==",
- "dependencies": {
- "get-nonce": "^1.0.0",
- "invariant": "^2.2.4",
- "tslib": "^1.0.0"
- },
- "engines": {
- "node": ">=8.5.0"
- },
- "peerDependencies": {
- "@types/react": "^16.8.0 || ^17.0.0",
- "react": "^16.8.0 || ^17.0.0"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/react-style-singleton/node_modules/tslib": {
- "version": "1.14.1",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
- "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
- },
- "node_modules/react-use-measure": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/react-use-measure/-/react-use-measure-2.1.1.tgz",
- "integrity": "sha512-nocZhN26cproIiIduswYpV5y5lQpSQS1y/4KuvUCjSKmw7ZWIS/+g3aFnX3WdBkyuGUtTLif3UTqnLLhbDoQig==",
- "dependencies": {
- "debounce": "^1.2.1"
- },
- "peerDependencies": {
- "react": ">=16.13",
- "react-dom": ">=16.13"
- }
- },
- "node_modules/regenerator-runtime": {
- "version": "0.13.9",
- "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
- "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA=="
- },
- "node_modules/resolve": {
- "version": "1.20.0",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz",
- "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==",
- "dependencies": {
- "is-core-module": "^2.2.0",
- "path-parse": "^1.0.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/resolve-from": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
- "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/safe-buffer": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
- "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
- },
- "node_modules/scheduler": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz",
- "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==",
- "dependencies": {
- "loose-envify": "^1.1.0",
- "object-assign": "^4.1.1"
- }
- },
- "node_modules/semver": {
- "version": "6.3.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
- "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
- "peer": true,
- "bin": {
- "semver": "bin/semver.js"
- }
- },
- "node_modules/setimmediate": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
- "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==",
- "peer": true
- },
- "node_modules/source-map": {
- "version": "0.5.7",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
- "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/style-value-types": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/style-value-types/-/style-value-types-5.0.0.tgz",
- "integrity": "sha512-08yq36Ikn4kx4YU6RD7jWEv27v4V+PUsOGa4n/as8Et3CuODMJQ00ENeAVXAeydX4Z2j1XHZF1K2sX4mGl18fA==",
- "dependencies": {
- "hey-listen": "^1.0.8",
- "tslib": "^2.1.0"
- }
- },
- "node_modules/stylis": {
- "version": "4.0.13",
- "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.0.13.tgz",
- "integrity": "sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag=="
- },
- "node_modules/supports-color": {
- "version": "5.5.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
- "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
- "dependencies": {
- "has-flag": "^3.0.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/tiny-invariant": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.2.0.tgz",
- "integrity": "sha512-1Uhn/aqw5C6RI4KejVeTg6mIS7IqxnLJ8Mv2tV5rTc0qWobay7pDUz6Wi392Cnc8ak1H0F2cjoRzb2/AW4+Fvg=="
- },
- "node_modules/to-fast-properties": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
- "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/toggle-selection": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz",
- "integrity": "sha1-bkWxJj8gF/oKzH2J14sVuL932jI="
- },
- "node_modules/tr46": {
- "version": "0.0.3",
- "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
- "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
- "peer": true
- },
- "node_modules/tslib": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
- "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
- },
- "node_modules/typescript": {
- "version": "4.5.4",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.4.tgz",
- "integrity": "sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg==",
- "bin": {
- "tsc": "bin/tsc",
- "tsserver": "bin/tsserver"
- },
- "engines": {
- "node": ">=4.2.0"
- }
- },
- "node_modules/ua-parser-js": {
- "version": "0.7.37",
- "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.37.tgz",
- "integrity": "sha512-xV8kqRKM+jhMvcHWUKthV9fNebIzrNy//2O9ZwWcfiBFR5f25XVZPLlEajk/sf3Ra15V92isyQqnIEXRDaZWEA==",
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/ua-parser-js"
- },
- {
- "type": "paypal",
- "url": "https://paypal.me/faisalman"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/faisalman"
- }
- ],
- "peer": true,
- "engines": {
- "node": "*"
- }
- },
- "node_modules/uc.micro": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
- "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA=="
- },
- "node_modules/update-browserslist-db": {
- "version": "1.0.13",
- "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz",
- "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==",
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/browserslist"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/browserslist"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "peer": true,
- "dependencies": {
- "escalade": "^3.1.1",
- "picocolors": "^1.0.0"
- },
- "bin": {
- "update-browserslist-db": "cli.js"
- },
- "peerDependencies": {
- "browserslist": ">= 4.21.0"
- }
- },
- "node_modules/urql": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/urql/-/urql-2.0.6.tgz",
- "integrity": "sha512-ovK9mx7YxD/CKUwVZGbEDBzZjbCcNsr1990nIhDCKe3Ij/0gNcIa+0EIyXKceOPuYDYKavIoaNQV2kOZjQxFcw==",
- "dependencies": {
- "@urql/core": "^2.3.6",
- "wonka": "^4.0.14"
- },
- "peerDependencies": {
- "graphql": "^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0",
- "react": ">= 16.8.0"
- }
- },
- "node_modules/use-callback-ref": {
- "version": "1.2.5",
- "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.2.5.tgz",
- "integrity": "sha512-gN3vgMISAgacF7sqsLPByqoePooY3n2emTH59Ur5d/M8eg4WTWu1xp8i8DHjohftIyEx0S08RiYxbffr4j8Peg==",
- "engines": {
- "node": ">=8.5.0"
- },
- "peerDependencies": {
- "@types/react": "^16.8.0 || ^17.0.0",
- "react": "^16.8.0 || ^17.0.0"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/use-sidecar": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.0.5.tgz",
- "integrity": "sha512-k9jnrjYNwN6xYLj1iaGhonDghfvmeTmYjAiGvOr7clwKfPjMXJf4/HOr7oT5tJwYafgp2tG2l3eZEOfoELiMcA==",
- "dependencies": {
- "detect-node-es": "^1.1.0",
- "tslib": "^1.9.3"
- },
- "engines": {
- "node": ">=8.5.0"
- },
- "peerDependencies": {
- "react": "^16.8.0 || ^17.0.0"
- }
- },
- "node_modules/use-sidecar/node_modules/tslib": {
- "version": "1.14.1",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
- "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
- },
- "node_modules/warning": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
- "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
- "dependencies": {
- "loose-envify": "^1.0.0"
- }
- },
- "node_modules/webidl-conversions": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
- "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
- "peer": true
- },
- "node_modules/whatwg-url": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
- "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
- "peer": true,
- "dependencies": {
- "tr46": "~0.0.3",
- "webidl-conversions": "^3.0.0"
- }
- },
- "node_modules/wonka": {
- "version": "4.0.15",
- "resolved": "https://registry.npmjs.org/wonka/-/wonka-4.0.15.tgz",
- "integrity": "sha512-U0IUQHKXXn6PFo9nqsHphVCE5m3IntqZNB9Jjn7EB1lrR7YTDY3YWgFvEvwniTzXSvOH/XMzAZaIfJF/LvHYXg=="
- },
- "node_modules/yallist": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
- "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
- "peer": true
- },
- "node_modules/yaml": {
- "version": "1.10.2",
- "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
- "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
- "engines": {
- "node": ">= 6"
- }
- }
- }
-}
diff --git a/dashboard/package.json b/dashboard/package.json
deleted file mode 100644
index 13b022e54..000000000
--- a/dashboard/package.json
+++ /dev/null
@@ -1,42 +0,0 @@
-{
- "name": "dashboard",
- "version": "1.0.0",
- "description": "",
- "main": "index.js",
- "scripts": {
- "build": "rm -rf build && NODE_ENV=production 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",
- "license": "ISC",
- "dependencies": {
- "@chakra-ui/react": "^1.7.3",
- "@emotion/core": "^11.0.0",
- "@emotion/react": "^11.7.1",
- "@emotion/styled": "^11.6.0",
- "@types/react": "^17.0.38",
- "@types/react-dom": "^17.0.11",
- "@types/react-router-dom": "^5.3.2",
- "dayjs": "^1.10.7",
- "esbuild": "^0.14.9",
- "focus-visible": "^5.2.0",
- "framer-motion": "^5.5.5",
- "graphql": "^16.2.0",
- "lodash": "^4.17.21",
- "react": "^17.0.2",
- "react-dom": "^17.0.2",
- "react-draft-wysiwyg": "^1.15.0",
- "react-dropzone": "^12.0.4",
- "react-email-editor": "^1.6.1",
- "react-icons": "^4.3.1",
- "react-router-dom": "^6.2.1",
- "typescript": "^4.5.4",
- "urql": "^2.0.6"
- },
- "devDependencies": {
- "@types/react-email-editor": "^1.1.7",
- "prettier": "2.7.1"
- }
-}
diff --git a/dashboard/src/index.tsx b/dashboard/src/index.tsx
deleted file mode 100644
index c463e63ea..000000000
--- a/dashboard/src/index.tsx
+++ /dev/null
@@ -1,10 +0,0 @@
-import React from 'react';
-import ReactDOM from 'react-dom';
-import App from './App';
-
-ReactDOM.render(
-
,
- document.getElementById('root'),
-);
diff --git a/dashboard/src/pages/Environment.tsx b/dashboard/src/pages/Environment.tsx
deleted file mode 100644
index f163c4fa3..000000000
--- a/dashboard/src/pages/Environment.tsx
+++ /dev/null
@@ -1,348 +0,0 @@
-import React, { useEffect } from 'react';
-import { useParams } from 'react-router-dom';
-import { Box, Flex, Stack, Button, useToast } from '@chakra-ui/react';
-import { useClient } from 'urql';
-import { FaSave } from 'react-icons/fa';
-import _ from 'lodash';
-import { EnvVariablesQuery } from '../graphql/queries';
-import {
- SelectInputType,
- HiddenInputType,
- TextInputType,
- HMACEncryptionType,
- RSAEncryptionType,
- ECDSAEncryptionType,
- envVarTypes,
- envSubViews,
-} from '../constants';
-import { UpdateEnvVariables } from '../graphql/mutation';
-import { getObjectDiff, capitalizeFirstLetter } from '../utils';
-import OAuthConfig from '../components/EnvComponents/OAuthConfig';
-import Roles from '../components/EnvComponents/Roles';
-import JWTConfigurations from '../components/EnvComponents/JWTConfiguration';
-import SessionStorage from '../components/EnvComponents/SessionStorage';
-import EmailConfigurations from '../components/EnvComponents/EmailConfiguration';
-import DomainWhiteListing from '../components/EnvComponents/DomainWhitelisting';
-import OrganizationInfo from '../components/EnvComponents/OrganizationInfo';
-import AccessToken from '../components/EnvComponents/AccessToken';
-import Features from '../components/EnvComponents/Features';
-import SecurityAdminSecret from '../components/EnvComponents/SecurityAdminSecret';
-import DatabaseCredentials from '../components/EnvComponents/DatabaseCredentials';
-
-const Environment = () => {
- const client = useClient();
- const toast = useToast();
- const [adminSecret, setAdminSecret] = React.useState<
- Record
- >({
- value: '',
- disableInputField: true,
- });
- const [loading, setLoading] = React.useState(true);
- const [envVariables, setEnvVariables] = React.useState({
- GOOGLE_CLIENT_ID: '',
- GOOGLE_CLIENT_SECRET: '',
- GITHUB_CLIENT_ID: '',
- GITHUB_CLIENT_SECRET: '',
- FACEBOOK_CLIENT_ID: '',
- FACEBOOK_CLIENT_SECRET: '',
- LINKEDIN_CLIENT_ID: '',
- LINKEDIN_CLIENT_SECRET: '',
- APPLE_CLIENT_ID: '',
- APPLE_CLIENT_SECRET: '',
- DISCORD_CLIENT_ID: '',
- DISCORD_CLIENT_SECRET: '',
- TWITTER_CLIENT_ID: '',
- TWITTER_CLIENT_SECRET: '',
- MICROSOFT_CLIENT_ID: '',
- MICROSOFT_CLIENT_SECRET: '',
- MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID: '',
- TWITCH_CLIENT_ID: '',
- TWITCH_CLIENT_SECRET: '',
- ROBLOX_CLIENT_ID: '',
- ROBLOX_CLIENT_SECRET: '',
- ROLES: [],
- DEFAULT_ROLES: [],
- PROTECTED_ROLES: [],
- JWT_TYPE: '',
- JWT_SECRET: '',
- JWT_ROLE_CLAIM: '',
- JWT_PRIVATE_KEY: '',
- JWT_PUBLIC_KEY: '',
- REDIS_URL: '',
- SMTP_HOST: '',
- SMTP_PORT: '',
- SMTP_USERNAME: '',
- SMTP_PASSWORD: '',
- SMTP_LOCAL_NAME: '',
- SENDER_EMAIL: '',
- SENDER_NAME: '',
- 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,
- DISABLE_BASIC_AUTHENTICATION: false,
- DISABLE_MOBILE_BASIC_AUTHENTICATION: false,
- DISABLE_SIGN_UP: false,
- DISABLE_STRONG_PASSWORD: false,
- OLD_ADMIN_SECRET: '',
- DATABASE_NAME: '',
- DATABASE_TYPE: '',
- DATABASE_URL: '',
- ACCESS_TOKEN_EXPIRY_TIME: '',
- DISABLE_MULTI_FACTOR_AUTHENTICATION: false,
- ENFORCE_MULTI_FACTOR_AUTHENTICATION: false,
- DEFAULT_AUTHORIZE_RESPONSE_TYPE: '',
- DEFAULT_AUTHORIZE_RESPONSE_MODE: '',
- DISABLE_PLAYGROUND: false,
- DISABLE_TOTP_LOGIN: false,
- DISABLE_MAIL_OTP_LOGIN: true,
- });
-
- const [fieldVisibility, setFieldVisibility] = React.useState<
- Record
- >({
- GOOGLE_CLIENT_SECRET: false,
- GITHUB_CLIENT_SECRET: false,
- FACEBOOK_CLIENT_SECRET: false,
- LINKEDIN_CLIENT_SECRET: false,
- APPLE_CLIENT_SECRET: false,
- DISCORD_CLIENT_SECRET: false,
- TWITTER_CLIENT_SECRET: false,
- TWITCH_CLIENT_SECRET: false,
- JWT_SECRET: false,
- SMTP_PASSWORD: false,
- ADMIN_SECRET: false,
- OLD_ADMIN_SECRET: false,
- });
-
- const { sec } = useParams();
-
- async function getData() {
- const {
- data: { _env: envData },
- } = await client.query(EnvVariablesQuery).toPromise();
- setLoading(false);
-
- setEnvVariables({
- ...envData,
- OLD_ADMIN_SECRET: envData.ADMIN_SECRET,
- ADMIN_SECRET: '',
- });
- setAdminSecret({
- value: '',
- disableInputField: true,
- });
- }
-
- useEffect(() => {
- getData();
- }, [sec]);
-
- const validateAdminSecretHandler = (event: any) => {
- if (envVariables.OLD_ADMIN_SECRET === event.target.value) {
- setAdminSecret({
- ...adminSecret,
- value: event.target.value,
- disableInputField: false,
- });
- } else {
- setAdminSecret({
- ...adminSecret,
- value: event.target.value,
- disableInputField: true,
- });
- }
- if (envVariables.ADMIN_SECRET !== '') {
- setEnvVariables({ ...envVariables, ADMIN_SECRET: '' });
- }
- };
-
- const saveHandler = async () => {
- setLoading(true);
- const {
- data: { _env: envData },
- } = await client.query(EnvVariablesQuery).toPromise();
- const diff = getObjectDiff(envVariables, envData);
- const updatedEnvVariables = diff.reduce(
- (acc: any, property: string) => ({
- ...acc,
- // @ts-ignore
- [property]: envVariables[property],
- }),
- {},
- );
- if (
- updatedEnvVariables[HiddenInputType.ADMIN_SECRET] === '' ||
- updatedEnvVariables[HiddenInputType.OLD_ADMIN_SECRET] !==
- envData.ADMIN_SECRET
- ) {
- delete updatedEnvVariables.OLD_ADMIN_SECRET;
- delete updatedEnvVariables.ADMIN_SECRET;
- }
-
- delete updatedEnvVariables.DATABASE_URL;
- delete updatedEnvVariables.DATABASE_TYPE;
- delete updatedEnvVariables.DATABASE_NAME;
-
- const res = await client
- .mutation(UpdateEnvVariables, { params: updatedEnvVariables })
- .toPromise();
-
- setLoading(false);
-
- if (res.error) {
- toast({
- title: capitalizeFirstLetter(res.error.message),
- isClosable: true,
- status: 'error',
- position: 'bottom-right',
- });
-
- return;
- }
-
- setAdminSecret({
- value: '',
- disableInputField: true,
- });
-
- getData();
-
- toast({
- title: `Successfully updated ${
- Object.keys(updatedEnvVariables).length
- } variables`,
- isClosable: true,
- status: 'success',
- position: 'top-right',
- });
- };
-
- const renderComponent = (tab: any) => {
- switch (tab) {
- case envSubViews.INSTANCE_INFO:
- return (
-
- );
- case envSubViews.ROLES:
- return (
-
- );
- case envSubViews.JWT_CONFIG:
- return (
-
- );
- case envSubViews.SESSION_STORAGE:
- return (
-
- );
- case envSubViews.EMAIL_CONFIG:
- return (
-
- );
- case envSubViews.WHITELIST_VARIABLES:
- return (
-
- );
- case envSubViews.ORGANIZATION_INFO:
- return (
-
- );
- case envSubViews.ACCESS_TOKEN:
- return (
-
- );
- case envSubViews.FEATURES:
- return (
-
- );
- case envSubViews.ADMIN_SECRET:
- return (
-
- );
- case envSubViews.DB_CRED:
- return (
-
- );
- default:
- return (
-
- );
- }
- };
- return (
-
- {renderComponent(sec)}
-
-
- }
- colorScheme="blue"
- variant="solid"
- onClick={saveHandler}
- isDisabled={loading}
- >
- Save
-
-
-
-
- );
-};
-
-export default Environment;
diff --git a/dashboard/yarn.lock b/dashboard/yarn.lock
deleted file mode 100644
index 641f7bfab..000000000
--- a/dashboard/yarn.lock
+++ /dev/null
@@ -1,1887 +0,0 @@
-# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
-# yarn lockfile v1
-
-
-"@ampproject/remapping@^2.2.0":
- version "2.2.1"
- resolved "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz"
- integrity sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==
- dependencies:
- "@jridgewell/gen-mapping" "^0.3.0"
- "@jridgewell/trace-mapping" "^0.3.9"
-
-"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.22.13":
- version "7.22.13"
- resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz"
- integrity sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==
- dependencies:
- "@babel/highlight" "^7.22.13"
- chalk "^2.4.2"
-
-"@babel/compat-data@^7.22.9":
- version "7.23.3"
- resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.3.tgz"
- integrity sha512-BmR4bWbDIoFJmJ9z2cZ8Gmm2MXgEDgjdWgpKmKWUt54UGFJdlj31ECtbaDvCG/qVdG3AQ1SfpZEs01lUFbzLOQ==
-
-"@babel/core@^7.0.0", "@babel/core@^7.0.0-0":
- version "7.23.3"
- resolved "https://registry.npmjs.org/@babel/core/-/core-7.23.3.tgz"
- integrity sha512-Jg+msLuNuCJDyBvFv5+OKOUjWMZgd85bKjbICd3zWrKAo+bJ49HJufi7CQE0q0uR8NGyO6xkCACScNqyjHSZew==
- dependencies:
- "@ampproject/remapping" "^2.2.0"
- "@babel/code-frame" "^7.22.13"
- "@babel/generator" "^7.23.3"
- "@babel/helper-compilation-targets" "^7.22.15"
- "@babel/helper-module-transforms" "^7.23.3"
- "@babel/helpers" "^7.23.2"
- "@babel/parser" "^7.23.3"
- "@babel/template" "^7.22.15"
- "@babel/traverse" "^7.23.3"
- "@babel/types" "^7.23.3"
- convert-source-map "^2.0.0"
- debug "^4.1.0"
- gensync "^1.0.0-beta.2"
- json5 "^2.2.3"
- semver "^6.3.1"
-
-"@babel/generator@^7.23.3":
- version "7.23.3"
- resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.23.3.tgz"
- integrity sha512-keeZWAV4LU3tW0qRi19HRpabC/ilM0HRBBzf9/k8FFiG4KVpiv0FIy4hHfLfFQZNhziCTPTmd59zoyv6DNISzg==
- dependencies:
- "@babel/types" "^7.23.3"
- "@jridgewell/gen-mapping" "^0.3.2"
- "@jridgewell/trace-mapping" "^0.3.17"
- jsesc "^2.5.1"
-
-"@babel/helper-compilation-targets@^7.22.15":
- version "7.22.15"
- resolved "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz"
- integrity sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==
- dependencies:
- "@babel/compat-data" "^7.22.9"
- "@babel/helper-validator-option" "^7.22.15"
- browserslist "^4.21.9"
- lru-cache "^5.1.1"
- semver "^6.3.1"
-
-"@babel/helper-environment-visitor@^7.22.20":
- version "7.22.20"
- resolved "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz"
- integrity sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==
-
-"@babel/helper-function-name@^7.23.0":
- version "7.23.0"
- resolved "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz"
- integrity sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==
- dependencies:
- "@babel/template" "^7.22.15"
- "@babel/types" "^7.23.0"
-
-"@babel/helper-hoist-variables@^7.22.5":
- version "7.22.5"
- resolved "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz"
- integrity sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==
- dependencies:
- "@babel/types" "^7.22.5"
-
-"@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.22.15":
- version "7.22.15"
- resolved "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz"
- integrity sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==
- dependencies:
- "@babel/types" "^7.22.15"
-
-"@babel/helper-module-transforms@^7.23.3":
- version "7.23.3"
- resolved "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz"
- integrity sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==
- dependencies:
- "@babel/helper-environment-visitor" "^7.22.20"
- "@babel/helper-module-imports" "^7.22.15"
- "@babel/helper-simple-access" "^7.22.5"
- "@babel/helper-split-export-declaration" "^7.22.6"
- "@babel/helper-validator-identifier" "^7.22.20"
-
-"@babel/helper-plugin-utils@^7.16.5":
- version "7.16.5"
- resolved "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.5.tgz"
- integrity sha512-59KHWHXxVA9K4HNF4sbHCf+eJeFe0Te/ZFGqBT4OjXhrwvA04sGfaEGsVTdsjoszq0YTP49RC9UKe5g8uN2RwQ==
-
-"@babel/helper-simple-access@^7.22.5":
- version "7.22.5"
- resolved "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz"
- integrity sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==
- dependencies:
- "@babel/types" "^7.22.5"
-
-"@babel/helper-split-export-declaration@^7.22.6":
- version "7.22.6"
- resolved "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz"
- integrity sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==
- dependencies:
- "@babel/types" "^7.22.5"
-
-"@babel/helper-string-parser@^7.22.5":
- version "7.22.5"
- resolved "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz"
- integrity sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==
-
-"@babel/helper-validator-identifier@^7.22.20":
- version "7.22.20"
- resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz"
- integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==
-
-"@babel/helper-validator-option@^7.22.15":
- version "7.22.15"
- resolved "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz"
- integrity sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==
-
-"@babel/helpers@^7.23.2":
- version "7.23.2"
- resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.2.tgz"
- integrity sha512-lzchcp8SjTSVe/fPmLwtWVBFC7+Tbn8LGHDVfDp9JGxpAY5opSaEFgt8UQvrnECWOTdji2mOWMz1rOhkHscmGQ==
- dependencies:
- "@babel/template" "^7.22.15"
- "@babel/traverse" "^7.23.2"
- "@babel/types" "^7.23.0"
-
-"@babel/highlight@^7.22.13":
- version "7.22.20"
- resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz"
- integrity sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==
- dependencies:
- "@babel/helper-validator-identifier" "^7.22.20"
- chalk "^2.4.2"
- js-tokens "^4.0.0"
-
-"@babel/parser@^7.22.15", "@babel/parser@^7.23.3":
- version "7.23.3"
- resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.23.3.tgz"
- integrity sha512-uVsWNvlVsIninV2prNz/3lHCb+5CJ+e+IUBfbjToAHODtfGYLfCFuY4AU7TskI+dAKk+njsPiBjq1gKTvZOBaw==
-
-"@babel/plugin-syntax-jsx@^7.12.13":
- version "7.16.5"
- resolved "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.16.5.tgz"
- integrity sha512-42OGssv9NPk4QHKVgIHlzeLgPOW5rGgfV5jzG90AhcXXIv6hu/eqj63w4VgvRxdvZY3AlYeDgPiSJ3BqAd1Y6Q==
- dependencies:
- "@babel/helper-plugin-utils" "^7.16.5"
-
-"@babel/runtime@^7.0.0", "@babel/runtime@^7.12.13", "@babel/runtime@^7.13.10", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6":
- version "7.16.5"
- resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.5.tgz"
- integrity sha512-TXWihFIS3Pyv5hzR7j6ihmeLkZfrXGxAr5UfSl8CHf+6q/wpiYDkUau0czckpYG8QmnCIuPpdLtuA9VmuGGyMA==
- dependencies:
- regenerator-runtime "^0.13.4"
-
-"@babel/template@^7.22.15":
- version "7.22.15"
- resolved "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz"
- integrity sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==
- dependencies:
- "@babel/code-frame" "^7.22.13"
- "@babel/parser" "^7.22.15"
- "@babel/types" "^7.22.15"
-
-"@babel/traverse@^7.23.2", "@babel/traverse@^7.23.3":
- version "7.23.3"
- resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.3.tgz"
- integrity sha512-+K0yF1/9yR0oHdE0StHuEj3uTPzwwbrLGfNOndVJVV2TqA5+j3oljJUb4nmB954FLGjNem976+B+eDuLIjesiQ==
- dependencies:
- "@babel/code-frame" "^7.22.13"
- "@babel/generator" "^7.23.3"
- "@babel/helper-environment-visitor" "^7.22.20"
- "@babel/helper-function-name" "^7.23.0"
- "@babel/helper-hoist-variables" "^7.22.5"
- "@babel/helper-split-export-declaration" "^7.22.6"
- "@babel/parser" "^7.23.3"
- "@babel/types" "^7.23.3"
- debug "^4.1.0"
- globals "^11.1.0"
-
-"@babel/types@^7.22.15", "@babel/types@^7.22.5", "@babel/types@^7.23.0", "@babel/types@^7.23.3":
- version "7.23.3"
- resolved "https://registry.npmjs.org/@babel/types/-/types-7.23.3.tgz"
- integrity sha512-OZnvoH2l8PK5eUvEcUyCt/sXgr/h+UWpVuBbOljwcrAgUl6lpchoQ++PHGyQy1AtYnVA6CEq3y5xeEI10brpXw==
- dependencies:
- "@babel/helper-string-parser" "^7.22.5"
- "@babel/helper-validator-identifier" "^7.22.20"
- to-fast-properties "^2.0.0"
-
-"@chakra-ui/accordion@1.4.2":
- version "1.4.2"
- resolved "https://registry.npmjs.org/@chakra-ui/accordion/-/accordion-1.4.2.tgz"
- integrity sha512-BAGMvcm2sFE5Ft7jwC9nF03/Yv7qztuhzwKBBy4iL0p1nCPh6kV54RBXUcoj3VWe+yrmNiAVYKRTdqQBTJFwOw==
- dependencies:
- "@chakra-ui/descendant" "2.1.1"
- "@chakra-ui/hooks" "1.7.1"
- "@chakra-ui/icon" "2.0.0"
- "@chakra-ui/react-utils" "1.2.1"
- "@chakra-ui/transition" "1.4.2"
- "@chakra-ui/utils" "1.9.1"
-
-"@chakra-ui/alert@1.3.2":
- version "1.3.2"
- resolved "https://registry.npmjs.org/@chakra-ui/alert/-/alert-1.3.2.tgz"
- integrity sha512-+OMeVeGtydpj6nry0zH7qFDt36zEaxckRnufx1BGiCfWdUg6ahVwKXl8qX93Q8w82od7eAoBKMgGJz7IVL5NPw==
- dependencies:
- "@chakra-ui/icon" "2.0.0"
- "@chakra-ui/react-utils" "1.2.1"
- "@chakra-ui/utils" "1.9.1"
-
-"@chakra-ui/anatomy@1.2.1":
- version "1.2.1"
- resolved "https://registry.npmjs.org/@chakra-ui/anatomy/-/anatomy-1.2.1.tgz"
- integrity sha512-kNS+FiEDTSnwpQUW4dEjZ5745xhkvB0XtmqjY1wpclUSpFfptLZM9QIHPTnBt2bzM9R+idmRRP+WkTt6kyTrLw==
- dependencies:
- "@chakra-ui/theme-tools" "^1.3.1"
-
-"@chakra-ui/avatar@1.3.1":
- version "1.3.1"
- resolved "https://registry.npmjs.org/@chakra-ui/avatar/-/avatar-1.3.1.tgz"
- integrity sha512-WI0/kcpTJViOH093V0bz8EB+e/rc+gjF+T5DkOuh1YWFxRRG5v+4Yd3PdEJtQgzWtBVhlbGWmE7WvBizyKwFCA==
- dependencies:
- "@chakra-ui/image" "1.1.1"
- "@chakra-ui/react-utils" "1.2.1"
- "@chakra-ui/utils" "1.9.1"
-
-"@chakra-ui/breadcrumb@1.3.1":
- version "1.3.1"
- resolved "https://registry.npmjs.org/@chakra-ui/breadcrumb/-/breadcrumb-1.3.1.tgz"
- integrity sha512-b1IoBmtr5FcP2fn5NRbdOdQo2c866OQ/WhcTcZ6UKae1jjik+36/qWE+X+RKzxC6FLfqo5qayV5zSgsnZym7Pg==
- dependencies:
- "@chakra-ui/react-utils" "1.2.1"
- "@chakra-ui/utils" "1.9.1"
-
-"@chakra-ui/button@1.5.1":
- version "1.5.1"
- resolved "https://registry.npmjs.org/@chakra-ui/button/-/button-1.5.1.tgz"
- integrity sha512-BvP29quEhP6OTgDiRsugD6adgkeOTEQpoDsZUVEmHnNVrbFfdsICEKKQTtDJ2iPf+hmpFrtnpN50vCLdAANKcw==
- dependencies:
- "@chakra-ui/hooks" "1.7.1"
- "@chakra-ui/react-utils" "1.2.1"
- "@chakra-ui/spinner" "1.2.1"
- "@chakra-ui/utils" "1.9.1"
-
-"@chakra-ui/checkbox@1.6.1":
- version "1.6.1"
- resolved "https://registry.npmjs.org/@chakra-ui/checkbox/-/checkbox-1.6.1.tgz"
- integrity sha512-Z5ZMeUYIRjRbi/knhYhSQshZH7OnROA7ezl9a9oVSKRF7iLMNMibQSlQLXmqUWaTKSgrS37cpKAzfgEuemyiUQ==
- dependencies:
- "@chakra-ui/hooks" "1.7.1"
- "@chakra-ui/react-utils" "1.2.1"
- "@chakra-ui/utils" "1.9.1"
- "@chakra-ui/visually-hidden" "1.1.1"
-
-"@chakra-ui/clickable@1.2.1":
- version "1.2.1"
- resolved "https://registry.npmjs.org/@chakra-ui/clickable/-/clickable-1.2.1.tgz"
- integrity sha512-B0CIbKzDMwzG1APeTpW9H2Jl8dkarI1Qstb3hDOy23O+N5TU6lpDdVnXQ7fpFJS6mu5JjFqtkwzGAVZnkkv1rw==
- dependencies:
- "@chakra-ui/react-utils" "1.2.1"
- "@chakra-ui/utils" "1.9.1"
-
-"@chakra-ui/close-button@1.2.2":
- version "1.2.2"
- resolved "https://registry.npmjs.org/@chakra-ui/close-button/-/close-button-1.2.2.tgz"
- integrity sha512-SqeLib0qgMjK3OsO1g5OnAHUmdCC8GMjToNEea7TeSrA44bH9EXVhFTkMMu2PnDVHbQmi4Ee1cuulNJt0UhQ3g==
- dependencies:
- "@chakra-ui/icon" "2.0.0"
- "@chakra-ui/utils" "1.9.1"
-
-"@chakra-ui/color-mode@1.3.2":
- version "1.3.2"
- resolved "https://registry.npmjs.org/@chakra-ui/color-mode/-/color-mode-1.3.2.tgz"
- integrity sha512-/rWcbrzbaWCyyUnT07Qjz0xf/ltHS31CHOKtVCWr2uTgfn2gOQpdxsKRbjrLYPOYZGTMdINUHNiAsqQjLoAoTQ==
- dependencies:
- "@chakra-ui/hooks" "1.7.1"
- "@chakra-ui/react-env" "1.1.1"
- "@chakra-ui/utils" "1.9.1"
-
-"@chakra-ui/control-box@1.1.1":
- version "1.1.1"
- resolved "https://registry.npmjs.org/@chakra-ui/control-box/-/control-box-1.1.1.tgz"
- integrity sha512-ZFbh85pzzZoiSjGnvLUzMB5BoA8Xm6TBMWvMtzLY5xiFGb9/mBeRDH2KFjr1GJzoqleWKkQwvFD6JM0kXcekpg==
- dependencies:
- "@chakra-ui/utils" "1.9.1"
-
-"@chakra-ui/counter@1.2.1":
- version "1.2.1"
- resolved "https://registry.npmjs.org/@chakra-ui/counter/-/counter-1.2.1.tgz"
- integrity sha512-Gm4njMzEsDyAzdQtExn40TvmupzkPBrT5DiCu0DlxYqpLqCfqV49HgJHEG5oW3WV+WaC9mzg7VV+idKYh/d+Gg==
- dependencies:
- "@chakra-ui/hooks" "1.7.1"
- "@chakra-ui/utils" "1.9.1"
-
-"@chakra-ui/css-reset@1.1.1":
- version "1.1.1"
- resolved "https://registry.npmjs.org/@chakra-ui/css-reset/-/css-reset-1.1.1.tgz"
- integrity sha512-+KNNHL4OWqeKia5SL858K3Qbd8WxMij9mWIilBzLD4j2KFrl/+aWFw8syMKth3NmgIibrjsljo+PU3fy2o50dg==
-
-"@chakra-ui/descendant@2.1.1":
- version "2.1.1"
- resolved "https://registry.npmjs.org/@chakra-ui/descendant/-/descendant-2.1.1.tgz"
- integrity sha512-JasdVaN4MjL7QFo1vMnADy6EtFAlPKT1kTJ1LwMtl9AaF9VFLBsfGxm0L+WQK+3NJMuCSDBXWJB8mV4AQ11Edg==
- dependencies:
- "@chakra-ui/react-utils" "^1.2.1"
-
-"@chakra-ui/editable@1.3.1":
- version "1.3.1"
- resolved "https://registry.npmjs.org/@chakra-ui/editable/-/editable-1.3.1.tgz"
- integrity sha512-MwyTtsnHNqmKmHv9SH3KIHWa06D4gBwcuTawTiSnYBUJL6My8ry/Wdca1to9So2tD6hcjz3TPTzOJOlyv0eiZg==
- dependencies:
- "@chakra-ui/hooks" "1.7.1"
- "@chakra-ui/react-utils" "1.2.1"
- "@chakra-ui/utils" "1.9.1"
-
-"@chakra-ui/focus-lock@1.2.1":
- version "1.2.1"
- resolved "https://registry.npmjs.org/@chakra-ui/focus-lock/-/focus-lock-1.2.1.tgz"
- integrity sha512-HYu39nvfaXUrBx+dIDJkFgebNCGEi9oZTfLUKzIJC+zPkmReTDSXV0dzSb/8vCAOq5fph1gFKsdbGy2U98P8GQ==
- dependencies:
- "@chakra-ui/utils" "1.9.1"
- react-focus-lock "2.5.2"
-
-"@chakra-ui/form-control@1.5.2":
- version "1.5.2"
- resolved "https://registry.npmjs.org/@chakra-ui/form-control/-/form-control-1.5.2.tgz"
- integrity sha512-uWv0/f+JEM0ZE5Hnj3TzCnJ09EB+A+DSs9QgyECOuxx9Ju6gnns2uaRki2BfxksQL9ZZomPCkMtXazY9Wa81ag==
- dependencies:
- "@chakra-ui/hooks" "1.7.1"
- "@chakra-ui/icon" "2.0.0"
- "@chakra-ui/react-utils" "1.2.1"
- "@chakra-ui/utils" "1.9.1"
-
-"@chakra-ui/hooks@1.7.1":
- version "1.7.1"
- resolved "https://registry.npmjs.org/@chakra-ui/hooks/-/hooks-1.7.1.tgz"
- integrity sha512-hgN19X6GUKQYAHczmFY+GAT8vl9h+X+nGWrIAnmvZ6BgUXxDajnTNhZeWhj0ZkR+7A7dCE6Y/3X44GafUgChMw==
- dependencies:
- "@chakra-ui/react-utils" "1.2.1"
- "@chakra-ui/utils" "1.9.1"
- compute-scroll-into-view "1.0.14"
- copy-to-clipboard "3.3.1"
-
-"@chakra-ui/icon@2.0.0":
- version "2.0.0"
- resolved "https://registry.npmjs.org/@chakra-ui/icon/-/icon-2.0.0.tgz"
- integrity sha512-/GuU+xIcOIy9uSUUUCu249ZJB/nLDbjWGkfpoSdBwqT4+ytJrKt+0Ckh3Ub14sz3BJD+Z6IiIt6ySOA9+7lbsA==
- dependencies:
- "@chakra-ui/utils" "1.9.1"
-
-"@chakra-ui/image@1.1.1":
- version "1.1.1"
- resolved "https://registry.npmjs.org/@chakra-ui/image/-/image-1.1.1.tgz"
- integrity sha512-bz1pn08XlXcO3r1KnpdjQgN3R2soiTx10sG2d5Pw9BdGdySf7Y73wiLh+Tan1xJHp6p2KH1hz4f7uKXXDn7Qmw==
- dependencies:
- "@chakra-ui/hooks" "1.7.1"
- "@chakra-ui/utils" "1.9.1"
-
-"@chakra-ui/input@1.3.2":
- version "1.3.2"
- resolved "https://registry.npmjs.org/@chakra-ui/input/-/input-1.3.2.tgz"
- integrity sha512-VMxmQgFiQ2UnBlkgLX/336G0IfYfw8YWF2ZoEFj5WL9kDSrrL1FXSBgjFGxrper74G4W20tESBCfU1S891y6cg==
- dependencies:
- "@chakra-ui/form-control" "1.5.2"
- "@chakra-ui/react-utils" "1.2.1"
- "@chakra-ui/utils" "1.9.1"
-
-"@chakra-ui/layout@1.6.0":
- version "1.6.0"
- resolved "https://registry.npmjs.org/@chakra-ui/layout/-/layout-1.6.0.tgz"
- integrity sha512-WUfQ104y1wNueU33/hPlZsMzYJGjO0dXMpVkQf5ZNhNX3IGDO+5+MO2x2xloP+j45yNPi3p8ti/HBnm3dXI+3Q==
- dependencies:
- "@chakra-ui/icon" "2.0.0"
- "@chakra-ui/react-utils" "1.2.1"
- "@chakra-ui/utils" "1.9.1"
-
-"@chakra-ui/live-region@1.1.1":
- version "1.1.1"
- resolved "https://registry.npmjs.org/@chakra-ui/live-region/-/live-region-1.1.1.tgz"
- integrity sha512-BSdI5gLIffNRETEp6W18kBNg9tL0ZLLzfWGRnuO9tEbox7NrcgqIeLF8mNKwhDOZz88NKHtUOPVzjAUKW1SryQ==
- dependencies:
- "@chakra-ui/utils" "1.9.1"
-
-"@chakra-ui/media-query@1.2.2":
- version "1.2.2"
- resolved "https://registry.npmjs.org/@chakra-ui/media-query/-/media-query-1.2.2.tgz"
- integrity sha512-xSmDVleE1drWiGH/MX3RqyVm29x/8Vf6G0UGaI2kCpbNmon+Q1zHW/yDHvptIuctLrPHYO8LOBxuUjfnIXwC2g==
- dependencies:
- "@chakra-ui/react-env" "1.1.1"
- "@chakra-ui/utils" "1.9.1"
-
-"@chakra-ui/menu@1.8.2":
- version "1.8.2"
- resolved "https://registry.npmjs.org/@chakra-ui/menu/-/menu-1.8.2.tgz"
- integrity sha512-u2GfkwTqbWa8L/7i/kOFbU3JANiT2HStR+gsYKuiuOPiuBcUb8OlgfJfP70OtVKegNKmVEMjvzXtld3wCCo/1g==
- dependencies:
- "@chakra-ui/clickable" "1.2.1"
- "@chakra-ui/descendant" "2.1.1"
- "@chakra-ui/hooks" "1.7.1"
- "@chakra-ui/popper" "2.4.1"
- "@chakra-ui/react-utils" "1.2.1"
- "@chakra-ui/transition" "1.4.2"
- "@chakra-ui/utils" "1.9.1"
-
-"@chakra-ui/modal@1.10.2":
- version "1.10.2"
- resolved "https://registry.npmjs.org/@chakra-ui/modal/-/modal-1.10.2.tgz"
- integrity sha512-ZlmYetPHwHW4CAM09j4/+Ui54dXR1nzU6mOwhWe4/IzLvEyoEU6fHJeKyGxVUpYTG/7wltG/wKFRJpYa77tiBg==
- dependencies:
- "@chakra-ui/close-button" "1.2.2"
- "@chakra-ui/focus-lock" "1.2.1"
- "@chakra-ui/hooks" "1.7.1"
- "@chakra-ui/portal" "1.3.1"
- "@chakra-ui/react-utils" "1.2.1"
- "@chakra-ui/transition" "1.4.2"
- "@chakra-ui/utils" "1.9.1"
- aria-hidden "^1.1.1"
- react-remove-scroll "2.4.1"
-
-"@chakra-ui/number-input@1.3.2":
- version "1.3.2"
- resolved "https://registry.npmjs.org/@chakra-ui/number-input/-/number-input-1.3.2.tgz"
- integrity sha512-7x7AoqwPXU1odyDcqIwjBwf0MJUwYMM2fa+6YZ52F941GKlvkDiiJOhK6xfhhBzkLUQD6DN8zgAmmGhaZ6UQXw==
- dependencies:
- "@chakra-ui/counter" "1.2.1"
- "@chakra-ui/form-control" "1.5.2"
- "@chakra-ui/hooks" "1.7.1"
- "@chakra-ui/icon" "2.0.0"
- "@chakra-ui/react-utils" "1.2.1"
- "@chakra-ui/utils" "1.9.1"
-
-"@chakra-ui/pin-input@1.7.1":
- version "1.7.1"
- resolved "https://registry.npmjs.org/@chakra-ui/pin-input/-/pin-input-1.7.1.tgz"
- integrity sha512-eFFc5sofiyion+NxELWfCzD23XHIBDrJcfKKbNxt8jdXg9Ek4mFpmvnxBVrK0DIz6cVYgKY8c364OmxNUf4IyA==
- dependencies:
- "@chakra-ui/descendant" "2.1.1"
- "@chakra-ui/hooks" "1.7.1"
- "@chakra-ui/react-utils" "1.2.1"
- "@chakra-ui/utils" "1.9.1"
-
-"@chakra-ui/popover@1.11.0":
- version "1.11.0"
- resolved "https://registry.npmjs.org/@chakra-ui/popover/-/popover-1.11.0.tgz"
- integrity sha512-cCHXAfhIRir+M0ehlYIjDw3mHpiCxDTJ9WV0H1zHQV8nDYVIlZw3nEntaq8oJrv0wpIzq2WCW5ss+bBR7nLZ1A==
- dependencies:
- "@chakra-ui/close-button" "1.2.2"
- "@chakra-ui/hooks" "1.7.1"
- "@chakra-ui/popper" "2.4.1"
- "@chakra-ui/react-utils" "1.2.1"
- "@chakra-ui/utils" "1.9.1"
-
-"@chakra-ui/popper@2.4.1":
- version "2.4.1"
- resolved "https://registry.npmjs.org/@chakra-ui/popper/-/popper-2.4.1.tgz"
- integrity sha512-cuwnwXx6RUXZGGynVOGG8fEIiMNBXUCy3UqWQD1eEd8200eWQobgNk4Z0YwzKuSzJwp0Auy+j5iKefi5FSkyog==
- dependencies:
- "@chakra-ui/react-utils" "1.2.1"
- "@popperjs/core" "^2.9.3"
-
-"@chakra-ui/portal@1.3.1":
- version "1.3.1"
- resolved "https://registry.npmjs.org/@chakra-ui/portal/-/portal-1.3.1.tgz"
- integrity sha512-6UOGZCfujgdijcPs/JTEY5IB5WtKvUbfrSQYsG5CDa+guIwvnoP5qZ+rH6BR6DSSM8Wr/1n+WrtanhfFZShHKA==
- dependencies:
- "@chakra-ui/hooks" "1.7.1"
- "@chakra-ui/react-utils" "1.2.1"
- "@chakra-ui/utils" "1.9.1"
-
-"@chakra-ui/progress@1.2.1":
- version "1.2.1"
- resolved "https://registry.npmjs.org/@chakra-ui/progress/-/progress-1.2.1.tgz"
- integrity sha512-213nN8nbODvD/A23vAtg+r3bRKKatWQHafgmLzeznUcxa/+ac0eVurIS8XSYLRkY4EXQ505re3ZkLhDd98a7QA==
- dependencies:
- "@chakra-ui/theme-tools" "1.3.1"
- "@chakra-ui/utils" "1.9.1"
-
-"@chakra-ui/provider@1.7.3":
- version "1.7.3"
- resolved "https://registry.npmjs.org/@chakra-ui/provider/-/provider-1.7.3.tgz"
- integrity sha512-D1SrQ7do4yzAv9/OTF3yj/BkLm7kFo5DdeuOCyvXGpVJumnvbtjltRmC7rFQH4R+y9qXPvfQP4LKMNBqSxPNng==
- dependencies:
- "@chakra-ui/css-reset" "1.1.1"
- "@chakra-ui/hooks" "1.7.1"
- "@chakra-ui/portal" "1.3.1"
- "@chakra-ui/react-env" "1.1.1"
- "@chakra-ui/system" "1.8.3"
- "@chakra-ui/utils" "1.9.1"
-
-"@chakra-ui/radio@1.4.3":
- version "1.4.3"
- resolved "https://registry.npmjs.org/@chakra-ui/radio/-/radio-1.4.3.tgz"
- integrity sha512-TQdyfdUD3BLklOP67n82JN8ksQv1BYjvaYsK0m6WCa0LDJr9aCC+XtUPgVq/1L2t4HqHdiGOrGBooF4vvy/+BA==
- dependencies:
- "@chakra-ui/form-control" "1.5.2"
- "@chakra-ui/hooks" "1.7.1"
- "@chakra-ui/react-utils" "1.2.1"
- "@chakra-ui/utils" "1.9.1"
- "@chakra-ui/visually-hidden" "1.1.1"
-
-"@chakra-ui/react-env@1.1.1":
- version "1.1.1"
- resolved "https://registry.npmjs.org/@chakra-ui/react-env/-/react-env-1.1.1.tgz"
- integrity sha512-Lgmb0y4kv0ffsGMelAOaYOd4tYZAv4FYWgV86ckGMjmYQWA8drv4v/lHTNltixxWMmBEpjcHALpJuS6yAZYHug==
- dependencies:
- "@chakra-ui/utils" "1.9.1"
-
-"@chakra-ui/react-utils@^1.2.1", "@chakra-ui/react-utils@1.2.1":
- version "1.2.1"
- resolved "https://registry.npmjs.org/@chakra-ui/react-utils/-/react-utils-1.2.1.tgz"
- integrity sha512-bV8FRaXiOgGxOg03iTNin/B02I+tHH9PQtqUTl3U7cJaoI+5AUYhrqXvl1Ya2/R7zxSFrb/gBVDTgbZiVkJ+Dg==
- dependencies:
- "@chakra-ui/utils" "^1.9.1"
-
-"@chakra-ui/react@^1.7.3":
- version "1.7.3"
- resolved "https://registry.npmjs.org/@chakra-ui/react/-/react-1.7.3.tgz"
- integrity sha512-6mrfDUOa9MoQ44Xvi7xgdDq48jTTTjW9BupCGf2R3DI+z6RbUKIHzbcoDJZt2HGY6j9EarMVNRoQJzvzGUKpoQ==
- dependencies:
- "@chakra-ui/accordion" "1.4.2"
- "@chakra-ui/alert" "1.3.2"
- "@chakra-ui/avatar" "1.3.1"
- "@chakra-ui/breadcrumb" "1.3.1"
- "@chakra-ui/button" "1.5.1"
- "@chakra-ui/checkbox" "1.6.1"
- "@chakra-ui/close-button" "1.2.2"
- "@chakra-ui/control-box" "1.1.1"
- "@chakra-ui/counter" "1.2.1"
- "@chakra-ui/css-reset" "1.1.1"
- "@chakra-ui/editable" "1.3.1"
- "@chakra-ui/form-control" "1.5.2"
- "@chakra-ui/hooks" "1.7.1"
- "@chakra-ui/icon" "2.0.0"
- "@chakra-ui/image" "1.1.1"
- "@chakra-ui/input" "1.3.2"
- "@chakra-ui/layout" "1.6.0"
- "@chakra-ui/live-region" "1.1.1"
- "@chakra-ui/media-query" "1.2.2"
- "@chakra-ui/menu" "1.8.2"
- "@chakra-ui/modal" "1.10.2"
- "@chakra-ui/number-input" "1.3.2"
- "@chakra-ui/pin-input" "1.7.1"
- "@chakra-ui/popover" "1.11.0"
- "@chakra-ui/popper" "2.4.1"
- "@chakra-ui/portal" "1.3.1"
- "@chakra-ui/progress" "1.2.1"
- "@chakra-ui/provider" "1.7.3"
- "@chakra-ui/radio" "1.4.3"
- "@chakra-ui/react-env" "1.1.1"
- "@chakra-ui/select" "1.2.2"
- "@chakra-ui/skeleton" "1.2.3"
- "@chakra-ui/slider" "1.5.2"
- "@chakra-ui/spinner" "1.2.1"
- "@chakra-ui/stat" "1.2.2"
- "@chakra-ui/switch" "1.3.1"
- "@chakra-ui/system" "1.8.3"
- "@chakra-ui/table" "1.3.1"
- "@chakra-ui/tabs" "1.6.1"
- "@chakra-ui/tag" "1.2.2"
- "@chakra-ui/textarea" "1.2.2"
- "@chakra-ui/theme" "1.12.2"
- "@chakra-ui/toast" "1.5.0"
- "@chakra-ui/tooltip" "1.4.2"
- "@chakra-ui/transition" "1.4.2"
- "@chakra-ui/utils" "1.9.1"
- "@chakra-ui/visually-hidden" "1.1.1"
-
-"@chakra-ui/select@1.2.2":
- version "1.2.2"
- resolved "https://registry.npmjs.org/@chakra-ui/select/-/select-1.2.2.tgz"
- integrity sha512-EchJW3St1DtSWHe//DHwKjGsQYL2zbKcNCLnJWQKGMPZsQhAD2wsm4xjowFrV8AkY7jbVM/U2v68puN7YTC3hg==
- dependencies:
- "@chakra-ui/form-control" "1.5.2"
- "@chakra-ui/utils" "1.9.1"
-
-"@chakra-ui/skeleton@1.2.3":
- version "1.2.3"
- resolved "https://registry.npmjs.org/@chakra-ui/skeleton/-/skeleton-1.2.3.tgz"
- integrity sha512-u5ASkzPiBjfvKxKuBienUfmyYDTHziSWQ8Ny6k83LbwLv9IcmBNGsSkmsp7hesgi9cMHGBQ3hY2GTqG9ljndIg==
- dependencies:
- "@chakra-ui/hooks" "1.7.1"
- "@chakra-ui/media-query" "1.2.2"
- "@chakra-ui/system" "1.8.3"
- "@chakra-ui/utils" "1.9.1"
-
-"@chakra-ui/slider@1.5.2":
- version "1.5.2"
- resolved "https://registry.npmjs.org/@chakra-ui/slider/-/slider-1.5.2.tgz"
- integrity sha512-zP07TMew61GkJe47Nu7zEg/SUEwPHpN4alW6VUM6Y8UaVpQaDx7InarbWTc/bXdTP03SfE+hQ6WD9Oy7noe4hQ==
- dependencies:
- "@chakra-ui/hooks" "1.7.1"
- "@chakra-ui/react-utils" "1.2.1"
- "@chakra-ui/utils" "1.9.1"
-
-"@chakra-ui/spinner@1.2.1":
- version "1.2.1"
- resolved "https://registry.npmjs.org/@chakra-ui/spinner/-/spinner-1.2.1.tgz"
- integrity sha512-CQsUJNJWWSot1ku5Se41Nz1dXIDhk+/7FIhTbfRHSjtYZnAab3CPMHBkTGqwbJxQ9oHYgk9Rso3cfG+/ra6aTQ==
- dependencies:
- "@chakra-ui/utils" "1.9.1"
- "@chakra-ui/visually-hidden" "1.1.1"
-
-"@chakra-ui/stat@1.2.2":
- version "1.2.2"
- resolved "https://registry.npmjs.org/@chakra-ui/stat/-/stat-1.2.2.tgz"
- integrity sha512-0StsPDC56MjzhdlBl0R8wU0uwj9L1tvhQzge/ELSDn4tQDI7VovrxpFzVH0qsj7EZDwZa0BRQaSrstzWvgmJ/Q==
- dependencies:
- "@chakra-ui/icon" "2.0.0"
- "@chakra-ui/utils" "1.9.1"
- "@chakra-ui/visually-hidden" "1.1.1"
-
-"@chakra-ui/styled-system@1.15.0":
- version "1.15.0"
- resolved "https://registry.npmjs.org/@chakra-ui/styled-system/-/styled-system-1.15.0.tgz"
- integrity sha512-LnsKeiYkUuJ+NMTwueiX0Mj8CW9XAMJrJxpQm/X3GY5L5PO7Hv6wW725Ovqdy4mhG3IK7S8444FthpsDv/luHw==
- dependencies:
- "@chakra-ui/utils" "1.9.1"
- csstype "^3.0.9"
-
-"@chakra-ui/switch@1.3.1":
- version "1.3.1"
- resolved "https://registry.npmjs.org/@chakra-ui/switch/-/switch-1.3.1.tgz"
- integrity sha512-92hXJ2/ozj7B3cJNT259mFNoad7Ck892uHTuEQ/GIdXb25doE6F1wCp0TreOnGiEgU5YSaxpdrcZjA0QODP//w==
- dependencies:
- "@chakra-ui/checkbox" "1.6.1"
- "@chakra-ui/utils" "1.9.1"
-
-"@chakra-ui/system@>=1.0.0", "@chakra-ui/system@1.8.3":
- version "1.8.3"
- resolved "https://registry.npmjs.org/@chakra-ui/system/-/system-1.8.3.tgz"
- integrity sha512-6MaevsT7A2ifgOGQQCQsfvzPVd0kEXqFrX1Oxd842bawaqthmbFdo2bBTdaia/+Ivq/8Xot2uAQSbU+3NuRiUA==
- dependencies:
- "@chakra-ui/color-mode" "1.3.2"
- "@chakra-ui/react-utils" "1.2.1"
- "@chakra-ui/styled-system" "1.15.0"
- "@chakra-ui/utils" "1.9.1"
- react-fast-compare "3.2.0"
-
-"@chakra-ui/table@1.3.1":
- version "1.3.1"
- resolved "https://registry.npmjs.org/@chakra-ui/table/-/table-1.3.1.tgz"
- integrity sha512-+ia/7zs7AGj01lon301EEx+mK4918yGc0K6e68Kxomex8tnxkwbskFWs6hX+6Kzbj56ZBm99eLlKpo2iGYX0HA==
- dependencies:
- "@chakra-ui/utils" "1.9.1"
-
-"@chakra-ui/tabs@1.6.1":
- version "1.6.1"
- resolved "https://registry.npmjs.org/@chakra-ui/tabs/-/tabs-1.6.1.tgz"
- integrity sha512-p7HdHcleJWNwteWYVPt2KF52YbS5pIIfs/IpgtnYZRsJbqvRVxSwgg5Wsn+vuxFXBKW0cA2rDGbyzsZ+ChtEXQ==
- dependencies:
- "@chakra-ui/clickable" "1.2.1"
- "@chakra-ui/descendant" "2.1.1"
- "@chakra-ui/hooks" "1.7.1"
- "@chakra-ui/react-utils" "1.2.1"
- "@chakra-ui/utils" "1.9.1"
-
-"@chakra-ui/tag@1.2.2":
- version "1.2.2"
- resolved "https://registry.npmjs.org/@chakra-ui/tag/-/tag-1.2.2.tgz"
- integrity sha512-H25y9nEyUAUdwQDND9P4mMXKf1wf9UH4A3DyP237qVKIyYBpa4aCH8eJU4dunh2yIzASB0DWcr7lsul/HAHxmg==
- dependencies:
- "@chakra-ui/icon" "2.0.0"
- "@chakra-ui/utils" "1.9.1"
-
-"@chakra-ui/textarea@1.2.2":
- version "1.2.2"
- resolved "https://registry.npmjs.org/@chakra-ui/textarea/-/textarea-1.2.2.tgz"
- integrity sha512-DoLdKxHk0DyrQDnj1la9wjl2AW3/SK62nfWDYLAm0ouFsw1VKPw9nU+Yyj0dPruQTzI19nLaYF26i97rtnT27g==
- dependencies:
- "@chakra-ui/form-control" "1.5.2"
- "@chakra-ui/utils" "1.9.1"
-
-"@chakra-ui/theme-tools@^1.3.1", "@chakra-ui/theme-tools@1.3.1":
- version "1.3.1"
- resolved "https://registry.npmjs.org/@chakra-ui/theme-tools/-/theme-tools-1.3.1.tgz"
- integrity sha512-D8arJ5uFGuYZrrFGpXqgov8FhsJYWRyar5oBZY5TJR9gsVYBlJ8Ai91pwM/NflCFqzerTOgyt7bNSGQMdZ8ghA==
- dependencies:
- "@chakra-ui/utils" "1.9.1"
- "@ctrl/tinycolor" "^3.4.0"
-
-"@chakra-ui/theme@>=1.0.0", "@chakra-ui/theme@1.12.2":
- version "1.12.2"
- resolved "https://registry.npmjs.org/@chakra-ui/theme/-/theme-1.12.2.tgz"
- integrity sha512-LVjSf16yYHD40ILrsDEd3idVQRvJSY7JY8lvTGWo2p6v+JQESWF+zXlYi9Le+TXRpZuFvJuuQ1SEvoqVwdcJ8Q==
- dependencies:
- "@chakra-ui/anatomy" "1.2.1"
- "@chakra-ui/theme-tools" "1.3.1"
- "@chakra-ui/utils" "1.9.1"
-
-"@chakra-ui/toast@1.5.0":
- version "1.5.0"
- resolved "https://registry.npmjs.org/@chakra-ui/toast/-/toast-1.5.0.tgz"
- integrity sha512-rTsFx/Qos5oVPN6aZMbT/wTxwZlFNSXQqrTpJYaRcRFQGzxIDDxmGkKYfPnyJjRP9i6EqynJhXEIyhMA0xO0dw==
- dependencies:
- "@chakra-ui/alert" "1.3.2"
- "@chakra-ui/close-button" "1.2.2"
- "@chakra-ui/hooks" "1.7.1"
- "@chakra-ui/theme" "1.12.2"
- "@chakra-ui/transition" "1.4.2"
- "@chakra-ui/utils" "1.9.1"
- "@reach/alert" "0.13.2"
-
-"@chakra-ui/tooltip@1.4.2":
- version "1.4.2"
- resolved "https://registry.npmjs.org/@chakra-ui/tooltip/-/tooltip-1.4.2.tgz"
- integrity sha512-+wyYXG8qenKkFy2YSFfOBf3rlWADnu6S9EUxP+3Rmm78unOWXDuTJWzqy2QlXs2BwoQoifaz1LVwzmMb7WLVgQ==
- dependencies:
- "@chakra-ui/hooks" "1.7.1"
- "@chakra-ui/popper" "2.4.1"
- "@chakra-ui/portal" "1.3.1"
- "@chakra-ui/react-utils" "1.2.1"
- "@chakra-ui/utils" "1.9.1"
- "@chakra-ui/visually-hidden" "1.1.1"
-
-"@chakra-ui/transition@1.4.2":
- version "1.4.2"
- resolved "https://registry.npmjs.org/@chakra-ui/transition/-/transition-1.4.2.tgz"
- integrity sha512-S+BNmpErHlntl//uaqv0sJegzMsQms0OnJapeZaRsvZL4s1SVYrR8kMrXigkdpeh4lAUqGsLpQHPKkzaKGbBOw==
- dependencies:
- "@chakra-ui/utils" "1.9.1"
-
-"@chakra-ui/utils@^1.9.1", "@chakra-ui/utils@1.9.1":
- version "1.9.1"
- resolved "https://registry.npmjs.org/@chakra-ui/utils/-/utils-1.9.1.tgz"
- integrity sha512-Tue8JfpzOqeHd8vSqAnX1l/Y3Gg456+BXFP/TH6mCIeqMAMbrvv25vDskds0wlXRjMYdmpqHxCEzkalFrscGHA==
- dependencies:
- "@types/lodash.mergewith" "4.6.6"
- css-box-model "1.2.1"
- framesync "5.3.0"
- lodash.mergewith "4.6.2"
-
-"@chakra-ui/visually-hidden@1.1.1":
- version "1.1.1"
- resolved "https://registry.npmjs.org/@chakra-ui/visually-hidden/-/visually-hidden-1.1.1.tgz"
- integrity sha512-AGK9YBQS2FW/1e5tfivS8VVXn8y2uTyJ9ACOnGiLm9FNdth9pR0fGil9axlcmhZpEYcSRlnCuma3nkqaCjJnAA==
- dependencies:
- "@chakra-ui/utils" "1.9.1"
-
-"@ctrl/tinycolor@^3.4.0":
- version "3.4.0"
- resolved "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.4.0.tgz"
- integrity sha512-JZButFdZ1+/xAfpguQHoabIXkcqRRKpMrWKBkpEZZyxfY9C1DpADFB8PEqGSTeFr135SaTRfKqGKx5xSCLI7ZQ==
-
-"@emotion/babel-plugin@^11.3.0":
- version "11.7.2"
- resolved "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.7.2.tgz"
- integrity sha512-6mGSCWi9UzXut/ZAN6lGFu33wGR3SJisNl3c0tvlmb8XChH1b2SUvxvnOh7hvLpqyRdHHU9AiazV3Cwbk5SXKQ==
- dependencies:
- "@babel/helper-module-imports" "^7.12.13"
- "@babel/plugin-syntax-jsx" "^7.12.13"
- "@babel/runtime" "^7.13.10"
- "@emotion/hash" "^0.8.0"
- "@emotion/memoize" "^0.7.5"
- "@emotion/serialize" "^1.0.2"
- babel-plugin-macros "^2.6.1"
- convert-source-map "^1.5.0"
- escape-string-regexp "^4.0.0"
- find-root "^1.1.0"
- source-map "^0.5.7"
- stylis "4.0.13"
-
-"@emotion/cache@^11.7.1":
- version "11.7.1"
- resolved "https://registry.npmjs.org/@emotion/cache/-/cache-11.7.1.tgz"
- integrity sha512-r65Zy4Iljb8oyjtLeCuBH8Qjiy107dOYC6SJq7g7GV5UCQWMObY4SJDPGFjiiVpPrOJ2hmJOoBiYTC7hwx9E2A==
- dependencies:
- "@emotion/memoize" "^0.7.4"
- "@emotion/sheet" "^1.1.0"
- "@emotion/utils" "^1.0.0"
- "@emotion/weak-memoize" "^0.2.5"
- stylis "4.0.13"
-
-"@emotion/core@^11.0.0":
- version "11.0.0"
- resolved "https://registry.npmjs.org/@emotion/core/-/core-11.0.0.tgz"
- integrity sha512-w4sE3AmHmyG6RDKf6mIbtHpgJUSJ2uGvPQb8VXFL7hFjMPibE8IiehG8cMX3Ztm4svfCQV6KqusQbeIOkurBcA==
-
-"@emotion/hash@^0.8.0":
- version "0.8.0"
- resolved "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz"
- integrity sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==
-
-"@emotion/is-prop-valid@^0.8.2":
- version "0.8.8"
- resolved "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz"
- integrity sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==
- dependencies:
- "@emotion/memoize" "0.7.4"
-
-"@emotion/is-prop-valid@^1.1.1":
- version "1.1.1"
- resolved "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.1.1.tgz"
- integrity sha512-bW1Tos67CZkOURLc0OalnfxtSXQJMrAMV0jZTVGJUPSOd4qgjF3+tTD5CwJM13PHA8cltGW1WGbbvV9NpvUZPw==
- dependencies:
- "@emotion/memoize" "^0.7.4"
-
-"@emotion/memoize@^0.7.4", "@emotion/memoize@^0.7.5":
- version "0.7.5"
- resolved "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.5.tgz"
- integrity sha512-igX9a37DR2ZPGYtV6suZ6whr8pTFtyHL3K/oLUotxpSVO2ASaprmAe2Dkq7tBo7CRY7MMDrAa9nuQP9/YG8FxQ==
-
-"@emotion/memoize@0.7.4":
- version "0.7.4"
- resolved "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz"
- integrity sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==
-
-"@emotion/react@^11.0.0", "@emotion/react@^11.0.0-rc.0", "@emotion/react@^11.7.1", "@emotion/react@>=10.0.35":
- version "11.7.1"
- resolved "https://registry.npmjs.org/@emotion/react/-/react-11.7.1.tgz"
- integrity sha512-DV2Xe3yhkF1yT4uAUoJcYL1AmrnO5SVsdfvu+fBuS7IbByDeTVx9+wFmvx9Idzv7/78+9Mgx2Hcmr7Fex3tIyw==
- dependencies:
- "@babel/runtime" "^7.13.10"
- "@emotion/cache" "^11.7.1"
- "@emotion/serialize" "^1.0.2"
- "@emotion/sheet" "^1.1.0"
- "@emotion/utils" "^1.0.0"
- "@emotion/weak-memoize" "^0.2.5"
- hoist-non-react-statics "^3.3.1"
-
-"@emotion/serialize@^1.0.2":
- version "1.0.2"
- resolved "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.0.2.tgz"
- integrity sha512-95MgNJ9+/ajxU7QIAruiOAdYNjxZX7G2mhgrtDWswA21VviYIRP1R5QilZ/bDY42xiKsaktP4egJb3QdYQZi1A==
- dependencies:
- "@emotion/hash" "^0.8.0"
- "@emotion/memoize" "^0.7.4"
- "@emotion/unitless" "^0.7.5"
- "@emotion/utils" "^1.0.0"
- csstype "^3.0.2"
-
-"@emotion/sheet@^1.1.0":
- version "1.1.0"
- resolved "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.1.0.tgz"
- integrity sha512-u0AX4aSo25sMAygCuQTzS+HsImZFuS8llY8O7b9MDRzbJM0kVJlAz6KNDqcG7pOuQZJmj/8X/rAW+66kMnMW+g==
-
-"@emotion/styled@^11.0.0", "@emotion/styled@^11.6.0":
- version "11.6.0"
- resolved "https://registry.npmjs.org/@emotion/styled/-/styled-11.6.0.tgz"
- integrity sha512-mxVtVyIOTmCAkFbwIp+nCjTXJNgcz4VWkOYQro87jE2QBTydnkiYusMrRGFtzuruiGK4dDaNORk4gH049iiQuw==
- dependencies:
- "@babel/runtime" "^7.13.10"
- "@emotion/babel-plugin" "^11.3.0"
- "@emotion/is-prop-valid" "^1.1.1"
- "@emotion/serialize" "^1.0.2"
- "@emotion/utils" "^1.0.0"
-
-"@emotion/unitless@^0.7.5":
- version "0.7.5"
- resolved "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz"
- integrity sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==
-
-"@emotion/utils@^1.0.0":
- version "1.0.0"
- resolved "https://registry.npmjs.org/@emotion/utils/-/utils-1.0.0.tgz"
- integrity sha512-mQC2b3XLDs6QCW+pDQDiyO/EdGZYOygE8s5N5rrzjSI4M3IejPE/JPndCBwRT9z982aqQNi6beWs1UeayrQxxA==
-
-"@emotion/weak-memoize@^0.2.5":
- version "0.2.5"
- resolved "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz"
- integrity sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA==
-
-"@graphql-typed-document-node/core@^3.1.0":
- version "3.1.1"
- resolved "https://registry.npmjs.org/@graphql-typed-document-node/core/-/core-3.1.1.tgz"
- integrity sha512-NQ17ii0rK1b34VZonlmT2QMJFI70m0TRwbknO/ihlbatXyaktDhN/98vBiUU6kNBPljqGqyIrl2T4nY2RpFANg==
-
-"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2":
- version "0.3.3"
- resolved "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz"
- integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==
- dependencies:
- "@jridgewell/set-array" "^1.0.1"
- "@jridgewell/sourcemap-codec" "^1.4.10"
- "@jridgewell/trace-mapping" "^0.3.9"
-
-"@jridgewell/resolve-uri@^3.1.0":
- version "3.1.1"
- resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz"
- integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==
-
-"@jridgewell/set-array@^1.0.1":
- version "1.1.2"
- resolved "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz"
- integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==
-
-"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14":
- version "1.4.15"
- resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz"
- integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==
-
-"@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9":
- version "0.3.20"
- resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz"
- integrity sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==
- dependencies:
- "@jridgewell/resolve-uri" "^3.1.0"
- "@jridgewell/sourcemap-codec" "^1.4.14"
-
-"@popperjs/core@^2.9.3":
- version "2.11.0"
- resolved "https://registry.npmjs.org/@popperjs/core/-/core-2.11.0.tgz"
- integrity sha512-zrsUxjLOKAzdewIDRWy9nsV1GQsKBCWaGwsZQlCgr6/q+vjyZhFgqedLfFBuI9anTPEUT4APq9Mu0SZBTzIcGQ==
-
-"@reach/alert@0.13.2":
- version "0.13.2"
- resolved "https://registry.npmjs.org/@reach/alert/-/alert-0.13.2.tgz"
- integrity sha512-LDz83AXCrClyq/MWe+0vaZfHp1Ytqn+kgL5VxG7rirUvmluWaj/snxzfNPWn0Ma4K2YENmXXRC/iHt5X95SqIg==
- dependencies:
- "@reach/utils" "0.13.2"
- "@reach/visually-hidden" "0.13.2"
- prop-types "^15.7.2"
- tslib "^2.1.0"
-
-"@reach/utils@0.13.2":
- version "0.13.2"
- resolved "https://registry.npmjs.org/@reach/utils/-/utils-0.13.2.tgz"
- integrity sha512-3ir6cN60zvUrwjOJu7C6jec/samqAeyAB12ZADK+qjnmQPdzSYldrFWwDVV5H0WkhbYXR3uh+eImu13hCetNPQ==
- dependencies:
- "@types/warning" "^3.0.0"
- tslib "^2.1.0"
- warning "^4.0.3"
-
-"@reach/visually-hidden@0.13.2":
- version "0.13.2"
- resolved "https://registry.npmjs.org/@reach/visually-hidden/-/visually-hidden-0.13.2.tgz"
- integrity sha512-sPZwNS0/duOuG0mYwE5DmgEAzW9VhgU3aIt1+mrfT/xiT9Cdncqke+kRBQgU708q/Ttm9tWsoHni03nn/SuPTQ==
- dependencies:
- prop-types "^15.7.2"
- tslib "^2.1.0"
-
-"@types/history@*":
- version "4.7.9"
- resolved "https://registry.npmjs.org/@types/history/-/history-4.7.9.tgz"
- integrity sha512-MUc6zSmU3tEVnkQ78q0peeEjKWPUADMlC/t++2bI8WnAG2tvYRPIgHG8lWkXwqc8MsUF6Z2MOf+Mh5sazOmhiQ==
-
-"@types/lodash.mergewith@4.6.6":
- version "4.6.6"
- resolved "https://registry.npmjs.org/@types/lodash.mergewith/-/lodash.mergewith-4.6.6.tgz"
- integrity sha512-RY/8IaVENjG19rxTZu9Nukqh0W2UrYgmBj5sdns4hWRZaV8PqR7wIKHFKzvOTjo4zVRV7sVI+yFhAJql12Kfqg==
- dependencies:
- "@types/lodash" "*"
-
-"@types/lodash@*":
- version "4.14.178"
- resolved "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.178.tgz"
- integrity sha512-0d5Wd09ItQWH1qFbEyQ7oTQ3GZrMfth5JkbN3EvTKLXcHLRDSXeLnlvlOn0wvxVIwK5o2M8JzP/OWz7T3NRsbw==
-
-"@types/parse-json@^4.0.0":
- version "4.0.0"
- resolved "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz"
- integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==
-
-"@types/prop-types@*":
- version "15.7.4"
- resolved "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.4.tgz"
- integrity sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==
-
-"@types/react-dom@^17.0.11":
- version "17.0.11"
- resolved "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.11.tgz"
- integrity sha512-f96K3k+24RaLGVu/Y2Ng3e1EbZ8/cVJvypZWd7cy0ofCBaf2lcM46xNhycMZ2xGwbBjRql7hOlZ+e2WlJ5MH3Q==
- dependencies:
- "@types/react" "*"
-
-"@types/react-email-editor@^1.1.7":
- version "1.1.7"
- resolved "https://registry.npmjs.org/@types/react-email-editor/-/react-email-editor-1.1.7.tgz"
- integrity sha512-OURTAgaE9pjA6KiU97k13fPdoglI1ZyowUuZ0nu5tTSyrw5PiZoYzYEf9y25YTjmw/ohxT5yqoP0tt+AjSh1qQ==
- dependencies:
- "@types/react" "*"
-
-"@types/react-router-dom@^5.3.2":
- version "5.3.2"
- resolved "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.3.2.tgz"
- integrity sha512-ELEYRUie2czuJzaZ5+ziIp9Hhw+juEw8b7C11YNA4QdLCVbQ3qLi2l4aq8XnlqM7V31LZX8dxUuFUCrzHm6sqQ==
- dependencies:
- "@types/history" "*"
- "@types/react" "*"
- "@types/react-router" "*"
-
-"@types/react-router@*":
- version "5.1.17"
- resolved "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.17.tgz"
- integrity sha512-RNSXOyb3VyRs/EOGmjBhhGKTbnN6fHWvy5FNLzWfOWOGjgVUKqJZXfpKzLmgoU8h6Hj8mpALj/mbXQASOb92wQ==
- dependencies:
- "@types/history" "*"
- "@types/react" "*"
-
-"@types/react@*", "@types/react@^16.8.0 || ^17.0.0", "@types/react@^17.0.38":
- version "17.0.38"
- resolved "https://registry.npmjs.org/@types/react/-/react-17.0.38.tgz"
- integrity sha512-SI92X1IA+FMnP3qM5m4QReluXzhcmovhZnLNm3pyeQlooi02qI7sLiepEYqT678uNiyc25XfCqxREFpy3W7YhQ==
- dependencies:
- "@types/prop-types" "*"
- "@types/scheduler" "*"
- csstype "^3.0.2"
-
-"@types/scheduler@*":
- version "0.16.2"
- resolved "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz"
- integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==
-
-"@types/warning@^3.0.0":
- version "3.0.0"
- resolved "https://registry.npmjs.org/@types/warning/-/warning-3.0.0.tgz"
- integrity sha1-DSUBJorY+ZYrdA04fEZU9fjiPlI=
-
-"@urql/core@^2.3.6":
- version "2.3.6"
- resolved "https://registry.npmjs.org/@urql/core/-/core-2.3.6.tgz"
- integrity sha512-PUxhtBh7/8167HJK6WqBv6Z0piuiaZHQGYbhwpNL9aIQmLROPEdaUYkY4wh45wPQXcTpnd11l0q3Pw+TI11pdw==
- dependencies:
- "@graphql-typed-document-node/core" "^3.1.0"
- wonka "^4.0.14"
-
-ansi-styles@^3.2.1:
- version "3.2.1"
- resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz"
- integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==
- dependencies:
- color-convert "^1.9.0"
-
-aria-hidden@^1.1.1:
- version "1.1.3"
- resolved "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.1.3.tgz"
- integrity sha512-RhVWFtKH5BiGMycI72q2RAFMLQi8JP9bLuQXgR5a8Znp7P5KOIADSJeyfI8PCVxLEp067B2HbP5JIiI/PXIZeA==
- dependencies:
- tslib "^1.0.0"
-
-asap@~2.0.3:
- version "2.0.6"
- resolved "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz"
- integrity sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==
-
-attr-accept@^2.2.2:
- version "2.2.2"
- resolved "https://registry.npmjs.org/attr-accept/-/attr-accept-2.2.2.tgz"
- integrity sha512-7prDjvt9HmqiZ0cl5CRjtS84sEyhsHP2coDkaZKRKVfCDo9s7iw7ChVmar78Gu9pC4SoR/28wFu/G5JJhTnqEg==
-
-babel-plugin-macros@^2.6.1:
- version "2.8.0"
- resolved "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz"
- integrity sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg==
- dependencies:
- "@babel/runtime" "^7.7.2"
- cosmiconfig "^6.0.0"
- resolve "^1.12.0"
-
-browserslist@^4.21.9, "browserslist@>= 4.21.0":
- version "4.22.1"
- resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz"
- integrity sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==
- dependencies:
- caniuse-lite "^1.0.30001541"
- electron-to-chromium "^1.4.535"
- node-releases "^2.0.13"
- update-browserslist-db "^1.0.13"
-
-callsites@^3.0.0:
- version "3.1.0"
- resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz"
- integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==
-
-caniuse-lite@^1.0.30001541:
- version "1.0.30001561"
- resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001561.tgz"
- integrity sha512-NTt0DNoKe958Q0BE0j0c1V9jbUzhBxHIEJy7asmGrpE0yG63KTV7PLHPnK2E1O9RsQrQ081I3NLuXGS6zht3cw==
-
-chalk@^2.4.2:
- version "2.4.2"
- resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz"
- integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
- dependencies:
- ansi-styles "^3.2.1"
- escape-string-regexp "^1.0.5"
- supports-color "^5.3.0"
-
-classnames@^2.2.6:
- version "2.3.1"
- resolved "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz"
- integrity sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==
-
-color-convert@^1.9.0:
- version "1.9.3"
- resolved "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz"
- integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==
- dependencies:
- color-name "1.1.3"
-
-color-name@1.1.3:
- version "1.1.3"
- resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz"
- integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==
-
-compute-scroll-into-view@1.0.14:
- version "1.0.14"
- resolved "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-1.0.14.tgz"
- integrity sha512-mKDjINe3tc6hGelUMNDzuhorIUZ7kS7BwyY0r2wQd2HOH2tRuJykiC06iSEX8y1TuhNzvz4GcJnK16mM2J1NMQ==
-
-convert-source-map@^1.5.0:
- version "1.8.0"
- resolved "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz"
- integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==
- dependencies:
- safe-buffer "~5.1.1"
-
-convert-source-map@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz"
- integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==
-
-copy-to-clipboard@3.3.1:
- version "3.3.1"
- resolved "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.1.tgz"
- integrity sha512-i13qo6kIHTTpCm8/Wup+0b1mVWETvu2kIMzKoK8FpkLkFxlt0znUAHcMzox+T8sPlqtZXq3CulEjQHsYiGFJUw==
- dependencies:
- toggle-selection "^1.0.6"
-
-core-js@^3.6.4:
- version "3.33.2"
- resolved "https://registry.npmjs.org/core-js/-/core-js-3.33.2.tgz"
- integrity sha512-XeBzWI6QL3nJQiHmdzbAOiMYqjrb7hwU7A39Qhvd/POSa/t9E1AeZyEZx3fNvp/vtM8zXwhoL0FsiS0hD0pruQ==
-
-cosmiconfig@^6.0.0:
- version "6.0.0"
- resolved "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz"
- integrity sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==
- dependencies:
- "@types/parse-json" "^4.0.0"
- import-fresh "^3.1.0"
- parse-json "^5.0.0"
- path-type "^4.0.0"
- yaml "^1.7.2"
-
-cross-fetch@^3.0.4:
- version "3.1.8"
- resolved "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz"
- integrity sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==
- dependencies:
- node-fetch "^2.6.12"
-
-css-box-model@1.2.1:
- version "1.2.1"
- resolved "https://registry.npmjs.org/css-box-model/-/css-box-model-1.2.1.tgz"
- integrity sha512-a7Vr4Q/kd/aw96bnJG332W9V9LkJO69JRcaCYDUqjp6/z0w6VcZjgAcTbgFxEPfBgdnAwlh3iwu+hLopa+flJw==
- dependencies:
- tiny-invariant "^1.0.6"
-
-csstype@^3.0.2, csstype@^3.0.9:
- version "3.0.10"
- resolved "https://registry.npmjs.org/csstype/-/csstype-3.0.10.tgz"
- integrity sha512-2u44ZG2OcNUO9HDp/Jl8C07x6pU/eTR3ncV91SiK3dhG9TWvRVsCoJw14Ckx5DgWkzGA3waZWO3d7pgqpUI/XA==
-
-dayjs@^1.10.7:
- version "1.10.7"
- resolved "https://registry.npmjs.org/dayjs/-/dayjs-1.10.7.tgz"
- integrity sha512-P6twpd70BcPK34K26uJ1KT3wlhpuOAPoMwJzpsIWUxHZ7wpmbdZL/hQqBDfz7hGurYSa5PhzdhDHtt319hL3ig==
-
-debounce@^1.2.1:
- version "1.2.1"
- resolved "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz"
- integrity sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==
-
-debug@^4.1.0:
- version "4.3.4"
- resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz"
- integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
- dependencies:
- ms "2.1.2"
-
-detect-node-es@^1.1.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz"
- integrity sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==
-
-"draft-js@^0.10.x || ^0.11.x", draft-js@^0.11.x:
- version "0.11.7"
- resolved "https://registry.npmjs.org/draft-js/-/draft-js-0.11.7.tgz"
- integrity sha512-ne7yFfN4sEL82QPQEn80xnADR8/Q6ALVworbC5UOSzOvjffmYfFsr3xSZtxbIirti14R7Y33EZC5rivpLgIbsg==
- dependencies:
- fbjs "^2.0.0"
- immutable "~3.7.4"
- object-assign "^4.1.1"
-
-draftjs-utils@^0.10.2:
- version "0.10.2"
- resolved "https://registry.npmjs.org/draftjs-utils/-/draftjs-utils-0.10.2.tgz"
- integrity sha512-EstHqr3R3JVcilJrBaO/A+01GvwwKmC7e4TCjC7S94ZeMh4IVmf60OuQXtHHpwItK8C2JCi3iljgN5KHkJboUg==
-
-electron-to-chromium@^1.4.535:
- version "1.4.581"
- resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.581.tgz"
- integrity sha512-6uhqWBIapTJUxgPTCHH9sqdbxIMPt7oXl0VcAL1kOtlU6aECdcMncCrX5Z7sHQ/invtrC9jUQUef7+HhO8vVFw==
-
-error-ex@^1.3.1:
- version "1.3.2"
- resolved "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz"
- integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==
- dependencies:
- is-arrayish "^0.2.1"
-
-esbuild-darwin-arm64@0.14.9:
- version "0.14.9"
- resolved "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.9.tgz"
- integrity sha512-3ue+1T4FR5TaAu4/V1eFMG8Uwn0pgAwQZb/WwL1X78d5Cy8wOVQ67KNH1lsjU+y/9AcwMKZ9x0GGNxBB4a1Rbw==
-
-esbuild@^0.14.9:
- version "0.14.9"
- resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.14.9.tgz"
- integrity sha512-uuT3kFsfUvzNW6I2RKKIHuCvutY/U9KFcAP6emUm98WvBhyhEr5vGkZLeN3r3vXfoykl+7xekAH8Ky09LXBd0Q==
- optionalDependencies:
- esbuild-android-arm64 "0.14.9"
- esbuild-darwin-64 "0.14.9"
- esbuild-darwin-arm64 "0.14.9"
- esbuild-freebsd-64 "0.14.9"
- esbuild-freebsd-arm64 "0.14.9"
- esbuild-linux-32 "0.14.9"
- esbuild-linux-64 "0.14.9"
- esbuild-linux-arm "0.14.9"
- esbuild-linux-arm64 "0.14.9"
- esbuild-linux-mips64le "0.14.9"
- esbuild-linux-ppc64le "0.14.9"
- esbuild-linux-s390x "0.14.9"
- esbuild-netbsd-64 "0.14.9"
- esbuild-openbsd-64 "0.14.9"
- esbuild-sunos-64 "0.14.9"
- esbuild-windows-32 "0.14.9"
- esbuild-windows-64 "0.14.9"
- esbuild-windows-arm64 "0.14.9"
-
-escalade@^3.1.1:
- version "3.1.1"
- resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz"
- integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==
-
-escape-string-regexp@^1.0.5:
- version "1.0.5"
- resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz"
- integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==
-
-escape-string-regexp@^4.0.0:
- version "4.0.0"
- resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz"
- integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
-
-fbjs-css-vars@^1.0.0:
- version "1.0.2"
- resolved "https://registry.npmjs.org/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz"
- integrity sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ==
-
-fbjs@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/fbjs/-/fbjs-2.0.0.tgz"
- integrity sha512-8XA8ny9ifxrAWlyhAbexXcs3rRMtxWcs3M0lctLfB49jRDHiaxj+Mo0XxbwE7nKZYzgCFoq64FS+WFd4IycPPQ==
- dependencies:
- core-js "^3.6.4"
- cross-fetch "^3.0.4"
- fbjs-css-vars "^1.0.0"
- loose-envify "^1.0.0"
- object-assign "^4.1.0"
- promise "^7.1.1"
- setimmediate "^1.0.5"
- ua-parser-js "^0.7.18"
-
-file-selector@^0.4.0:
- version "0.4.0"
- resolved "https://registry.npmjs.org/file-selector/-/file-selector-0.4.0.tgz"
- integrity sha512-iACCiXeMYOvZqlF1kTiYINzgepRBymz1wwjiuup9u9nayhb6g4fSwiyJ/6adli+EPwrWtpgQAh2PoS7HukEGEg==
- dependencies:
- tslib "^2.0.3"
-
-find-root@^1.1.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz"
- integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==
-
-focus-lock@^0.9.1:
- version "0.9.2"
- resolved "https://registry.npmjs.org/focus-lock/-/focus-lock-0.9.2.tgz"
- integrity sha512-YtHxjX7a0IC0ZACL5wsX8QdncXofWpGPNoVMuI/nZUrPGp6LmNI6+D5j0pPj+v8Kw5EpweA+T5yImK0rnWf7oQ==
- dependencies:
- tslib "^2.0.3"
-
-focus-visible@^5.2.0:
- version "5.2.0"
- resolved "https://registry.npmjs.org/focus-visible/-/focus-visible-5.2.0.tgz"
- integrity sha512-Rwix9pBtC1Nuy5wysTmKy+UjbDJpIfg8eHjw0rjZ1mX4GNLz1Bmd16uDpI3Gk1i70Fgcs8Csg2lPm8HULFg9DQ==
-
-framer-motion@^5.5.5, "framer-motion@3.x || 4.x || 5.x":
- version "5.5.5"
- resolved "https://registry.npmjs.org/framer-motion/-/framer-motion-5.5.5.tgz"
- integrity sha512-+LPAF5ddo02qKh+MK4h1ChwqUFvrLkK1NDWwrHy+MuCVmQDGgiFNHvwqOSklTDGkEtbio3dCOEDy23+ZyNAa9g==
- dependencies:
- framesync "6.0.1"
- hey-listen "^1.0.8"
- popmotion "11.0.3"
- react-merge-refs "^1.1.0"
- react-use-measure "^2.1.1"
- style-value-types "5.0.0"
- tslib "^2.1.0"
- optionalDependencies:
- "@emotion/is-prop-valid" "^0.8.2"
-
-framesync@5.3.0:
- version "5.3.0"
- resolved "https://registry.npmjs.org/framesync/-/framesync-5.3.0.tgz"
- integrity sha512-oc5m68HDO/tuK2blj7ZcdEBRx3p1PjrgHazL8GYEpvULhrtGIFbQArN6cQS2QhW8mitffaB+VYzMjDqBxxQeoA==
- dependencies:
- tslib "^2.1.0"
-
-framesync@6.0.1:
- version "6.0.1"
- resolved "https://registry.npmjs.org/framesync/-/framesync-6.0.1.tgz"
- integrity sha512-fUY88kXvGiIItgNC7wcTOl0SNRCVXMKSWW2Yzfmn7EKNc+MpCzcz9DhdHcdjbrtN3c6R4H5dTY2jiCpPdysEjA==
- dependencies:
- tslib "^2.1.0"
-
-function-bind@^1.1.1:
- version "1.1.1"
- resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz"
- integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
-
-gensync@^1.0.0-beta.2:
- version "1.0.0-beta.2"
- resolved "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz"
- integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==
-
-get-nonce@^1.0.0:
- version "1.0.1"
- resolved "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz"
- integrity sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==
-
-globals@^11.1.0:
- version "11.12.0"
- resolved "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz"
- integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==
-
-"graphql@^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0", "graphql@^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0", graphql@^16.2.0:
- version "16.2.0"
- resolved "https://registry.npmjs.org/graphql/-/graphql-16.2.0.tgz"
- integrity sha512-MuQd7XXrdOcmfwuLwC2jNvx0n3rxIuNYOxUtiee5XOmfrWo613ar2U8pE7aHAKh8VwfpifubpD9IP+EdEAEOsA==
-
-has-flag@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz"
- integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==
-
-has@^1.0.3:
- version "1.0.3"
- resolved "https://registry.npmjs.org/has/-/has-1.0.3.tgz"
- integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==
- dependencies:
- function-bind "^1.1.1"
-
-hey-listen@^1.0.8:
- version "1.0.8"
- resolved "https://registry.npmjs.org/hey-listen/-/hey-listen-1.0.8.tgz"
- integrity sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==
-
-history@^5.2.0:
- version "5.2.0"
- resolved "https://registry.npmjs.org/history/-/history-5.2.0.tgz"
- integrity sha512-uPSF6lAJb3nSePJ43hN3eKj1dTWpN9gMod0ZssbFTIsen+WehTmEadgL+kg78xLJFdRfrrC//SavDzmRVdE+Ig==
- dependencies:
- "@babel/runtime" "^7.7.6"
-
-hoist-non-react-statics@^3.3.1:
- version "3.3.2"
- resolved "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz"
- integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==
- dependencies:
- react-is "^16.7.0"
-
-html-to-draftjs@^1.5.0:
- version "1.5.0"
- resolved "https://registry.npmjs.org/html-to-draftjs/-/html-to-draftjs-1.5.0.tgz"
- integrity sha512-kggLXBNciKDwKf+KYsuE+V5gw4dZ7nHyGMX9m0wy7urzWjKGWyNFetmArRLvRV0VrxKN70WylFsJvMTJx02OBQ==
-
-immutable@~3.7.4:
- version "3.7.6"
- resolved "https://registry.npmjs.org/immutable/-/immutable-3.7.6.tgz"
- integrity sha512-AizQPcaofEtO11RZhPPHBOJRdo/20MKQF9mBLnVkBoyHi1/zXK8fzVdnEpSV9gxqtnh6Qomfp3F0xT5qP/vThw==
-
-"immutable@3.x.x || 4.x.x":
- version "4.3.4"
- resolved "https://registry.npmjs.org/immutable/-/immutable-4.3.4.tgz"
- integrity sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==
-
-import-fresh@^3.1.0:
- version "3.3.0"
- resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz"
- integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==
- dependencies:
- parent-module "^1.0.0"
- resolve-from "^4.0.0"
-
-invariant@^2.2.4:
- version "2.2.4"
- resolved "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz"
- integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==
- dependencies:
- loose-envify "^1.0.0"
-
-is-arrayish@^0.2.1:
- version "0.2.1"
- resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz"
- integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=
-
-is-core-module@^2.2.0:
- version "2.8.0"
- resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz"
- integrity sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==
- dependencies:
- has "^1.0.3"
-
-"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
- version "4.0.0"
- resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz"
- integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
-
-jsesc@^2.5.1:
- version "2.5.2"
- resolved "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz"
- integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==
-
-json-parse-even-better-errors@^2.3.0:
- version "2.3.1"
- resolved "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz"
- integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==
-
-json5@^2.2.3:
- version "2.2.3"
- resolved "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz"
- integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==
-
-lines-and-columns@^1.1.6:
- version "1.2.4"
- resolved "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz"
- integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==
-
-linkify-it@^2.2.0:
- version "2.2.0"
- resolved "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz"
- integrity sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==
- dependencies:
- uc.micro "^1.0.1"
-
-lodash.mergewith@4.6.2:
- version "4.6.2"
- resolved "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz"
- integrity sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==
-
-lodash@^4.17.21:
- version "4.17.21"
- resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz"
- integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
-
-loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0:
- version "1.4.0"
- resolved "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz"
- integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
- dependencies:
- js-tokens "^3.0.0 || ^4.0.0"
-
-lru-cache@^5.1.1:
- version "5.1.1"
- resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz"
- integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==
- dependencies:
- yallist "^3.0.2"
-
-ms@2.1.2:
- version "2.1.2"
- resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz"
- integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
-
-node-fetch@^2.6.12:
- version "2.7.0"
- resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz"
- integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==
- dependencies:
- whatwg-url "^5.0.0"
-
-node-releases@^2.0.13:
- version "2.0.13"
- resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz"
- integrity sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==
-
-object-assign@^4.1.0, object-assign@^4.1.1:
- version "4.1.1"
- resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz"
- integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
-
-parent-module@^1.0.0:
- version "1.0.1"
- resolved "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz"
- integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==
- dependencies:
- callsites "^3.0.0"
-
-parse-json@^5.0.0:
- version "5.2.0"
- resolved "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz"
- integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==
- dependencies:
- "@babel/code-frame" "^7.0.0"
- error-ex "^1.3.1"
- json-parse-even-better-errors "^2.3.0"
- lines-and-columns "^1.1.6"
-
-path-parse@^1.0.6:
- version "1.0.7"
- resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz"
- integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
-
-path-type@^4.0.0:
- version "4.0.0"
- resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz"
- integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
-
-picocolors@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz"
- integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==
-
-popmotion@11.0.3:
- version "11.0.3"
- resolved "https://registry.npmjs.org/popmotion/-/popmotion-11.0.3.tgz"
- integrity sha512-Y55FLdj3UxkR7Vl3s7Qr4e9m0onSnP8W7d/xQLsoJM40vs6UKHFdygs6SWryasTZYqugMjm3BepCF4CWXDiHgA==
- dependencies:
- framesync "6.0.1"
- hey-listen "^1.0.8"
- style-value-types "5.0.0"
- tslib "^2.1.0"
-
-prettier@2.7.1:
- version "2.7.1"
- resolved "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz"
- integrity sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==
-
-promise@^7.1.1:
- version "7.3.1"
- resolved "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz"
- integrity sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==
- dependencies:
- asap "~2.0.3"
-
-prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1:
- version "15.8.1"
- resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz"
- integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
- dependencies:
- loose-envify "^1.4.0"
- object-assign "^4.1.1"
- react-is "^16.13.1"
-
-react-clientside-effect@^1.2.5:
- version "1.2.5"
- resolved "https://registry.npmjs.org/react-clientside-effect/-/react-clientside-effect-1.2.5.tgz"
- integrity sha512-2bL8qFW1TGBHozGGbVeyvnggRpMjibeZM2536AKNENLECutp2yfs44IL8Hmpn8qjFQ2K7A9PnYf3vc7aQq/cPA==
- dependencies:
- "@babel/runtime" "^7.12.13"
-
-"react-dom@^16.8.0 || 17.x", react-dom@^17.0.2, react-dom@>=0.14.0, react-dom@>=16.13, react-dom@>=16.8, "react-dom@>=16.8 || ^17.0.0", react-dom@>=16.8.6, "react-dom@0.13.x || 0.14.x || ^15.0.0-0 || 15.x.x || ^16.0.0-0 || ^16.x.x || ^17.x.x || ^18.x.x":
- version "17.0.2"
- resolved "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz"
- integrity sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==
- dependencies:
- loose-envify "^1.1.0"
- object-assign "^4.1.1"
- scheduler "^0.20.2"
-
-react-draft-wysiwyg@^1.15.0:
- version "1.15.0"
- resolved "https://registry.npmjs.org/react-draft-wysiwyg/-/react-draft-wysiwyg-1.15.0.tgz"
- integrity sha512-p1cYZcWc6/ALFBVksbFoCM3b29fGQDlZLIMrXng0TU/UElxIOF2/AWWo4L5auIYVhmqKTZ0NkNjnXOzGGuxyeA==
- dependencies:
- classnames "^2.2.6"
- draftjs-utils "^0.10.2"
- html-to-draftjs "^1.5.0"
- linkify-it "^2.2.0"
- prop-types "^15.7.2"
-
-react-dropzone@^12.0.4:
- version "12.0.4"
- resolved "https://registry.npmjs.org/react-dropzone/-/react-dropzone-12.0.4.tgz"
- integrity sha512-fcqHEYe1MzAghU6/Hz86lHDlBNsA+lO48nAcm7/wA+kIzwS6uuJbUG33tBZjksj7GAZ1iUQ6NHwjUURPmSGang==
- dependencies:
- attr-accept "^2.2.2"
- file-selector "^0.4.0"
- prop-types "^15.8.1"
-
-react-email-editor@^1.6.1:
- version "1.6.1"
- resolved "https://registry.npmjs.org/react-email-editor/-/react-email-editor-1.6.1.tgz"
- integrity sha512-pEWpRmTY0ok03cwTGqEOoEldnzThhuRGTrcMnv8W3/jc5MTfcr9USU/IQ9HrVvFStLKoxYBIQnSKY+iCYWOtSQ==
-
-react-fast-compare@3.2.0:
- version "3.2.0"
- resolved "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz"
- integrity sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==
-
-react-focus-lock@2.5.2:
- version "2.5.2"
- resolved "https://registry.npmjs.org/react-focus-lock/-/react-focus-lock-2.5.2.tgz"
- integrity sha512-WzpdOnEqjf+/A3EH9opMZWauag7gV0BxFl+EY4ElA4qFqYsUsBLnmo2sELbN5OC30S16GAWMy16B9DLPpdJKAQ==
- dependencies:
- "@babel/runtime" "^7.0.0"
- focus-lock "^0.9.1"
- prop-types "^15.6.2"
- react-clientside-effect "^1.2.5"
- use-callback-ref "^1.2.5"
- use-sidecar "^1.0.5"
-
-react-icons@^4.3.1:
- version "4.3.1"
- resolved "https://registry.npmjs.org/react-icons/-/react-icons-4.3.1.tgz"
- integrity sha512-cB10MXLTs3gVuXimblAdI71jrJx8njrJZmNMEMC+sQu5B/BIOmlsAjskdqpn81y8UBVEGuHODd7/ci5DvoSzTQ==
-
-react-is@^16.13.1, react-is@^16.7.0:
- version "16.13.1"
- resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz"
- integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
-
-react-merge-refs@^1.1.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/react-merge-refs/-/react-merge-refs-1.1.0.tgz"
- integrity sha512-alTKsjEL0dKH/ru1Iyn7vliS2QRcBp9zZPGoWxUOvRGWPUYgjo+V01is7p04It6KhgrzhJGnIj9GgX8W4bZoCQ==
-
-react-remove-scroll-bar@^2.1.0:
- version "2.2.0"
- resolved "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.2.0.tgz"
- integrity sha512-UU9ZBP1wdMR8qoUs7owiVcpaPwsQxUDC2lypP6mmixaGlARZa7ZIBx1jcuObLdhMOvCsnZcvetOho0wzPa9PYg==
- dependencies:
- react-style-singleton "^2.1.0"
- tslib "^1.0.0"
-
-react-remove-scroll@2.4.1:
- version "2.4.1"
- resolved "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.4.1.tgz"
- integrity sha512-K7XZySEzOHMTq7dDwcHsZA6Y7/1uX5RsWhRXVYv8rdh+y9Qz2nMwl9RX/Mwnj/j7JstCGmxyfyC0zbVGXYh3mA==
- dependencies:
- react-remove-scroll-bar "^2.1.0"
- react-style-singleton "^2.1.0"
- tslib "^1.0.0"
- use-callback-ref "^1.2.3"
- use-sidecar "^1.0.1"
-
-react-router-dom@^6.2.1:
- version "6.2.1"
- resolved "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.2.1.tgz"
- integrity sha512-I6Zax+/TH/cZMDpj3/4Fl2eaNdcvoxxHoH1tYOREsQ22OKDYofGebrNm6CTPUcvLvZm63NL/vzCYdjf9CUhqmA==
- dependencies:
- history "^5.2.0"
- react-router "6.2.1"
-
-react-router@6.2.1:
- version "6.2.1"
- resolved "https://registry.npmjs.org/react-router/-/react-router-6.2.1.tgz"
- integrity sha512-2fG0udBtxou9lXtK97eJeET2ki5//UWfQSl1rlJ7quwe6jrktK9FCCc8dQb5QY6jAv3jua8bBQRhhDOM/kVRsg==
- dependencies:
- history "^5.2.0"
-
-react-style-singleton@^2.1.0:
- version "2.1.1"
- resolved "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.1.1.tgz"
- integrity sha512-jNRp07Jza6CBqdRKNgGhT3u9umWvils1xsuMOjZlghBDH2MU0PL2WZor4PGYjXpnRCa9DQSlHMs/xnABWOwYbA==
- dependencies:
- get-nonce "^1.0.0"
- invariant "^2.2.4"
- tslib "^1.0.0"
-
-react-use-measure@^2.1.1:
- version "2.1.1"
- resolved "https://registry.npmjs.org/react-use-measure/-/react-use-measure-2.1.1.tgz"
- integrity sha512-nocZhN26cproIiIduswYpV5y5lQpSQS1y/4KuvUCjSKmw7ZWIS/+g3aFnX3WdBkyuGUtTLif3UTqnLLhbDoQig==
- dependencies:
- debounce "^1.2.1"
-
-react@*, "react@^15.3.0 || ^16.0.0 || ^17.0.0", "react@^16.8.0 || ^17.0.0", "react@^16.8.0 || 17.x", react@^17.0.2, "react@>= 16.8", "react@>= 16.8.0", react@>=0.14.0, react@>=16.13, react@>=16.8, "react@>=16.8 || ^17.0.0", react@>=16.8.0, react@>=16.8.6, "react@0.13.x || 0.14.x || ^15.0.0-0 || 15.x.x || ^16.0.0-0 || ^16.x.x || ^17.x.x || ^18.x.x", "react@15.x || 16.x || 17.x", react@17.0.2:
- version "17.0.2"
- resolved "https://registry.npmjs.org/react/-/react-17.0.2.tgz"
- integrity sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==
- dependencies:
- loose-envify "^1.1.0"
- object-assign "^4.1.1"
-
-regenerator-runtime@^0.13.4:
- version "0.13.9"
- resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz"
- integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==
-
-resolve-from@^4.0.0:
- version "4.0.0"
- resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz"
- integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==
-
-resolve@^1.12.0:
- version "1.20.0"
- resolved "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz"
- integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==
- dependencies:
- is-core-module "^2.2.0"
- path-parse "^1.0.6"
-
-safe-buffer@~5.1.1:
- version "5.1.2"
- resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz"
- integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
-
-scheduler@^0.20.2:
- version "0.20.2"
- resolved "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz"
- integrity sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==
- dependencies:
- loose-envify "^1.1.0"
- object-assign "^4.1.1"
-
-semver@^6.3.1:
- version "6.3.1"
- resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz"
- integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==
-
-setimmediate@^1.0.5:
- version "1.0.5"
- resolved "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz"
- integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==
-
-source-map@^0.5.7:
- version "0.5.7"
- resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz"
- integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=
-
-style-value-types@5.0.0:
- version "5.0.0"
- resolved "https://registry.npmjs.org/style-value-types/-/style-value-types-5.0.0.tgz"
- integrity sha512-08yq36Ikn4kx4YU6RD7jWEv27v4V+PUsOGa4n/as8Et3CuODMJQ00ENeAVXAeydX4Z2j1XHZF1K2sX4mGl18fA==
- dependencies:
- hey-listen "^1.0.8"
- tslib "^2.1.0"
-
-stylis@4.0.13:
- version "4.0.13"
- resolved "https://registry.npmjs.org/stylis/-/stylis-4.0.13.tgz"
- integrity sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag==
-
-supports-color@^5.3.0:
- version "5.5.0"
- resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz"
- integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
- dependencies:
- has-flag "^3.0.0"
-
-tiny-invariant@^1.0.6:
- version "1.2.0"
- resolved "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.2.0.tgz"
- integrity sha512-1Uhn/aqw5C6RI4KejVeTg6mIS7IqxnLJ8Mv2tV5rTc0qWobay7pDUz6Wi392Cnc8ak1H0F2cjoRzb2/AW4+Fvg==
-
-to-fast-properties@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz"
- integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=
-
-toggle-selection@^1.0.6:
- version "1.0.6"
- resolved "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz"
- integrity sha1-bkWxJj8gF/oKzH2J14sVuL932jI=
-
-tr46@~0.0.3:
- version "0.0.3"
- resolved "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz"
- integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==
-
-tslib@^1.0.0:
- version "1.14.1"
- resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz"
- integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
-
-tslib@^1.9.3:
- version "1.14.1"
- resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz"
- integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
-
-tslib@^2.0.3, tslib@^2.1.0:
- version "2.3.1"
- resolved "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz"
- integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==
-
-typescript@^4.5.4:
- version "4.5.4"
- resolved "https://registry.npmjs.org/typescript/-/typescript-4.5.4.tgz"
- integrity sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg==
-
-ua-parser-js@^0.7.18:
- version "0.7.37"
- resolved "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.37.tgz"
- integrity sha512-xV8kqRKM+jhMvcHWUKthV9fNebIzrNy//2O9ZwWcfiBFR5f25XVZPLlEajk/sf3Ra15V92isyQqnIEXRDaZWEA==
-
-uc.micro@^1.0.1:
- version "1.0.6"
- resolved "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz"
- integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==
-
-update-browserslist-db@^1.0.13:
- version "1.0.13"
- resolved "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz"
- integrity sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==
- dependencies:
- escalade "^3.1.1"
- picocolors "^1.0.0"
-
-urql@^2.0.6:
- version "2.0.6"
- resolved "https://registry.npmjs.org/urql/-/urql-2.0.6.tgz"
- integrity sha512-ovK9mx7YxD/CKUwVZGbEDBzZjbCcNsr1990nIhDCKe3Ij/0gNcIa+0EIyXKceOPuYDYKavIoaNQV2kOZjQxFcw==
- dependencies:
- "@urql/core" "^2.3.6"
- wonka "^4.0.14"
-
-use-callback-ref@^1.2.3, use-callback-ref@^1.2.5:
- version "1.2.5"
- resolved "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.2.5.tgz"
- integrity sha512-gN3vgMISAgacF7sqsLPByqoePooY3n2emTH59Ur5d/M8eg4WTWu1xp8i8DHjohftIyEx0S08RiYxbffr4j8Peg==
-
-use-sidecar@^1.0.1, use-sidecar@^1.0.5:
- version "1.0.5"
- resolved "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.0.5.tgz"
- integrity sha512-k9jnrjYNwN6xYLj1iaGhonDghfvmeTmYjAiGvOr7clwKfPjMXJf4/HOr7oT5tJwYafgp2tG2l3eZEOfoELiMcA==
- dependencies:
- detect-node-es "^1.1.0"
- tslib "^1.9.3"
-
-warning@^4.0.3:
- version "4.0.3"
- resolved "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz"
- integrity sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==
- dependencies:
- loose-envify "^1.0.0"
-
-webidl-conversions@^3.0.0:
- version "3.0.1"
- resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz"
- integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==
-
-whatwg-url@^5.0.0:
- version "5.0.0"
- resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz"
- integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==
- dependencies:
- tr46 "~0.0.3"
- webidl-conversions "^3.0.0"
-
-wonka@^4.0.14:
- version "4.0.15"
- resolved "https://registry.npmjs.org/wonka/-/wonka-4.0.15.tgz"
- integrity sha512-U0IUQHKXXn6PFo9nqsHphVCE5m3IntqZNB9Jjn7EB1lrR7YTDY3YWgFvEvwniTzXSvOH/XMzAZaIfJF/LvHYXg==
-
-yallist@^3.0.2:
- version "3.1.1"
- resolved "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz"
- integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==
-
-yaml@^1.7.2:
- version "1.10.2"
- resolved "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz"
- integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==
diff --git a/server/go.mod b/go.mod
similarity index 74%
rename from server/go.mod
rename to go.mod
index fc6045dd5..83fb96480 100644
--- a/server/go.mod
+++ b/go.mod
@@ -1,11 +1,9 @@
-module github.com/authorizerdev/authorizer/server
+module github.com/authorizerdev/authorizer
-go 1.21
-
-toolchain go1.21.4
+go 1.24.2
require (
- github.com/99designs/gqlgen v0.17.45
+ github.com/99designs/gqlgen v0.17.73
github.com/arangodb/go-driver v1.6.0
github.com/aws/aws-sdk-go v1.47.4
github.com/coreos/go-oidc/v3 v3.6.0
@@ -14,23 +12,21 @@ require (
github.com/gin-gonic/gin v1.9.1
github.com/glebarez/sqlite v1.10.0
github.com/gocql/gocql v1.6.0
- github.com/gokyle/twofactor v1.0.1
- github.com/golang-jwt/jwt v3.2.2+incompatible
+ github.com/golang-jwt/jwt/v4 v4.5.2
github.com/google/uuid v1.6.0
github.com/guregu/dynamo v1.20.2
- github.com/joho/godotenv v1.5.1
github.com/pquerna/otp v1.4.0
- github.com/redis/go-redis/v9 v9.2.1
+ github.com/redis/go-redis/v9 v9.6.3
github.com/robertkrimen/otto v0.2.1
- github.com/sirupsen/logrus v1.9.3
- github.com/stretchr/testify v1.9.0
- github.com/tuotoo/qrcode v0.0.0-20220425170535-52ccc2bebf5d
+ github.com/rs/zerolog v1.33.0
+ github.com/spf13/cobra v1.8.1
+ github.com/stretchr/testify v1.10.0
github.com/twilio/twilio-go v1.14.1
- github.com/vektah/gqlparser/v2 v2.5.11
+ github.com/vektah/gqlparser/v2 v2.5.26
go.mongodb.org/mongo-driver v1.12.1
- golang.org/x/crypto v0.21.0
- golang.org/x/oauth2 v0.13.0
- google.golang.org/appengine v1.6.8
+ golang.org/x/crypto v0.46.0
+ golang.org/x/oauth2 v0.30.0
+ golang.org/x/sync v0.19.0
gopkg.in/mail.v2 v2.3.1
gopkg.in/square/go-jose.v2 v2.6.0
gorm.io/driver/mysql v1.5.2
@@ -40,27 +36,28 @@ require (
)
require (
- github.com/agnivade/levenshtein v1.1.1 // indirect
+ github.com/agnivade/levenshtein v1.2.1 // indirect
github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230512164433-5d1fd1a340c9 // indirect
github.com/arangodb/go-velocypack v0.0.0-20200318135517-5af53c29c67e // indirect
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc // indirect
github.com/bytedance/sonic v1.9.1 // indirect
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
- github.com/cespare/xxhash/v2 v2.2.0 // indirect
+ github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
github.com/couchbase/gocbcore/v10 v10.2.8 // indirect
- github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
+ github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/glebarez/go-sqlite v1.21.2 // indirect
- github.com/go-jose/go-jose/v3 v3.0.0 // indirect
+ github.com/go-jose/go-jose/v3 v3.0.4 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.14.0 // indirect
github.com/go-sql-driver/mysql v1.7.0 // indirect
+ github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect
github.com/golang-sql/sqlexp v0.1.0 // indirect
@@ -70,9 +67,11 @@ require (
github.com/gorilla/websocket v1.5.0 // indirect
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed // indirect
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
+ github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
- github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
- github.com/jackc/pgx/v5 v5.4.3 // indirect
+ github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
+ github.com/jackc/pgx/v5 v5.5.4 // indirect
+ github.com/jackc/puddle/v2 v2.2.1 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
@@ -82,10 +81,9 @@ require (
github.com/leodido/go-urn v1.2.4 // indirect
github.com/libsql/libsql-client-go v0.0.0-20231026052543-fce76c0f39a7 // indirect
github.com/libsql/sqlite-antlr4-parser v0.0.0-20230802215326-5cb5bb604475 // indirect
- github.com/maruel/rs v1.1.0 // indirect
+ github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/microsoft/go-mssqldb v1.6.0 // indirect
- github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/montanaflynn/stats v0.7.0 // indirect
@@ -95,24 +93,24 @@ require (
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/rogpeppe/go-internal v1.11.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
- github.com/sosodev/duration v1.2.0 // indirect
+ github.com/sosodev/duration v1.3.1 // indirect
+ github.com/spf13/pflag v1.0.5 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.11 // indirect
- github.com/urfave/cli/v2 v2.27.1 // indirect
+ github.com/urfave/cli/v2 v2.27.6 // indirect
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
github.com/xdg-go/scram v1.1.2 // indirect
github.com/xdg-go/stringprep v1.0.4 // indirect
- github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
+ github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect
golang.org/x/arch v0.3.0 // indirect
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect
- golang.org/x/mod v0.16.0 // indirect
- golang.org/x/net v0.22.0 // indirect
- golang.org/x/sync v0.6.0 // indirect
- golang.org/x/sys v0.18.0 // indirect
- golang.org/x/text v0.14.0 // indirect
- golang.org/x/tools v0.19.0 // indirect
- google.golang.org/protobuf v1.33.0 // indirect
+ golang.org/x/mod v0.30.0 // indirect
+ golang.org/x/net v0.47.0 // indirect
+ golang.org/x/sys v0.39.0 // indirect
+ golang.org/x/text v0.32.0 // indirect
+ golang.org/x/tools v0.39.0 // indirect
+ google.golang.org/protobuf v1.36.6 // indirect
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/sourcemap.v1 v1.0.5 // indirect
@@ -122,5 +120,4 @@ require (
modernc.org/memory v1.5.0 // indirect
modernc.org/sqlite v1.23.1 // indirect
nhooyr.io/websocket v1.8.7 // indirect
- rsc.io/qr v0.2.0 // indirect
)
diff --git a/server/go.sum b/go.sum
similarity index 84%
rename from server/go.sum
rename to go.sum
index 4ce25c18b..c3327f3b7 100644
--- a/server/go.sum
+++ b/go.sum
@@ -1,5 +1,5 @@
-github.com/99designs/gqlgen v0.17.45 h1:bH0AH67vIJo8JKNKPJP+pOPpQhZeuVRQLf53dKIpDik=
-github.com/99designs/gqlgen v0.17.45/go.mod h1:Bas0XQ+Jiu/Xm5E33jC8sES3G+iC2esHBMXcq0fUPs0=
+github.com/99designs/gqlgen v0.17.73 h1:A3Ki+rHWqKbAOlg5fxiZBnz6OjW3nwupDHEG15gEsrg=
+github.com/99designs/gqlgen v0.17.73/go.mod h1:2RyGWjy2k7W9jxrs8MOQthXGkD3L3oGr0jXW3Pu8lGg=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.4.0/go.mod h1:ON4tFdPTwRcgWEaVDrN3584Ef+b7GgSJaXxe5fW9t4M=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.0/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.1/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q=
@@ -18,14 +18,14 @@ github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v0.8.0/go.mod h
github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0/go.mod h1:kgDmCTgBzIEPFElEF+FK0SdjAor06dRq2Go927dnQ6o=
github.com/AzureAD/microsoft-authentication-library-for-go v1.1.0 h1:HCc0+LpPfpCKs6LGGLAhwBARt9632unrVcI6i8s/8os=
github.com/AzureAD/microsoft-authentication-library-for-go v1.1.0/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
-github.com/PuerkitoBio/goquery v1.9.1 h1:mTL6XjbJTZdpfL+Gwl5U2h1l9yEkJjhmlTeV9VPW7UI=
-github.com/PuerkitoBio/goquery v1.9.1/go.mod h1:cW1n6TmIMDoORQU5IU/P1T3tGFunOeXEpGP2WHRwkbY=
-github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8=
-github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo=
+github.com/PuerkitoBio/goquery v1.10.3 h1:pFYcNSqHxBD06Fpj/KsbStFRsgRATgnf3LeXiUkhzPo=
+github.com/PuerkitoBio/goquery v1.10.3/go.mod h1:tMUX0zDMHXYlAQk6p35XxQMqMweEKB7iK7iLNd4RH4Y=
+github.com/agnivade/levenshtein v1.2.1 h1:EHBY3UOn1gwdy/VbFwgo4cxecRznFk7fKWN1KOX7eoM=
+github.com/agnivade/levenshtein v1.2.1/go.mod h1:QVVI16kDrtSuwcpd0p1+xMC6Z/VfhtCyDIjcwga4/DU=
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/andybalholm/cascadia v1.3.2 h1:3Xi6Dw5lHF15JtdcmAHD3i1+T8plmv7BQ/nsViSLyss=
-github.com/andybalholm/cascadia v1.3.2/go.mod h1:7gtRlve5FxPPgIgX36uWBX58OdBsSS6lUvCFb+h7KvU=
+github.com/andybalholm/cascadia v1.3.3 h1:AG2YHrzJIm4BZ19iwJ/DAua6Btl3IwJX+VI4kktS1LM=
+github.com/andybalholm/cascadia v1.3.3/go.mod h1:xNd9bqTn98Ln4DwST8/nG+H0yuB8Hmgu1YHNnWw0GeA=
github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230512164433-5d1fd1a340c9 h1:goHVqTbFX3AIo0tzGr14pgfAW2ZfPChKO21Z9MGf/gk=
github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230512164433-5d1fd1a340c9/go.mod h1:pSwJ0fSY5KhvocuWSx4fz3BA8OrA1bQn+K1Eli3BRwM=
github.com/arangodb/go-driver v1.6.0 h1:NFWj/idqXZxhFVueihMSI2R9NotNIsgvNfM/xmpekb4=
@@ -40,8 +40,6 @@ github.com/aws/aws-sdk-go v1.47.4/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3Tju
github.com/beevik/etree v1.1.0/go.mod h1:r8Aw8JqVegEf0w2fDnATrX9VpkMcyFeM0FhwO62wh+A=
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/bits-and-blooms/bitset v1.2.1 h1:M+/hrU9xlMp7t4TyTDQW97d3tRPVuKFC6zBEK16QnXY=
-github.com/bits-and-blooms/bitset v1.2.1/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
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/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc h1:biVzkmvwrH8WK8raXaxBx6fRVTlJILwEwQGL1I/ByEI=
@@ -55,13 +53,14 @@ github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s
github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM=
github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
-github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
-github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
+github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams=
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
github.com/coreos/go-oidc/v3 v3.6.0 h1:AKVxfYw1Gmkn/w96z0DbT/B/xFnzTd3MkZvWLjF4n/o=
github.com/coreos/go-oidc/v3 v3.6.0/go.mod h1:ZpHUsHBucTUj6WOkrP4E20UPynbLZzhTQ1XKCXkxyPc=
+github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/couchbase/gocb/v2 v2.6.4 h1:o5k5JnxYkgamVL9svx+vbXc7vKF5X72tNt/qORs+L30=
github.com/couchbase/gocb/v2 v2.6.4/go.mod h1:W/cHlBGfendPh53WzRaF1KIXTovI9DaI7EPeeqIsnmc=
github.com/couchbase/gocbcore/v10 v10.2.8 h1:Enjxyxd6XYIP0SSlKxt+GHL0J+A/GaLxGJZ13XCfOW4=
@@ -69,16 +68,17 @@ github.com/couchbase/gocbcore/v10 v10.2.8/go.mod h1:lYQIIk+tzoMcwtwU5GzPbDdqEkwk
github.com/couchbaselabs/gocaves/client v0.0.0-20230307083111-cc3960c624b1/go.mod h1:AVekAZwIY2stsJOMWLAS/0uA/+qdp7pjO8EHnl61QkY=
github.com/couchbaselabs/gocaves/client v0.0.0-20230404095311-05e3ba4f0259 h1:2TXy68EGEzIMHOx9UvczR5ApVecwCfQZ0LjkmwMI6g4=
github.com/couchbaselabs/gocaves/client v0.0.0-20230404095311-05e3ba4f0259/go.mod h1:AVekAZwIY2stsJOMWLAS/0uA/+qdp7pjO8EHnl61QkY=
-github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
-github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
+github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
+github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc=
+github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
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=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
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/dgryski/trifles v0.0.0-20230903005119-f50d829f2e54 h1:SG7nF6SRlWhcT7cNTs5R6Hk4V2lcmLz2NsG2VnInyNo=
+github.com/dgryski/trifles v0.0.0-20230903005119-f50d829f2e54/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.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
@@ -96,8 +96,8 @@ github.com/glebarez/go-sqlite v1.21.2 h1:3a6LFC4sKahUunAmynQKLZceZCOzUthkRkEAl9g
github.com/glebarez/go-sqlite v1.21.2/go.mod h1:sfxdZyhQjTM2Wry3gVYWaW072Ri1WMdWJi0k6+3382k=
github.com/glebarez/sqlite v1.10.0 h1:u4gt8y7OND/cCei/NMHmfbLxF6xP2wgKcT/BJf2pYkc=
github.com/glebarez/sqlite v1.10.0/go.mod h1:IJ+lfSOmiekhQsFTJRx/lHtGYmCdtAiTaf5wI9u5uHA=
-github.com/go-jose/go-jose/v3 v3.0.0 h1:s6rrhirfEP/CGIoc6p+PZAeogN2SxKav6Wp7+dyMWVo=
-github.com/go-jose/go-jose/v3 v3.0.0/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8=
+github.com/go-jose/go-jose/v3 v3.0.4 h1:Wp5HA7bLQcKnf6YYao/4kpRpVMp/yf6+pJKV8WFSaNY=
+github.com/go-jose/go-jose/v3 v3.0.4/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ=
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
@@ -112,6 +112,8 @@ github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg
github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc=
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
+github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=
+github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0=
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo=
github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8=
@@ -122,12 +124,13 @@ github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/gocql/gocql v1.6.0 h1:IdFdOTbnpbd0pDhl4REKQDM+Q0SzKXQ1Yh+YZZ8T/qU=
github.com/gocql/gocql v1.6.0/go.mod h1:3gM2c4D3AnkISwBxGnMMsS8Oy4y2lhbPRsH4xnJrHG8=
-github.com/gokyle/twofactor v1.0.1 h1:uRhvx0S4Hb82RPIDALnf7QxbmPL49LyyaCkJDpWx+Ek=
-github.com/gokyle/twofactor v1.0.1/go.mod h1:4gxzH1eaE/F3Pct/sCDNOylP0ClofUO5j4XZN9tKtLE=
+github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
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.4.3/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
+github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI=
+github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/golang-jwt/jwt/v5 v5.0.0 h1:1n1XNM9hk7O9mnQoNBGolZvzebBQ7p93ULHRc28XJUE=
github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA=
@@ -139,7 +142,6 @@ github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+Licev
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
-github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
@@ -147,11 +149,11 @@ github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.0/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.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
+github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ=
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo=
@@ -172,12 +174,16 @@ github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b
github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
+github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
+github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
-github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk=
-github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
-github.com/jackc/pgx/v5 v5.4.3 h1:cxFyXhxlvAifxnkKKdlxv8XqUf59tDlYjnV5YYfsJJY=
-github.com/jackc/pgx/v5 v5.4.3/go.mod h1:Ig06C2Vu0t5qXC60W8sqIthScaEnFvojjj9dSljmHRA=
+github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
+github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
+github.com/jackc/pgx/v5 v5.5.4 h1:Xp2aQS8uXButQdnCMWNmvx6UysWQQC+u1EoizjguY+8=
+github.com/jackc/pgx/v5 v5.5.4/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A=
+github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk=
+github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs=
github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM=
github.com/jcmturner/gofork v1.7.6/go.mod h1:1622LH6i/EZqLloHfE7IeZ0uEJwMSUyQ/nDd82IeqRo=
@@ -192,8 +198,6 @@ github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9Y
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.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
-github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/json-iterator/go v1.1.9/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=
@@ -222,17 +226,18 @@ github.com/libsql/sqlite-antlr4-parser v0.0.0-20230802215326-5cb5bb604475 h1:6Pf
github.com/libsql/sqlite-antlr4-parser v0.0.0-20230802215326-5cb5bb604475/go.mod h1:20nXSmcf0nAscrzqsXeC2/tA3KkV2eCiJqYuyAgl+ss=
github.com/localtunnel/go-localtunnel v0.0.0-20170326223115-8a804488f275 h1:IZycmTpoUtQK3PD60UYBwjaCUHUP7cML494ao9/O8+Q=
github.com/localtunnel/go-localtunnel v0.0.0-20170326223115-8a804488f275/go.mod h1:zt6UU74K6Z6oMOYJbJzYpYucqdcQwSMPBEdSvGiaUMw=
-github.com/maruel/rs v1.1.0 h1:dh4OceAF5yD06EASOrb+DS358LI4g0B90YApSdjCP6U=
-github.com/maruel/rs v1.1.0/go.mod h1:vzwMjzSJJxLIXmU62qHj6O5QRn5kvCKxFrfaFCxBcUY=
+github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
+github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
+github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
+github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
+github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6YIM=
github.com/mattn/go-sqlite3 v1.14.17/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
github.com/microsoft/go-mssqldb v1.6.0 h1:mM3gYdVwEPFrlg/Dvr2DNVEgYFG7L42l+dGc67NNNpc=
github.com/microsoft/go-mssqldb v1.6.0/go.mod h1:00mDtPbeQCRGC1HwOOR5K/gr30P1NcEG0vx6Kbv2aJU=
-github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
-github.com/mitchellh/mapstructure v1.5.0/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=
@@ -254,8 +259,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pquerna/otp v1.4.0 h1:wZvl1TIVxKRThZIBiwOOHOGP/1+nZyWBil9Y2XNEDzg=
github.com/pquerna/otp v1.4.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg=
-github.com/redis/go-redis/v9 v9.2.1 h1:WlYJg71ODF0dVspZZCpYmoF1+U1Jjk9Rwd7pq6QmlCg=
-github.com/redis/go-redis/v9 v9.2.1/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M=
+github.com/redis/go-redis/v9 v9.6.3 h1:8Dr5ygF1QFXRxIH/m3Xg9MMG1rS8YCtAgosrsewT6i0=
+github.com/redis/go-redis/v9 v9.6.3/go.mod h1:0C0c6ycQsdpVNQpxb1njEQIqkx5UcsM8FJCQLgE9+RA=
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
@@ -263,14 +268,19 @@ github.com/robertkrimen/otto v0.2.1 h1:FVP0PJ0AHIjC+N4pKCG9yCDz6LHNPCwi/GKID5pGG
github.com/robertkrimen/otto v0.2.1/go.mod h1:UPwtJ1Xu7JrLcZjNWN8orJaM5n5YEtqL//farB5FlRY=
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
+github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
+github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8=
+github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
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/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=
github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I=
-github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
-github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
-github.com/sosodev/duration v1.2.0 h1:pqK/FLSjsAADWY74SyWDCjOcd5l7H8GSnnOGEB9A1Us=
-github.com/sosodev/duration v1.2.0/go.mod h1:RQIBBX0+fMLc/D9+Jb/fwvVmo0eZvDDEERAikUR6SDg=
+github.com/sosodev/duration v1.3.1 h1:qtHBDMQ6lvMQsL15g4aopM4HEfOaYuhWBw3NPTtlqq4=
+github.com/sosodev/duration v1.3.1/go.mod h1:RQIBBX0+fMLc/D9+Jb/fwvVmo0eZvDDEERAikUR6SDg=
+github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
+github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
+github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
+github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
@@ -279,7 +289,6 @@ github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/
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/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/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
@@ -287,10 +296,8 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
-github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
-github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
-github.com/tuotoo/qrcode v0.0.0-20220425170535-52ccc2bebf5d h1:4x1FeGJRB00cvxnKXnRJDT89fvG/Lzm2ecm0vlr/qDs=
-github.com/tuotoo/qrcode v0.0.0-20220425170535-52ccc2bebf5d/go.mod h1:uSELzeIcTceNCgzbKdJuJa0ouCqqtkyzL+6bnA3rM+M=
+github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
+github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/twilio/twilio-go v1.14.1 h1:uyMwNe2naFKwxLpVflAHbKEPiW9iHNI8VF6NWLJJ1Kk=
github.com/twilio/twilio-go v1.14.1/go.mod h1:tdnfQ5TjbewoAu4lf9bMsGvfuJ/QU9gYuv9yx3TSIXU=
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
@@ -299,18 +306,18 @@ github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVM
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
-github.com/urfave/cli/v2 v2.27.1 h1:8xSQ6szndafKVRmfyeUMxkNUJQMjL1F2zmsZ+qHpfho=
-github.com/urfave/cli/v2 v2.27.1/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ=
-github.com/vektah/gqlparser/v2 v2.5.11 h1:JJxLtXIoN7+3x6MBdtIP59TP1RANnY7pXOaDnADQSf8=
-github.com/vektah/gqlparser/v2 v2.5.11/go.mod h1:1rCcfwB2ekJofmluGWXMSEnPMZgbxzwj6FaZ/4OT8Cc=
+github.com/urfave/cli/v2 v2.27.6 h1:VdRdS98FNhKZ8/Az8B7MTyGQmpIr36O1EHybx/LaZ4g=
+github.com/urfave/cli/v2 v2.27.6/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ=
+github.com/vektah/gqlparser/v2 v2.5.26 h1:REqqFkO8+SOEgZHR/eHScjjVjGS8Nk3RMO/juiTobN4=
+github.com/vektah/gqlparser/v2 v2.5.26/go.mod h1:D1/VCZtV3LPnQrcPBeR/q5jkSQIPti0uYCP/RI0gIeo=
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.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY=
github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4=
github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8=
github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM=
-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/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4=
+github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM=
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.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
@@ -321,7 +328,6 @@ golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUu
golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k=
golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
@@ -330,15 +336,16 @@ golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
-golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
-golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
+golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
+golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU=
+golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA=
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
-golang.org/x/mod v0.16.0 h1:QX4fJ0Rr5cPQCF7O9lh9Se4pmwfwskqZfq5moyldzic=
-golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
+golang.org/x/mod v0.30.0 h1:fDEXFVZ/fmCKProc/yAXXUijritrDzahmwwefnjoPFk=
+golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@@ -353,17 +360,17 @@ golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
-golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc=
-golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
-golang.org/x/oauth2 v0.13.0 h1:jDDenyj+WgFtmV3zYVoi8aE2BwtXFLWOA67ZfNWftiY=
-golang.org/x/oauth2 v0.13.0/go.mod h1:/JMhi4ZRXAf4HG9LiNmxvk+45+96RUlVThiH8FzNBn0=
+golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
+golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
+golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
+golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/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/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
-golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
-golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
+golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -376,15 +383,17 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/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-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/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-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
-golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
+golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
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.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
@@ -392,6 +401,7 @@ golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
+golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
@@ -403,26 +413,25 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
-golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
+golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
+golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
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-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
-golang.org/x/tools v0.19.0 h1:tfGCXNR1OsFG+sVdLAitlpjAvD/I6dHDKnYrpEZUHkw=
-golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc=
+golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ=
+golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
-google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=
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.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
-google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
+google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
+google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
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=
@@ -466,5 +475,3 @@ modernc.org/sqlite v1.23.1/go.mod h1:OrDj17Mggn6MhE+iPbBNf7RGKODDE9NFT0f3EwDzJqk
nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g=
nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0=
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
-rsc.io/qr v0.2.0 h1:6vBLea5/NRMVTz8V66gipeLycZMl/+UlFmk8DvqQ6WY=
-rsc.io/qr v0.2.0/go.mod h1:IF+uZjkb9fqyeF/4tlBoynqmQxUoPfWEKh921coOuXs=
diff --git a/server/gqlgen.yml b/gqlgen.yml
similarity index 88%
rename from server/gqlgen.yml
rename to gqlgen.yml
index 104bdab25..2258e4196 100644
--- a/server/gqlgen.yml
+++ b/gqlgen.yml
@@ -1,26 +1,26 @@
# Where are all the schema files located? globs are supported eg src/**/*.graphqls
schema:
- - graph/*.graphqls
+ - internal/graph/*.graphqls
# Where should the generated server code go?
exec:
- filename: graph/generated/generated.go
+ filename: internal/graph/generated/generated.go
package: generated
# Uncomment to enable federation
# federation:
-# filename: graph/generated/federation.go
+# filename: internal/graph/generated/federation.go
# package: generated
# Where should any generated models go?
model:
- filename: graph/model/models_gen.go
+ filename: internal/graph/model/models_gen.go
package: model
# Where should the resolver implementations go?
resolver:
layout: follow-schema
- dir: graph
+ dir: internal/graph
package: graph
# Optional: turn on use ` + "`" + `gqlgen:"fieldName"` + "`" + ` tags in your models
@@ -42,7 +42,7 @@ resolver:
# 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/internal/internal/graph/model"
# This section declares type mapping between the GraphQL and go type systems
#
diff --git a/internal/authenticators/config/config.go b/internal/authenticators/config/config.go
new file mode 100644
index 000000000..7d4834802
--- /dev/null
+++ b/internal/authenticators/config/config.go
@@ -0,0 +1,13 @@
+package config
+
+// AuthenticatorConfig defines authenticator config
+type AuthenticatorConfig struct {
+ // ScannerImage is the base64 of QR code image
+ ScannerImage string
+ // Secrets is the secret key
+ Secret string
+ // RecoveryCode is the list of recovery codes
+ RecoveryCodes []string
+ // RecoveryCodeMap is the map of recovery codes
+ RecoveryCodeMap map[string]bool
+}
diff --git a/internal/authenticators/providers.go b/internal/authenticators/providers.go
new file mode 100644
index 000000000..a22c5e82c
--- /dev/null
+++ b/internal/authenticators/providers.go
@@ -0,0 +1,38 @@
+package authenticators
+
+import (
+ "context"
+
+ ac "github.com/authorizerdev/authorizer/internal/authenticators/config"
+ "github.com/authorizerdev/authorizer/internal/authenticators/totp"
+ "github.com/authorizerdev/authorizer/internal/config"
+ "github.com/authorizerdev/authorizer/internal/storage"
+ "github.com/rs/zerolog"
+)
+
+// Dependencies defines the dependencies for authenticators provider
+type Dependencies struct {
+ Log *zerolog.Logger
+ StorageProvider storage.Provider
+}
+
+// Provider defines authenticators provider
+type Provider interface {
+ // Generate totp: to generate totp, store secret into db and returns base64 of QR code image
+ Generate(ctx context.Context, id string) (*ac.AuthenticatorConfig, error)
+ // Validate totp: user passcode with secret stored in our db
+ Validate(ctx context.Context, passcode string, userID string) (bool, error)
+ // ValidateRecoveryCode totp: allows user to validate using recovery code incase if they lost their device
+ ValidateRecoveryCode(ctx context.Context, recoveryCode, userID string) (bool, error)
+}
+
+// New returns a new authenticators provider
+func New(cfg *config.Config, deps *Dependencies) (Provider, error) {
+ if !cfg.EnableTOTPLogin {
+ return nil, nil
+ }
+ return totp.NewProvider(&totp.Dependencies{
+ Log: deps.Log,
+ StorageProvider: deps.StorageProvider,
+ })
+}
diff --git a/internal/authenticators/totp/provider.go b/internal/authenticators/totp/provider.go
new file mode 100644
index 000000000..04231c341
--- /dev/null
+++ b/internal/authenticators/totp/provider.go
@@ -0,0 +1,29 @@
+package totp
+
+import (
+ "github.com/rs/zerolog"
+
+ "github.com/authorizerdev/authorizer/internal/storage"
+)
+
+type Dependencies struct {
+ Log *zerolog.Logger
+ StorageProvider storage.Provider
+}
+
+type provider struct {
+ deps *Dependencies
+}
+
+// TOTPConfig defines totp config
+type TOTPConfig struct {
+ ScannerImage string
+ Secret string
+}
+
+// NewProvider returns a new totp provider
+func NewProvider(deps *Dependencies) (*provider, error) {
+ return &provider{
+ deps: deps,
+ }, nil
+}
diff --git a/server/authenticators/providers/totp/totp.go b/internal/authenticators/totp/totp.go
similarity index 70%
rename from server/authenticators/providers/totp/totp.go
rename to internal/authenticators/totp/totp.go
index b02fe293e..e96799b66 100644
--- a/server/authenticators/providers/totp/totp.go
+++ b/internal/authenticators/totp/totp.go
@@ -10,25 +10,24 @@ import (
"github.com/google/uuid"
"github.com/pquerna/otp/totp"
- log "github.com/sirupsen/logrus"
- "github.com/authorizerdev/authorizer/server/authenticators/providers"
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/crypto"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/db/models"
- "github.com/authorizerdev/authorizer/server/refs"
+ "github.com/authorizerdev/authorizer/internal/authenticators/config"
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/crypto"
+ "github.com/authorizerdev/authorizer/internal/refs"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
// Generate generates a Time-Based One-Time Password (TOTP) for a user and returns the base64-encoded QR code for frontend display.
-func (p *provider) Generate(ctx context.Context, id string) (*providers.AuthenticatorConfig, error) {
+func (p *provider) Generate(ctx context.Context, id string) (*config.AuthenticatorConfig, error) {
+ log := p.deps.Log.With().Str("func", "Generate (totp provider)").Logger()
var buf bytes.Buffer
- //get user details
- user, err := db.Provider.GetUserByID(ctx, id)
+ // Get user details
+ user, err := p.deps.StorageProvider.GetUserByID(ctx, id)
if err != nil {
return nil, err
}
- // generate totp, Authenticators hash is valid for 30 seconds
+ // Generate totp, Authenticators hash is valid for 30 seconds
key, err := totp.Generate(totp.GenerateOpts{
Issuer: "authorizer",
AccountName: refs.StringValue(user.Email),
@@ -36,7 +35,7 @@ func (p *provider) Generate(ctx context.Context, id string) (*providers.Authenti
if err != nil {
return nil, err
}
- //generating image for key and encoding to base64 for displaying in frontend
+ // Generating image for key and encoding to base64 for displaying in frontend
img, err := key.Image(200, 200)
if err != nil {
return nil, err
@@ -59,20 +58,20 @@ func (p *provider) Generate(ctx context.Context, id string) (*providers.Authenti
return nil, err
}
recoveryCodesString := string(jsonData)
- totpModel := &models.Authenticator{
+ totpModel := &schemas.Authenticator{
Secret: secret,
RecoveryCodes: refs.NewStringRef(recoveryCodesString),
UserID: user.ID,
Method: constants.EnvKeyTOTPAuthenticator,
}
- authenticator, err := db.Provider.GetAuthenticatorDetailsByUserId(ctx, user.ID, constants.EnvKeyTOTPAuthenticator)
+ authenticator, err := p.deps.StorageProvider.GetAuthenticatorDetailsByUserId(ctx, user.ID, constants.EnvKeyTOTPAuthenticator)
if err != nil {
- log.Debug("Failed to get authenticator details by user id, creating new record: ", err)
+ log.Debug().Err(err).Msg("error getting authenticator details")
// continue
}
if authenticator == nil {
// if authenticator is nil then create new authenticator
- _, err = db.Provider.AddAuthenticator(ctx, totpModel)
+ _, err = p.deps.StorageProvider.AddAuthenticator(ctx, totpModel)
if err != nil {
return nil, err
}
@@ -80,12 +79,12 @@ func (p *provider) Generate(ctx context.Context, id string) (*providers.Authenti
authenticator.Secret = secret
authenticator.RecoveryCodes = refs.NewStringRef(recoveryCodesString)
// if authenticator is not nil then update authenticator
- _, err = db.Provider.UpdateAuthenticator(ctx, authenticator)
+ _, err = p.deps.StorageProvider.UpdateAuthenticator(ctx, authenticator)
if err != nil {
return nil, err
}
}
- return &providers.AuthenticatorConfig{
+ return &config.AuthenticatorConfig{
ScannerImage: encodedText,
Secret: secret,
RecoveryCodes: recoveryCodes,
@@ -96,7 +95,7 @@ func (p *provider) Generate(ctx context.Context, id string) (*providers.Authenti
// Validate validates a Time-Based One-Time Password (TOTP) against the stored TOTP secret for a user.
func (p *provider) Validate(ctx context.Context, passcode string, userID string) (bool, error) {
// get totp details
- totpModel, err := db.Provider.GetAuthenticatorDetailsByUserId(ctx, userID, constants.EnvKeyTOTPAuthenticator)
+ totpModel, err := p.deps.StorageProvider.GetAuthenticatorDetailsByUserId(ctx, userID, constants.EnvKeyTOTPAuthenticator)
if err != nil {
return false, err
}
@@ -106,7 +105,7 @@ func (p *provider) Validate(ctx context.Context, passcode string, userID string)
if totpModel.VerifiedAt == nil && status {
timeNow := time.Now().Unix()
totpModel.VerifiedAt = &timeNow
- _, err = db.Provider.UpdateAuthenticator(ctx, totpModel)
+ _, err = p.deps.StorageProvider.UpdateAuthenticator(ctx, totpModel)
if err != nil {
return false, err
}
@@ -117,7 +116,7 @@ func (p *provider) Validate(ctx context.Context, passcode string, userID string)
// ValidateRecoveryCode validates a Time-Based One-Time Password (TOTP) recovery code against the stored TOTP recovery code for a user.
func (p *provider) ValidateRecoveryCode(ctx context.Context, recoveryCode, userID string) (bool, error) {
// get totp details
- totpModel, err := db.Provider.GetAuthenticatorDetailsByUserId(ctx, userID, constants.EnvKeyTOTPAuthenticator)
+ totpModel, err := p.deps.StorageProvider.GetAuthenticatorDetailsByUserId(ctx, userID, constants.EnvKeyTOTPAuthenticator)
if err != nil {
return false, err
}
@@ -143,7 +142,7 @@ func (p *provider) ValidateRecoveryCode(ctx context.Context, recoveryCode, userI
recoveryCodesString := string(jsonData)
totpModel.RecoveryCodes = refs.NewStringRef(recoveryCodesString)
// update recovery code map in db
- _, err = db.Provider.UpdateAuthenticator(ctx, totpModel)
+ _, err = p.deps.StorageProvider.UpdateAuthenticator(ctx, totpModel)
if err != nil {
return false, err
}
diff --git a/internal/authenticators/totp_store.go b/internal/authenticators/totp_store.go
new file mode 100644
index 000000000..306ac68df
--- /dev/null
+++ b/internal/authenticators/totp_store.go
@@ -0,0 +1,20 @@
+package authenticators
+
+// TODO delete file
+// Provider is the global authenticators provider.
+// var Provider providers.Provider
+
+// InitTOTPStore initializes the TOTP authenticator store if it's not disabled in the environment variables.
+// It sets the global Provider variable to a new TOTP provider.
+// func InitTOTPStore() error {
+// var err error
+// isTOTPEnvServiceDisabled, _ := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableTOTPLogin)
+
+// if !isTOTPEnvServiceDisabled {
+// Provider, err = totp.NewProvider()
+// if err != nil {
+// return err
+// }
+// }
+// return nil
+// }
diff --git a/server/cli/cli.go b/internal/cli/cli.go
similarity index 100%
rename from server/cli/cli.go
rename to internal/cli/cli.go
diff --git a/internal/config/config.go b/internal/config/config.go
new file mode 100644
index 000000000..fabdb48e8
--- /dev/null
+++ b/internal/config/config.go
@@ -0,0 +1,243 @@
+package config
+
+// Config defines the configuration for the authorizer instance
+type Config struct {
+ // Env is the environment of the authorizer instance
+ Env string
+ // OrganizationLogo is the logo of the organization
+ OrganizationLogo string
+ // OrganizationName is the name of the organization
+ OrganizationName string
+ // AdminSecret is the secret for the admin
+ AdminSecret string
+ // AllowedOrigins is the list of allowed origins
+ AllowedOrigins []string
+
+ // EnableLoginPage is the flag to enable login page
+ EnableLoginPage bool
+ // EnablePlayground is the flag to enable playground
+ EnablePlayground bool
+
+ // Database Configurations
+ // DatabaseType is the type of database to use
+ DatabaseType string
+ // DatabaseURL is the URL of the database
+ DatabaseURL string
+ // DatabaseName is the name of the database
+ DatabaseName string
+ // DatabaseUsername is the username for the database
+ DatabaseUsername string
+ // DatabasePassword is the password for the database
+ DatabasePassword string
+ // DatabaseHost is the host for the database
+ DatabaseHost string
+ // DatabasePort is the port for the database
+ DatabasePort int
+ // DatabaseCert is the certificate for the database
+ DatabaseCert string
+ // DatabaseCACert is the CA certificate for the database
+ DatabaseCACert string
+ // DatabaseCertKey is the certificate key for the database
+ DatabaseCertKey string
+
+ // CouchBase flags
+ // CouchBaseBucket is the bucket for the database
+ // Used only for CouchBase database
+ CouchBaseBucket string
+ // CouchBaseRamQuota is the RAM quota for the database
+ // Used only for CouchBase database
+ CouchBaseRamQuota string
+ // CouchBaseScope is the scope for the database
+ // Used only for CouchBase database
+ CouchBaseScope string
+
+ // AWS flags
+ // AWSRegion is the region for the database
+ // Used only for AWS database
+ AWSRegion string
+ // AWSAccessKeyID is the access key ID for the database
+ // Used only for AWS database
+ AWSAccessKeyID string
+ // AWSSecretAccessKey is the secret access key for the database
+ // Used only for AWS database
+ AWSSecretAccessKey string
+
+ // Email Configurations
+ // SMTPHost is the host for the SMTP server
+ SMTPHost string
+ // SMTPPort is the port for the SMTP server
+ SMTPPort int
+ // SMTPUsername is the username for the SMTP server
+ SMTPUsername string
+ // SMTPPassword is the password for the SMTP server
+ SMTPPassword string
+ // SMTPSenderEmail is the sender email for the SMTP server
+ SMTPSenderEmail string
+ // SMTPSenderName is the sender name for the SMTP server
+ SMTPSenderName string
+ // SMTPLocalName is the local name for the SMTP server
+ SMTPLocalName string
+ // SkipTLSVerification is the flag to skip TLS verification
+ SkipTLSVerification bool
+
+ // Memory Store Configurations
+ // RedisURL is the URL of the redis server
+ RedisURL string
+
+ // Auth Configurations
+ // DefaultRoles is the default roles for the user
+ // It is a comma separated string
+ // TODO: check derived keys
+ DefaultRoles []string
+ // Roles is the list of all the roles of the user
+ // It is a comma separated string
+ Roles []string
+ // ProtectedRoles is the list of all the protected roles
+ // For this roles, sign-up is disabled
+ // It is a comma separated string
+ ProtectedRoles []string
+ // EnableStrongPassword is the flag to enable strong password
+ EnableStrongPassword bool
+ // EnableTOTPLogin boolean to enable TOTP login
+ EnableTOTPLogin bool
+ // EnableBasicAuthentication boolean to enable basic authentication
+ EnableBasicAuthentication bool
+ // EnableMagicLinkLogin boolean to enable magic link login
+ EnableMagicLinkLogin bool
+ // EnableEmailVerification boolean to enable email verification
+ EnableEmailVerification bool
+ // EnableMobileBasicAuthentication boolean to enable mobile basic authentication
+ EnableMobileBasicAuthentication bool
+ // EnablePhoneVerification boolean to enable phone verification
+ EnablePhoneVerification bool
+ // EnableMFA boolean to enable MFA
+ EnableMFA bool
+ // EnableEmailOTP boolean to enable email OTP
+ EnableEmailOTP bool
+ // EnableSMSOTP boolean to enable SMS OTP
+ EnableSMSOTP bool
+ // EnableSignup boolean to enable signup
+ EnableSignup bool
+ // IsEmailServiceEnabled is derived from SMTP configurations
+ IsEmailServiceEnabled bool
+ // IsSMSServiceEnabled is derived from Twilio configurations
+ IsSMSServiceEnabled bool
+ // EnforceMFA is the flag to enforce MFA
+ EnforceMFA bool
+
+ // URLs
+ // ResetPasswordURL is the URL for reset password
+ ResetPasswordURL string
+
+ // JWT Configurations
+ // JWTType is the type of JWT to use
+ JWTType string
+ // JWTSecret is the secret for the JWT
+ JWTSecret string
+ // JWTPublicKey is the public key for the JWT
+ JWTPublicKey string
+ // JWTPrivateKey is the private key for the JWT
+ JWTPrivateKey string
+ // JWTRoleClaim is the role claim for the JWT
+ JWTRoleClaim string
+ // CustomAccessTokenScript is the custom access token script
+ CustomAccessTokenScript string
+
+ // OAuth Configurations
+ // ClientID is the client ID for the authorizer
+ ClientID string
+ // ClientSecret is the secret for the authorizer
+ ClientSecret string
+ // Default Authorize response mode
+ DefaultAuthorizeResponseMode string
+ // Default Authorize response type
+ DefaultAuthorizeResponseType string
+
+ // Twilio Configurations
+ // TwilioAPISecret is the API secret for Twilio
+ TwilioAPISecret string
+ // TwilioAPIKey is the API key for Twilio
+ TwilioAPIKey string
+ // TwilioSender is the sender for Twilio
+ TwilioSender string
+ // TwilioAccountSID is the account SID for Twilio
+ TwilioAccountSID string
+
+ // OAuth providers that authorizer supports
+ // GoogleClientID is the client ID for Google OAuth
+ GoogleClientID string
+ // GoogleClientSecret is the client secret for Google OAuth
+ GoogleClientSecret string
+ // Scopes is the list of scopes for Google OAuth
+ GoogleScopes []string
+
+ // GithubClientID is the client ID for Github OAuth
+ GithubClientID string
+ // GithubClientSecret is the client secret for Github OAuth
+ GithubClientSecret string
+ // GithubScopes is the list of scopes for Github OAuth
+ GithubScopes []string
+
+ // FacebookClientID is the client ID for Facebook OAuth
+ FacebookClientID string
+ // FacebookClientSecret is the client secret for Facebook OAuth
+ FacebookClientSecret string
+ // FacebookScopes is the list of scopes for Facebook OAuth
+ FacebookScopes []string
+
+ // LinkedinClientID is the client ID for Linkedin OAuth
+ LinkedinClientID string
+ // LinkedinClientSecret is the client secret for Linkedin OAuth
+ LinkedinClientSecret string
+ // LinkedinScopes is the list of scopes for Linkedin OAuth
+ LinkedinScopes []string
+
+ // TwitterClientID is the client ID for Twitter OAuth
+ TwitterClientID string
+ // TwitterClientSecret is the client secret for Twitter OAuth
+ TwitterClientSecret string
+ // TwitterScopes is the list of scopes for Twitter OAuth
+ TwitterScopes []string
+
+ // MicrosoftClientID is the client ID for Microsoft OAuth
+ MicrosoftClientID string
+ // MicrosoftClientSecret is the client secret for Microsoft OAuth
+ MicrosoftClientSecret string
+ // MicrosoftTenantID is the tenant ID for Microsoft OAuth
+ MicrosoftTenantID string
+ // MicrosoftScopes is the list of scopes for Microsoft OAuth
+ MicrosoftScopes []string
+
+ // AppleClientID is the client ID for Apple OAuth
+ AppleClientID string
+ // AppleClientSecret is the client secret for Apple OAuth
+ AppleClientSecret string
+ // AppleScopes is the list of scopes for Apple OAuth
+ AppleScopes []string
+
+ // DiscordClientID is the client ID for Discord OAuth
+ DiscordClientID string
+ // DiscordClientSecret is the client secret for Discord OAuth
+ DiscordClientSecret string
+ // DiscordScopes is the list of scopes for Discord OAuth
+ DiscordScopes []string
+
+ // TwitchClientID is the client ID for Twitch OAuth
+ TwitchClientID string
+ // TwitchClientSecret is the client secret for Twitch OAuth
+ TwitchClientSecret string
+ // TwitchScopes is the list of scopes for Twitch OAuth
+ TwitchScopes []string
+
+ // RobloxClientID is the client ID for Roblox OAuth
+ RobloxClientID string
+ // RobloxClientSecret is the client secret for Roblox OAuth
+ RobloxClientSecret string
+ // RobloxScopes is the list of scopes for Roblox OAuth
+ RobloxScopes []string
+
+ // IsAppCookieSecure is the flag to set secure(http only) cookie
+ AppCookieSecure bool
+ // IsAdminCookieSecure is the flag to set secure(http only) cookie
+ AdminCookieSecure bool
+}
diff --git a/server/constants/auth_methods.go b/internal/constants/auth_methods.go
similarity index 99%
rename from server/constants/auth_methods.go
rename to internal/constants/auth_methods.go
index ca2002fa6..659667b27 100644
--- a/server/constants/auth_methods.go
+++ b/internal/constants/auth_methods.go
@@ -9,6 +9,7 @@ const (
AuthRecipeMethodMagicLinkLogin = "magic_link_login"
// AuthRecipeMethodMobileOTP is the mobile_otp auth method
AuthRecipeMethodMobileOTP = "mobile_otp"
+
// AuthRecipeMethodGoogle is the google auth method
AuthRecipeMethodGoogle = "google"
// AuthRecipeMethodGithub is the github auth method
diff --git a/server/constants/authenticator_method.go b/internal/constants/authenticator_method.go
similarity index 100%
rename from server/constants/authenticator_method.go
rename to internal/constants/authenticator_method.go
diff --git a/server/constants/cookie.go b/internal/constants/cookie.go
similarity index 100%
rename from server/constants/cookie.go
rename to internal/constants/cookie.go
diff --git a/server/constants/db_types.go b/internal/constants/db_types.go
similarity index 82%
rename from server/constants/db_types.go
rename to internal/constants/db_types.go
index 63ad637fb..d6d0777f2 100644
--- a/server/constants/db_types.go
+++ b/internal/constants/db_types.go
@@ -11,24 +11,29 @@ const (
DbTypeMysql = "mysql"
// DbTypeSqlserver is the sqlserver database type
DbTypeSqlserver = "sqlserver"
- // DbTypeArangodb is the arangodb database type
- DbTypeArangodb = "arangodb"
- // DbTypeMongodb is the mongodb database type
- DbTypeMongodb = "mongodb"
// DbTypeYugabyte is the yugabyte database type
DbTypeYugabyte = "yugabyte"
// DbTypeMariaDB is the mariadb database type
DbTypeMariaDB = "mariadb"
- // DbTypeCassandra is the cassandra database type
+ // DbTypePlanetScaleDB is the planetscale database type
+ DbTypePlanetScaleDB = "planetscale"
+ // DbTypeCockroachDB is the cockroach database type
+ DbTypeCockroachDB = "cockroachdb"
+
+ // DbTypeArangoDB is the arangodb database type
+ DbTypeArangoDB = "arangodb"
+
+ // DbTypeMongoDB is the mongodb database type
+ DbTypeMongoDB = "mongodb"
+
+ // DbTypeCassandraDB is the cassandra database type
DbTypeCassandraDB = "cassandradb"
// DbTypeScyllaDB is the scylla database type
DbTypeScyllaDB = "scylladb"
- // DbTypeCockroachDB is the cockroach database type
- DbTypeCockroachDB = "cockroachdb"
- // DbTypePlanetScaleDB is the planetscale database type
- DbTypePlanetScaleDB = "planetscale"
+
// DbTypeDynamoDB is the Dynamo database type
DbTypeDynamoDB = "dynamodb"
+
// DbTypeCouchbaseDB is the Couchbase database type
DbTypeCouchbaseDB = "couchbase"
)
diff --git a/internal/constants/env.go b/internal/constants/env.go
new file mode 100644
index 000000000..be9761cd0
--- /dev/null
+++ b/internal/constants/env.go
@@ -0,0 +1,215 @@
+package constants
+
+var VERSION = "0.0.1"
+
+const (
+ // TestEnv is used for testing
+ TestEnv = "test"
+ // // EnvKeyEnv key for env variable ENV
+ // EnvKeyEnv = "ENV"
+ // // EnvKeyEnvPath key for cli arg variable ENV_PATH
+ // EnvKeyEnvPath = "ENV_PATH"
+ // // EnvKeyAuthorizerURL key for env variable AUTHORIZER_URL
+ // EnvKeyAuthorizerURL = "AUTHORIZER_URL"
+ // // EnvKeyPort key for env variable PORT
+ // EnvKeyPort = "PORT"
+ // // EnvKeyAccessTokenExpiryTime key for env variable ACCESS_TOKEN_EXPIRY_TIME
+ // EnvKeyAccessTokenExpiryTime = "ACCESS_TOKEN_EXPIRY_TIME"
+ // // EnvKeyAdminSecret key for env variable ADMIN_SECRET
+ // EnvKeyAdminSecret = "ADMIN_SECRET"
+ // // EnvKeyDatabaseType key for env variable DATABASE_TYPE
+ // 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
+ // EnvKeyDatabaseUsername = "DATABASE_USERNAME"
+ // // EnvKeyDatabasePassword key for env variable DATABASE_PASSWORD
+ // EnvKeyDatabasePassword = "DATABASE_PASSWORD"
+ // // EnvKeyDatabasePort key for env variable DATABASE_PORT
+ // EnvKeyDatabasePort = "DATABASE_PORT"
+ // // EnvKeyDatabaseHost key for env variable DATABASE_HOST
+ // EnvKeyDatabaseHost = "DATABASE_HOST"
+ // // EnvKeyDatabaseCert key for env variable DATABASE_CERT
+ // EnvKeyDatabaseCert = "DATABASE_CERT"
+ // // EnvKeyDatabaseCertKey key for env variable DATABASE_KEY
+ // EnvKeyDatabaseCertKey = "DATABASE_CERT_KEY"
+ // // EnvKeyDatabaseCACert key for env variable DATABASE_CA_CERT
+ // EnvKeyDatabaseCACert = "DATABASE_CA_CERT"
+ // // EnvCouchbaseBucket key for env variable COUCHBASE_BUCKET
+ // EnvCouchbaseBucket = "COUCHBASE_BUCKET"
+ // // EnvCouchbaseBucketRAMQuotaMB key for env variable COUCHBASE_BUCKET_RAM_QUOTA
+ // // This value should be parsed as number
+ // EnvCouchbaseBucketRAMQuotaMB = "COUCHBASE_BUCKET_RAM_QUOTA"
+ // // EnvCouchbaseBucket key for env variable COUCHBASE_SCOPE
+ // EnvCouchbaseScope = "COUCHBASE_SCOPE"
+ // // EnvKeySmtpHost key for env variable SMTP_HOST
+ // EnvKeySmtpHost = "SMTP_HOST"
+ // // EnvKeySmtpPort key for env variable SMTP_PORT
+ // EnvKeySmtpPort = "SMTP_PORT"
+ // // EnvKeySmtpUsername key for env variable SMTP_USERNAME
+ // 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"
+ // // EnvKeySenderName key for env variable SENDER_NAME
+ // EnvKeySenderName = "SENDER_NAME"
+ // EnvKeyIsEmailServiceEnabled key for env variable IS_EMAIL_SERVICE_ENABLED
+ // EnvKeyIsEmailServiceEnabled = "IS_EMAIL_SERVICE_ENABLED"
+ // EnvKeyIsSMSServiceEnabled key for env variable IS_SMS_SERVICE_ENABLED
+ // EnvKeyIsSMSServiceEnabled = "IS_SMS_SERVICE_ENABLED"
+ // EnvKeyAppCookieSecure key for env variable APP_COOKIE_SECURE
+ // EnvKeyAppCookieSecure = "APP_COOKIE_SECURE"
+ // EnvKeyAdminCookieSecure key for env variable ADMIN_COOKIE_SECURE
+ // EnvKeyAdminCookieSecure = "ADMIN_COOKIE_SECURE"
+ // EnvKeyJwtType key for env variable JWT_TYPE
+ // EnvKeyJwtType = "JWT_TYPE"
+ // // EnvKeyJwtSecret key for env variable JWT_SECRET
+ // EnvKeyJwtSecret = "JWT_SECRET"
+ // // EnvKeyJwtPrivateKey key for env variable JWT_PRIVATE_KEY
+ // EnvKeyJwtPrivateKey = "JWT_PRIVATE_KEY"
+ // // EnvKeyJwtPublicKey key for env variable JWT_PUBLIC_KEY
+ // EnvKeyJwtPublicKey = "JWT_PUBLIC_KEY"
+ // EnvKeyAppURL key for env variable APP_URL
+ // EnvKeyAppURL = "APP_URL"
+ // EnvKeyRedisURL key for env variable REDIS_URL
+ // EnvKeyRedisURL = "REDIS_URL"
+ // EnvKeyResetPasswordURL key for env variable RESET_PASSWORD_URL
+ // EnvKeyResetPasswordURL = "RESET_PASSWORD_URL"
+ // EnvKeyJwtRoleClaim key for env variable JWT_ROLE_CLAIM
+ // EnvKeyJwtRoleClaim = "JWT_ROLE_CLAIM"
+ // EnvKeyGoogleClientID key for env variable GOOGLE_CLIENT_ID
+ // EnvKeyGoogleClientID = "GOOGLE_CLIENT_ID"
+ // // EnvKeyGoogleClientSecret key for env variable GOOGLE_CLIENT_SECRET
+ // EnvKeyGoogleClientSecret = "GOOGLE_CLIENT_SECRET"
+ // // EnvKeyGithubClientID key for env variable GITHUB_CLIENT_ID
+ // EnvKeyGithubClientID = "GITHUB_CLIENT_ID"
+ // // EnvKeyGithubClientSecret key for env variable GITHUB_CLIENT_SECRET
+ // EnvKeyGithubClientSecret = "GITHUB_CLIENT_SECRET"
+ // // EnvKeyFacebookClientID key for env variable FACEBOOK_CLIENT_ID
+ // EnvKeyFacebookClientID = "FACEBOOK_CLIENT_ID"
+ // // EnvKeyFacebookClientSecret key for env variable FACEBOOK_CLIENT_SECRET
+ // EnvKeyFacebookClientSecret = "FACEBOOK_CLIENT_SECRET"
+ // // EnvKeyLinkedinClientID key for env variable LINKEDIN_CLIENT_ID
+ // EnvKeyLinkedInClientID = "LINKEDIN_CLIENT_ID"
+ // // EnvKeyLinkedinClientSecret key for env variable LINKEDIN_CLIENT_SECRET
+ // EnvKeyLinkedInClientSecret = "LINKEDIN_CLIENT_SECRET"
+ // // EnvKeyAppleClientID key for env variable APPLE_CLIENT_ID
+ // EnvKeyAppleClientID = "APPLE_CLIENT_ID"
+ // // EnvKeyAppleClientSecret key for env variable APPLE_CLIENT_SECRET
+ // EnvKeyAppleClientSecret = "APPLE_CLIENT_SECRET"
+ // // EnvKeyDiscordClientID key for env variable DISCORD_CLIENT_ID
+ // EnvKeyDiscordClientID = "DISCORD_CLIENT_ID"
+ // // EnvKeyDiscordClientSecret key for env variable DISCORD_CLIENT_SECRET
+ // EnvKeyDiscordClientSecret = "DISCORD_CLIENT_SECRET"
+ // // EnvKeyTwitterClientID key for env variable TWITTER_CLIENT_ID
+ // EnvKeyTwitterClientID = "TWITTER_CLIENT_ID"
+ // // EnvKeyTwitterClientSecret key for env variable TWITTER_CLIENT_SECRET
+ // EnvKeyTwitterClientSecret = "TWITTER_CLIENT_SECRET"
+ // // EnvKeyMicrosoftClientID key for env variable MICROSOFT_CLIENT_ID
+ // EnvKeyMicrosoftClientID = "MICROSOFT_CLIENT_ID"
+ // // EnvKeyMicrosoftActiveDirectoryTenantID key for env variable MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID
+ // EnvKeyMicrosoftActiveDirectoryTenantID = "MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID"
+ // // EnvKeyMicrosoftClientSecret key for env variable MICROSOFT_CLIENT_SECRET
+ // EnvKeyMicrosoftClientSecret = "MICROSOFT_CLIENT_SECRET"
+ // // EnvKeyTwitchClientID key for env variable TWITCH_CLIENT_ID
+ // EnvKeyTwitchClientID = "TWITCH_CLIENT_ID"
+ // // EnvKeyTwitchClientSecret key for env variable TWITCH_CLIENT_SECRET
+ // EnvKeyTwitchClientSecret = "TWITCH_CLIENT_SECRET"
+ // // EnvKeyRobloxClientID key for env variable ROBLOX_CLIENT_ID
+ // EnvKeyRobloxClientID = "ROBLOX_CLIENT_ID"
+ // // EnvKeyRobloxClientSecret key for env variable ROBLOX_CLIENT_SECRET
+ // EnvKeyRobloxClientSecret = "ROBLOX_CLIENT_SECRET"
+ // // EnvKeyOrganizationName key for env variable ORGANIZATION_NAME
+ // EnvKeyOrganizationName = "ORGANIZATION_NAME"
+ // // EnvKeyOrganizationLogo key for env variable ORGANIZATION_LOGO
+ // EnvKeyOrganizationLogo = "ORGANIZATION_LOGO"
+ // // EnvKeyCustomAccessTokenScript key for env variable CUSTOM_ACCESS_TOKEN_SCRIPT
+ // EnvKeyCustomAccessTokenScript = "CUSTOM_ACCESS_TOKEN_SCRIPT"
+
+ // Not Exposed Keys
+ // EnvKeyClientID key for env variable CLIENT_ID
+ // EnvKeyClientID = "CLIENT_ID"
+ // // EnvKeyClientSecret key for env variable CLIENT_SECRET
+ // EnvKeyClientSecret = "CLIENT_SECRET"
+ // // EnvKeyEncryptionKey key for env variable ENCRYPTION_KEY
+ // EnvKeyEncryptionKey = "ENCRYPTION_KEY"
+ // // EnvKeyJWK key for env variable JWK
+ // EnvKeyJWK = "JWK"
+
+ // Boolean variables
+ // EnvKeyIsProd key for env variable IS_PROD
+ // EnvKeyIsProd = "IS_PROD"
+ // // EnvKeyDisableEmailVerification key for env variable DISABLE_EMAIL_VERIFICATION
+ // EnvKeyDisableEmailVerification = "DISABLE_EMAIL_VERIFICATION"
+ // // EnvKeyDisableBasicAuthentication key for env variable DISABLE_BASIC_AUTH
+ // EnvKeyDisableBasicAuthentication = "DISABLE_BASIC_AUTHENTICATION"
+ // // EnvKeyDisableBasicAuthentication key for env variable DISABLE_MOBILE_BASIC_AUTH
+ // EnvKeyDisableMobileBasicAuthentication = "DISABLE_MOBILE_BASIC_AUTHENTICATION"
+ // // EnvKeyDisableMagicLinkLogin key for env variable DISABLE_MAGIC_LINK_LOGIN
+ // EnvKeyDisableMagicLinkLogin = "DISABLE_MAGIC_LINK_LOGIN"
+ // // EnvKeyDisableLoginPage key for env variable DISABLE_LOGIN_PAGE
+ // EnvKeyDisableLoginPage = "DISABLE_LOGIN_PAGE"
+ // // EnvKeyDisableSignUp key for env variable DISABLE_SIGN_UP
+ // EnvKeyDisableSignUp = "DISABLE_SIGN_UP"
+ // // EnvKeyDisableRedisForEnv key for env variable DISABLE_REDIS_FOR_ENV
+ // EnvKeyDisableRedisForEnv = "DISABLE_REDIS_FOR_ENV"
+ // EnvKeyDisableStrongPassword key for env variable DISABLE_STRONG_PASSWORD
+ // EnvKeyDisableStrongPassword = "DISABLE_STRONG_PASSWORD"
+ // EnvKeyEnforceMultiFactorAuthentication is key for env variable ENFORCE_MULTI_FACTOR_AUTHENTICATION
+ // If enforced and changed later on, existing user will have MFA but new user will not have MFA
+ // EnvKeyEnforceMultiFactorAuthentication = "ENFORCE_MULTI_FACTOR_AUTHENTICATION"
+ // EnvKeyDisableMultiFactorAuthentication is key for env variable DISABLE_MULTI_FACTOR_AUTHENTICATION
+ // this variable is used to completely disable multi factor authentication. It will have no effect on profile preference
+ // EnvKeyDisableMultiFactorAuthentication = "DISABLE_MULTI_FACTOR_AUTHENTICATION"
+ // EnvKeyDisableTOTPLogin is key for env variable DISABLE_TOTP_LOGIN
+ // this variable is used to completely disable totp verification
+ // EnvKeyDisableTOTPLogin = "DISABLE_TOTP_LOGIN"
+ // EnvKeyDisableMailOTPLogin is key for env variable DISABLE_MAIL_OTP_LOGIN
+ // this variable is used to completely disable totp verification
+ // EnvKeyDisableMailOTPLogin = "DISABLE_MAIL_OTP_LOGIN"
+ // EnvKeyDisablePhoneVerification is key for env variable DISABLE_PHONE_VERIFICATION
+ // this variable is used to disable phone verification
+ // EnvKeyDisablePhoneVerification = "DISABLE_PHONE_VERIFICATION"
+ // EnvKeyDisablePlayGround is key for env variable DISABLE_PLAYGROUND
+ // this variable will disable or enable playground use in dashboard
+ // EnvKeyDisablePlayGround = "DISABLE_PLAYGROUND"
+
+ // Slice variables
+ // EnvKeyRoles key for env variable ROLES
+ // EnvKeyRoles = "ROLES"
+ // EnvKeyProtectedRoles key for env variable PROTECTED_ROLES
+ // EnvKeyProtectedRoles = "PROTECTED_ROLES"
+ // EnvKeyDefaultRoles key for env variable DEFAULT_ROLES
+ // EnvKeyDefaultRoles = "DEFAULT_ROLES"
+ // EnvKeyAllowedOrigins key for env variable ALLOWED_ORIGINS
+ // EnvKeyAllowedOrigins = "ALLOWED_ORIGINS"
+
+ // For oauth/openid/authorize
+ // EnvKeyDefaultAuthorizeResponseType key for env variable DEFAULT_AUTHORIZE_RESPONSE_TYPE
+ // This env is used for setting default response type in authorize handler
+ // EnvKeyDefaultAuthorizeResponseType = "DEFAULT_AUTHORIZE_RESPONSE_TYPE"
+ // EnvKeyDefaultAuthorizeResponseMode key for env variable DEFAULT_AUTHORIZE_RESPONSE_MODE
+ // This env is used for setting default response mode in authorize handler
+ // EnvKeyDefaultAuthorizeResponseMode = "DEFAULT_AUTHORIZE_RESPONSE_MODE"
+
+ // Twilio env variables
+ // EnvKeyTwilioAPIKey key for env variable TWILIO_API_KEY
+ // EnvKeyTwilioAPIKey = "TWILIO_API_KEY"
+ // // EnvKeyTwilioAPISecret key for env variable TWILIO_API_SECRET
+ // EnvKeyTwilioAPISecret = "TWILIO_API_SECRET"
+ // // EnvKeyTwilioAccountSID key for env variable TWILIO_ACCOUNT_SID
+ // EnvKeyTwilioAccountSID = "TWILIO_ACCOUNT_SID"
+ // // EnvKeyTwilioSender key for env variable TWILIO_SENDER
+ // EnvKeyTwilioSender = "TWILIO_SENDER"
+)
diff --git a/server/constants/oauth2.go b/internal/constants/oauth2.go
similarity index 100%
rename from server/constants/oauth2.go
rename to internal/constants/oauth2.go
diff --git a/server/constants/oauth_info_urls.go b/internal/constants/oauth_info_urls.go
similarity index 100%
rename from server/constants/oauth_info_urls.go
rename to internal/constants/oauth_info_urls.go
diff --git a/server/constants/pagination.go b/internal/constants/pagination.go
similarity index 100%
rename from server/constants/pagination.go
rename to internal/constants/pagination.go
diff --git a/server/constants/token_types.go b/internal/constants/token_types.go
similarity index 100%
rename from server/constants/token_types.go
rename to internal/constants/token_types.go
diff --git a/server/constants/verification_types.go b/internal/constants/verification_types.go
similarity index 100%
rename from server/constants/verification_types.go
rename to internal/constants/verification_types.go
diff --git a/server/constants/webhook_event.go b/internal/constants/webhook_event.go
similarity index 100%
rename from server/constants/webhook_event.go
rename to internal/constants/webhook_event.go
diff --git a/server/cookie/admin_cookie.go b/internal/cookie/admin_cookie.go
similarity index 57%
rename from server/cookie/admin_cookie.go
rename to internal/cookie/admin_cookie.go
index f03a945ac..d0e2b4b2b 100644
--- a/server/cookie/admin_cookie.go
+++ b/internal/cookie/admin_cookie.go
@@ -3,22 +3,14 @@ package cookie
import (
"net/url"
- log "github.com/sirupsen/logrus"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/parsers"
"github.com/gin-gonic/gin"
+
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/parsers"
)
// SetAdminCookie sets the admin cookie in the response
-func SetAdminCookie(gc *gin.Context, token string) {
- adminCookieSecure, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyAdminCookieSecure)
- if err != nil {
- log.Debug("Error while getting admin cookie secure from env variable: %v", err)
- adminCookieSecure = true
- }
-
+func SetAdminCookie(gc *gin.Context, token string, adminCookieSecure bool) {
secure := adminCookieSecure
httpOnly := adminCookieSecure
hostname := parsers.GetHost(gc)
@@ -43,13 +35,7 @@ func GetAdminCookie(gc *gin.Context) (string, error) {
}
// DeleteAdminCookie sets the response cookie to empty
-func DeleteAdminCookie(gc *gin.Context) {
- adminCookieSecure, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyAdminCookieSecure)
- if err != nil {
- log.Debug("Error while getting admin cookie secure from env variable: %v", err)
- adminCookieSecure = true
- }
-
+func DeleteAdminCookie(gc *gin.Context, adminCookieSecure bool) {
secure := adminCookieSecure
httpOnly := adminCookieSecure
hostname := parsers.GetHost(gc)
diff --git a/server/cookie/cookie.go b/internal/cookie/cookie.go
similarity index 74%
rename from server/cookie/cookie.go
rename to internal/cookie/cookie.go
index 7dd9ccf89..6f707b443 100644
--- a/server/cookie/cookie.go
+++ b/internal/cookie/cookie.go
@@ -4,22 +4,14 @@ import (
"net/http"
"net/url"
- log "github.com/sirupsen/logrus"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/parsers"
"github.com/gin-gonic/gin"
+
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/parsers"
)
// SetSession sets the session cookie in the response
-func SetSession(gc *gin.Context, sessionID string) {
- appCookieSecure, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyAppCookieSecure)
- if err != nil {
- log.Debug("Error while getting app cookie secure from env variable: %v", err)
- appCookieSecure = true
- }
-
+func SetSession(gc *gin.Context, sessionID string, appCookieSecure bool) {
secure := appCookieSecure
httpOnly := appCookieSecure
hostname := parsers.GetHost(gc)
@@ -48,13 +40,7 @@ func SetSession(gc *gin.Context, sessionID string) {
}
// DeleteSession sets session cookies to expire
-func DeleteSession(gc *gin.Context) {
- appCookieSecure, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyAppCookieSecure)
- if err != nil {
- log.Debug("Error while getting app cookie secure from env variable: %v", err)
- appCookieSecure = true
- }
-
+func DeleteSession(gc *gin.Context, appCookieSecure bool) {
secure := appCookieSecure
httpOnly := appCookieSecure
hostname := parsers.GetHost(gc)
diff --git a/server/cookie/mfa_session.go b/internal/cookie/mfa_session.go
similarity index 74%
rename from server/cookie/mfa_session.go
rename to internal/cookie/mfa_session.go
index 3fdcaacec..81256a5bf 100644
--- a/server/cookie/mfa_session.go
+++ b/internal/cookie/mfa_session.go
@@ -4,22 +4,16 @@ import (
"net/http"
"net/url"
- log "github.com/sirupsen/logrus"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/parsers"
"github.com/gin-gonic/gin"
+
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/parsers"
)
-// SetMfaSession sets the mfa session cookie in the response
-func SetMfaSession(gc *gin.Context, sessionID string) {
- appCookieSecure, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyAppCookieSecure)
- if err != nil {
- log.Debug("Error while getting app cookie secure from env variable: %v", err)
- appCookieSecure = true
- }
+// TODO set app cookie as per config
+// SetMfaSession sets the mfa session cookie in the response
+func SetMfaSession(gc *gin.Context, sessionID string, appCookieSecure bool) {
secure := appCookieSecure
httpOnly := appCookieSecure
hostname := parsers.GetHost(gc)
@@ -48,13 +42,7 @@ func SetMfaSession(gc *gin.Context, sessionID string) {
}
// DeleteMfaSession deletes the mfa session cookies to expire
-func DeleteMfaSession(gc *gin.Context) {
- appCookieSecure, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyAppCookieSecure)
- if err != nil {
- log.Debug("Error while getting app cookie secure from env variable: %v", err)
- appCookieSecure = true
- }
-
+func DeleteMfaSession(gc *gin.Context, appCookieSecure bool) {
secure := appCookieSecure
httpOnly := appCookieSecure
hostname := parsers.GetHost(gc)
diff --git a/internal/crypto/aes.go b/internal/crypto/aes.go
new file mode 100644
index 000000000..5c8fec237
--- /dev/null
+++ b/internal/crypto/aes.go
@@ -0,0 +1,143 @@
+package crypto
+
+import (
+ "bytes"
+ "crypto/aes"
+ "crypto/cipher"
+ "crypto/rand"
+ "encoding/base64"
+ "errors"
+ "io"
+)
+
+// var bytes = []byte{35, 46, 57, 24, 85, 35, 24, 74, 87, 35, 88, 98, 66, 32, 14, 0o5}
+
+// const (
+// // Static key for encryption
+// encryptionKey = "authorizerdev"
+// )
+
+// EncryptAES method is to encrypt or hide any classified text
+func EncryptAES(key, text string) (string, error) {
+ keyBytes := []byte(ensureHashKey(key))
+ block, err := aes.NewCipher(keyBytes)
+ if err != nil {
+ return "", err
+ }
+
+ // The IV needs to be unique, but not secure. Therefore, it's common to
+ // include it at the beginning of the ciphertext.
+ ciphertext := make([]byte, aes.BlockSize+len(text))
+ iv := ciphertext[:aes.BlockSize]
+ if _, err := io.ReadFull(rand.Reader, iv); err != nil {
+ return "", err
+ }
+
+ stream := cipher.NewCFBEncrypter(block, iv)
+ stream.XORKeyStream(ciphertext[aes.BlockSize:], []byte(text))
+
+ // Encode the ciphertext to URL-safe base64 without padding
+ return base64.RawURLEncoding.EncodeToString(ciphertext), nil
+}
+
+// DecryptAES method is to extract back the encrypted text
+func DecryptAES(key, encryptedText string) (string, error) {
+ keyBytes := []byte(ensureHashKey(key))
+ ciphertext, err := base64.RawURLEncoding.DecodeString(encryptedText)
+ if err != nil {
+ return "", err
+ }
+
+ block, err := aes.NewCipher(keyBytes)
+ if err != nil {
+ return "", err
+ }
+
+ if len(ciphertext) < aes.BlockSize {
+ return "", errors.New("ciphertext too short")
+ }
+
+ iv := ciphertext[:aes.BlockSize]
+ ciphertext = ciphertext[aes.BlockSize:]
+
+ stream := cipher.NewCFBDecrypter(block, iv)
+ stream.XORKeyStream(ciphertext, ciphertext)
+
+ return string(ciphertext), nil
+}
+
+// ensureHashKey ensure the key is 32 bytes long
+// if short it will append 0's to the key
+// if long it will truncate the key
+func ensureHashKey(key string) string {
+ if len(key) < 32 {
+ return key + string(bytes.Repeat([]byte{0}, 32-len(key)))
+ }
+ return key[:32]
+}
+
+// EncryptAESEnv encrypts data using AES algorithm
+// kept for the backward compatibility of env data encryption
+// TODO: Check if this is still needed
+// func EncryptAESEnv(text []byte) ([]byte, error) {
+// var res []byte
+// key := []byte(encryptionKey)
+// c, err := aes.NewCipher(key)
+// if err != nil {
+// return res, err
+// }
+
+// // gcm or Galois/Counter Mode, is a mode of operation
+// // for symmetric key cryptographic block ciphers
+// // - https://en.wikipedia.org/wiki/Galois/Counter_Mode
+// gcm, err := cipher.NewGCM(c)
+// if err != nil {
+// return res, err
+// }
+
+// // creates a new byte array the size of the nonce
+// // which must be passed to Seal
+// nonce := make([]byte, gcm.NonceSize())
+// // populates our nonce with a cryptographically secure
+// // random sequence
+// if _, err = io.ReadFull(rand.Reader, nonce); err != nil {
+// return res, err
+// }
+
+// // here we encrypt our text using the Seal function
+// // Seal encrypts and authenticates plaintext, authenticates the
+// // additional data and appends the result to dst, returning the updated
+// // slice. The nonce must be NonceSize() bytes long and unique for all
+// // time, for a given key.
+// return gcm.Seal(nonce, nonce, text, nil), nil
+// }
+
+// // DecryptAES decrypts data using AES algorithm
+// // Kept for the backward compatibility of env data decryption
+// // TODO: Check if this is still needed
+// func DecryptAESEnv(ciphertext []byte) ([]byte, error) {
+// var res []byte
+// key := []byte(encryptionKey)
+// c, err := aes.NewCipher(key)
+// if err != nil {
+// return res, err
+// }
+
+// gcm, err := cipher.NewGCM(c)
+// if err != nil {
+// return res, err
+// }
+
+// nonceSize := gcm.NonceSize()
+// if len(ciphertext) < nonceSize {
+// return res, err
+// }
+
+// nonce, ciphertext := ciphertext[:nonceSize], ciphertext[nonceSize:]
+// plaintext, err := gcm.Open(nil, nonce, ciphertext, nil)
+// if err != nil {
+// return res, err
+// }
+
+// return plaintext, nil
+// }
diff --git a/server/crypto/b64.go b/internal/crypto/b64.go
similarity index 100%
rename from server/crypto/b64.go
rename to internal/crypto/b64.go
diff --git a/internal/crypto/common.go b/internal/crypto/common.go
new file mode 100644
index 000000000..3f5a3fedc
--- /dev/null
+++ b/internal/crypto/common.go
@@ -0,0 +1,71 @@
+package crypto
+
+import (
+ "crypto/x509"
+
+ "golang.org/x/crypto/bcrypt"
+ "gopkg.in/square/go-jose.v2"
+)
+
+// GetPubJWK returns JWK for given keys
+func GetPubJWK(algo, keyID string, publicKey interface{}) (string, error) {
+ jwk := &jose.JSONWebKeySet{
+ Keys: []jose.JSONWebKey{
+ {
+ Algorithm: algo,
+ Key: publicKey,
+ Use: "sig",
+ KeyID: keyID,
+ Certificates: []*x509.Certificate{},
+ CertificateThumbprintSHA1: []uint8{},
+ CertificateThumbprintSHA256: []uint8{},
+ },
+ },
+ }
+ jwkPublicKey, err := jwk.Keys[0].MarshalJSON()
+ if err != nil {
+ return "", err
+ }
+ return string(jwkPublicKey), nil
+}
+
+// // EncryptEnvData is used to encrypt the env data
+// TODO: remove this function if not needed
+// func EncryptEnvData(data map[string]interface{}) (string, error) {
+// jsonBytes, err := json.Marshal(data)
+// if err != nil {
+// return "", err
+// }
+
+// storeData, err := memorystore.Provider.GetEnvStore()
+// if err != nil {
+// return "", err
+// }
+
+// err = json.Unmarshal(jsonBytes, &storeData)
+// if err != nil {
+// return "", err
+// }
+
+// configData, err := json.Marshal(storeData)
+// if err != nil {
+// return "", err
+// }
+
+// encryptedConfig, err := EncryptAESEnv(configData)
+// if err != nil {
+// return "", err
+// }
+
+// return EncryptB64(string(encryptedConfig)), nil
+// }
+
+// EncryptPassword is used for encrypting password
+func EncryptPassword(password string) (string, error) {
+ pw, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
+ if err != nil {
+ return "", err
+ }
+
+ return string(pw), nil
+}
diff --git a/server/crypto/ecdsa.go b/internal/crypto/ecdsa.go
similarity index 100%
rename from server/crypto/ecdsa.go
rename to internal/crypto/ecdsa.go
diff --git a/server/crypto/hmac.go b/internal/crypto/hmac.go
similarity index 100%
rename from server/crypto/hmac.go
rename to internal/crypto/hmac.go
diff --git a/server/crypto/rsa.go b/internal/crypto/rsa.go
similarity index 100%
rename from server/crypto/rsa.go
rename to internal/crypto/rsa.go
diff --git a/internal/email/email.go b/internal/email/email.go
new file mode 100644
index 000000000..30e6526a2
--- /dev/null
+++ b/internal/email/email.go
@@ -0,0 +1,146 @@
+package email
+
+import (
+ "bytes"
+ "context"
+ "crypto/tls"
+ "strings"
+ "text/template"
+
+ "github.com/rs/zerolog"
+ gomail "gopkg.in/mail.v2"
+
+ "github.com/authorizerdev/authorizer/internal/config"
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/email/templates"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/storage"
+)
+
+// Provider interface for email provider
+type Provider interface {
+ SendEmail(to []string, event string, data map[string]interface{}) error
+}
+
+// Dependencies struct for email provider
+type Dependencies struct {
+ Log *zerolog.Logger
+ StorageProvider storage.Provider
+}
+
+// provider struct for email provider
+type provider struct {
+ config *config.Config
+ deps *Dependencies
+
+ mailer *gomail.Dialer
+}
+
+// New returns a new email provider
+func New(
+ config *config.Config,
+ deps *Dependencies,
+) (Provider, error) {
+ mailer := gomail.NewDialer(config.SMTPHost, config.SMTPPort, config.SMTPUsername, config.SMTPPassword)
+ if strings.TrimSpace(config.SMTPLocalName) != "" {
+ mailer.LocalName = config.SMTPLocalName
+ }
+ if config.SkipTLSVerification {
+ mailer.TLSConfig = &tls.Config{InsecureSkipVerify: true}
+ }
+ return &provider{
+ config: config,
+ deps: deps,
+ mailer: mailer,
+ }, nil
+}
+
+// SendEmail function to send mail
+func (p *provider) SendEmail(to []string, event string, data map[string]interface{}) error {
+ log := p.deps.Log.With().Str("func", "send_email").Str("event", event).Logger()
+ // Don't trigger email sending in case of test
+ if p.config.Env == constants.TestEnv {
+ return nil
+ }
+
+ tmp, err := p.getEmailTemplate(event, data)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get email template")
+ return err
+ }
+
+ m := gomail.NewMessage()
+ m.SetAddressHeader("From", p.config.SMTPSenderEmail, p.config.SMTPSenderName)
+ m.SetHeader("To", to...)
+ m.SetHeader("Subject", tmp.Subject)
+ m.SetBody("text/html", tmp.Template)
+ if err := p.mailer.DialAndSend(m); err != nil {
+ log.Debug().Err(err).Msg("Failed to send email")
+ return err
+ }
+ return nil
+}
+
+func getDefaultTemplate(event string) *model.EmailTemplate {
+ switch event {
+ case constants.VerificationTypeBasicAuthSignup, constants.VerificationTypeMagicLinkLogin, constants.VerificationTypeUpdateEmail:
+ return &model.EmailTemplate{
+ Subject: templates.EmailVerificationSubject,
+ Template: templates.EmailVerificationTemplate,
+ }
+ case constants.VerificationTypeForgotPassword:
+ return &model.EmailTemplate{
+ Subject: templates.ForgotPasswordSubject,
+ Template: templates.ForgotPasswordTemplate,
+ }
+ case constants.VerificationTypeInviteMember:
+ return &model.EmailTemplate{
+ Subject: templates.InviteUserEmailSubject,
+ Template: templates.InviteUserEmailTemplate,
+ }
+ case constants.VerificationTypeOTP:
+ return &model.EmailTemplate{
+ Subject: templates.OtpEmailSubject,
+ Template: templates.OtpEmailTemplate,
+ }
+ default:
+ return nil
+ }
+}
+
+func (p *provider) getEmailTemplate(event string, data map[string]interface{}) (*model.EmailTemplate, error) {
+ ctx := context.Background()
+ var tmp *model.EmailTemplate
+ et, err := p.deps.StorageProvider.GetEmailTemplateByEventName(ctx, event)
+ if err != nil || et == nil {
+ tmp = getDefaultTemplate(event)
+ } else {
+ tmp = et.AsAPIEmailTemplate()
+ }
+
+ templ, err := template.New(event + "_template.tmpl").Parse(tmp.Template)
+ if err != nil {
+ return nil, err
+ }
+ buf := &bytes.Buffer{}
+ err = templ.Execute(buf, data)
+ if err != nil {
+ return nil, err
+ }
+ templateString := buf.String()
+
+ subject, err := template.New(event + "_subject.tmpl").Parse(tmp.Subject)
+ if err != nil {
+ return nil, err
+ }
+ buf = &bytes.Buffer{}
+ err = subject.Execute(buf, data)
+ if err != nil {
+ return nil, err
+ }
+ subjectString := buf.String()
+ return &model.EmailTemplate{
+ Template: templateString,
+ Subject: subjectString,
+ }, nil
+}
diff --git a/server/email/email_verification.go b/internal/email/templates/email_verification.go
similarity index 95%
rename from server/email/email_verification.go
rename to internal/email/templates/email_verification.go
index 7a3de2557..9d537c789 100644
--- a/server/email/email_verification.go
+++ b/internal/email/templates/email_verification.go
@@ -1,8 +1,12 @@
-package email
+package templates
const (
- emailVerificationSubject = "Please verify your email"
- emailVerificationTemplate = `
+ // EmailVerificationSubject is the default subject of the email
+ // sent for email verification
+ EmailVerificationSubject = "Please verify your email"
+ // EmailVerificationTemplate is the default template of the email
+ // sent for email verification
+ EmailVerificationTemplate = `
diff --git a/server/email/forgot_password_email.go b/internal/email/templates/forgot_password.go
similarity index 96%
rename from server/email/forgot_password_email.go
rename to internal/email/templates/forgot_password.go
index 678f83c80..2fc80ffb2 100644
--- a/server/email/forgot_password_email.go
+++ b/internal/email/templates/forgot_password.go
@@ -1,8 +1,10 @@
-package email
+package templates
const (
- forgotPasswordSubject = "Reset Password"
- forgotPasswordTemplate = `
+ // ForgotPasswordSubject is the default subject for forgot password email
+ ForgotPasswordSubject = "Reset Password"
+ // ForgotPasswordTemplate is the default template for forgot password email
+ ForgotPasswordTemplate = `
diff --git a/server/email/invite_email.go b/internal/email/templates/invite_user.go
similarity index 95%
rename from server/email/invite_email.go
rename to internal/email/templates/invite_user.go
index bec33a60c..351a8a3d4 100644
--- a/server/email/invite_email.go
+++ b/internal/email/templates/invite_user.go
@@ -1,8 +1,10 @@
-package email
+package templates
const (
- inviteEmailSubject = "Please accept the invitation"
- inviteEmailTemplate = `
+ // InviteUserEmailSubject is the default subject of the email sent to invite a user
+ InviteUserEmailSubject = "Please accept the invitation"
+ // InviteUserEmailTemplate is the default template of the email sent to invite a user
+ InviteUserEmailTemplate = `
diff --git a/server/email/otp.go b/internal/email/templates/otp.go
similarity index 96%
rename from server/email/otp.go
rename to internal/email/templates/otp.go
index d3bf7c0d5..0c6874c8d 100644
--- a/server/email/otp.go
+++ b/internal/email/templates/otp.go
@@ -1,8 +1,10 @@
-package email
+package templates
const (
- otpEmailSubject = "OTP for your multi factor authentication"
- otpEmailTemplate = `
+ // OtPEmailSubject is the default subject of the OTP email
+ OtpEmailSubject = "OTP for your multi factor authentication"
+ // OtpEmailTemplate is the default template of the OTP email
+ OtpEmailTemplate = `
diff --git a/internal/env/env.go b/internal/env/env.go
new file mode 100644
index 000000000..b5c8b316f
--- /dev/null
+++ b/internal/env/env.go
@@ -0,0 +1,887 @@
+package env
+
+// InitEnv to initialize EnvData and through error if required env are not present
+// func InitAllEnv() error {
+// envData, err := GetEnvData()
+// if err != nil || envData == nil {
+// log.Info("No env data found in db, using local clone of env data")
+// // get clone of current store
+// envData, err = memorystore.Provider.GetEnvStore()
+// if err != nil {
+// log.Debug("Error while getting env data from memorystore: ", err)
+// return err
+// }
+// }
+
+// // unique client id for each instance
+// cid, ok := envData[constants.EnvKeyClientID]
+// clientID := ""
+// if !ok || cid == "" {
+// clientID = uuid.New().String()
+// envData[constants.EnvKeyClientID] = clientID
+// } else {
+// clientID = cid.(string)
+// }
+
+// // unique client secret for each instance
+// if val, ok := envData[constants.EnvKeyClientSecret]; !ok || val != "" {
+// envData[constants.EnvKeyClientSecret] = uuid.New().String()
+// }
+
+// // os string envs
+// osEnv := os.Getenv(constants.EnvKeyEnv)
+// osAppURL := os.Getenv(constants.EnvKeyAppURL)
+// osAuthorizerURL := os.Getenv(constants.EnvKeyAuthorizerURL)
+// osPort := os.Getenv(constants.EnvKeyPort)
+// osAccessTokenExpiryTime := os.Getenv(constants.EnvKeyAccessTokenExpiryTime)
+// osAdminSecret := os.Getenv(constants.EnvKeyAdminSecret)
+// osSmtpHost := os.Getenv(constants.EnvKeySmtpHost)
+// 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)
+// osSenderName := os.Getenv(constants.EnvKeySenderName)
+// osJwtType := os.Getenv(constants.EnvKeyJwtType)
+// osJwtSecret := os.Getenv(constants.EnvKeyJwtSecret)
+// osJwtPrivateKey := os.Getenv(constants.EnvKeyJwtPrivateKey)
+// osJwtPublicKey := os.Getenv(constants.EnvKeyJwtPublicKey)
+// osJwtRoleClaim := os.Getenv(constants.EnvKeyJwtRoleClaim)
+// osCustomAccessTokenScript := os.Getenv(constants.EnvKeyCustomAccessTokenScript)
+// osGoogleClientID := os.Getenv(constants.EnvKeyGoogleClientID)
+// osGoogleClientSecret := os.Getenv(constants.EnvKeyGoogleClientSecret)
+// osGithubClientID := os.Getenv(constants.EnvKeyGithubClientID)
+// osGithubClientSecret := os.Getenv(constants.EnvKeyGithubClientSecret)
+// osFacebookClientID := os.Getenv(constants.EnvKeyFacebookClientID)
+// osFacebookClientSecret := os.Getenv(constants.EnvKeyFacebookClientSecret)
+// osLinkedInClientID := os.Getenv(constants.EnvKeyLinkedInClientID)
+// osLinkedInClientSecret := os.Getenv(constants.EnvKeyLinkedInClientSecret)
+// osAppleClientID := os.Getenv(constants.EnvKeyAppleClientID)
+// osAppleClientSecret := os.Getenv(constants.EnvKeyAppleClientSecret)
+// osTwitterClientID := os.Getenv(constants.EnvKeyTwitterClientID)
+// osTwitterClientSecret := os.Getenv(constants.EnvKeyTwitterClientSecret)
+// osMicrosoftClientID := os.Getenv(constants.EnvKeyMicrosoftClientID)
+// osMicrosoftClientSecret := os.Getenv(constants.EnvKeyMicrosoftClientSecret)
+// osMicrosoftActiveDirectoryTenantID := os.Getenv(constants.EnvKeyMicrosoftActiveDirectoryTenantID)
+// osTwitchClientID := os.Getenv(constants.EnvKeyTwitchClientID)
+// osTwitchClientSecret := os.Getenv(constants.EnvKeyTwitchClientSecret)
+// osRobloxClientID := os.Getenv(constants.EnvKeyTwitchClientID)
+// osRobloxClientSecret := os.Getenv(constants.EnvKeyTwitchClientSecret)
+// 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)
+// osCouchbaseBucket := os.Getenv(constants.EnvCouchbaseBucket)
+// osCouchbaseScope := os.Getenv(constants.EnvCouchbaseScope)
+// osCouchbaseBucketRAMQuotaMB := os.Getenv(constants.EnvCouchbaseBucketRAMQuotaMB)
+// osAuthorizeResponseType := os.Getenv(constants.EnvKeyDefaultAuthorizeResponseType)
+// osAuthorizeResponseMode := os.Getenv(constants.EnvKeyDefaultAuthorizeResponseMode)
+
+// // os bool vars
+// osAppCookieSecure := os.Getenv(constants.EnvKeyAppCookieSecure)
+// osAdminCookieSecure := os.Getenv(constants.EnvKeyAdminCookieSecure)
+// osDisableBasicAuthentication := os.Getenv(constants.EnvKeyDisableBasicAuthentication)
+// osDisableMobileBasicAuthentication := os.Getenv(constants.AuthRecipeMethodMobileBasicAuth)
+// osDisableEmailVerification := os.Getenv(constants.EnvKeyDisableEmailVerification)
+// osDisableMagicLinkLogin := os.Getenv(constants.EnvKeyDisableMagicLinkLogin)
+// osDisableLoginPage := os.Getenv(constants.EnvKeyDisableLoginPage)
+// osDisableSignUp := os.Getenv(constants.EnvKeyDisableSignUp)
+// osDisableRedisForEnv := os.Getenv(constants.EnvKeyDisableRedisForEnv)
+// osDisableStrongPassword := os.Getenv(constants.EnvKeyDisableStrongPassword)
+// osEnforceMultiFactorAuthentication := os.Getenv(constants.EnvKeyEnforceMultiFactorAuthentication)
+// osDisableMultiFactorAuthentication := os.Getenv(constants.EnvKeyDisableMultiFactorAuthentication)
+// osDisableTOTPLogin := os.Getenv(constants.EnvKeyDisableTOTPLogin)
+// osDisableMailOTPLogin := os.Getenv(constants.EnvKeyDisableMailOTPLogin)
+// // phone verification var
+// osDisablePhoneVerification := os.Getenv(constants.EnvKeyDisablePhoneVerification)
+// osDisablePlayground := os.Getenv(constants.EnvKeyDisablePlayGround)
+
+// // twilio vars
+// osTwilioApiKey := os.Getenv(constants.EnvKeyTwilioAPIKey)
+// osTwilioApiSecret := os.Getenv(constants.EnvKeyTwilioAPISecret)
+// osTwilioAccountSid := os.Getenv(constants.EnvKeyTwilioAccountSID)
+// osTwilioSender := os.Getenv(constants.EnvKeyTwilioSender)
+
+// // os slice vars
+// osAllowedOrigins := os.Getenv(constants.EnvKeyAllowedOrigins)
+// osRoles := os.Getenv(constants.EnvKeyRoles)
+// osDefaultRoles := os.Getenv(constants.EnvKeyDefaultRoles)
+// osProtectedRoles := os.Getenv(constants.EnvKeyProtectedRoles)
+
+// ienv, ok := envData[constants.EnvKeyEnv]
+// if !ok || ienv == "" {
+// envData[constants.EnvKeyEnv] = osEnv
+// if envData[constants.EnvKeyEnv] == "" {
+// envData[constants.EnvKeyEnv] = "production"
+// }
+
+// if envData[constants.EnvKeyEnv] == "production" {
+// envData[constants.EnvKeyIsProd] = true
+// } else {
+// envData[constants.EnvKeyIsProd] = false
+// }
+// }
+// if osEnv != "" && osEnv != envData[constants.EnvKeyEnv] {
+// envData[constants.EnvKeyEnv] = osEnv
+// if envData[constants.EnvKeyEnv] == "production" {
+// envData[constants.EnvKeyIsProd] = true
+// } else {
+// envData[constants.EnvKeyIsProd] = false
+// }
+// }
+
+// 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] != osAwsAccessKey {
+// envData[constants.EnvAwsAccessKeyID] = osAwsAccessKey
+// }
+
+// if val, ok := envData[constants.EnvAwsSecretAccessKey]; !ok || val == "" {
+// envData[constants.EnvAwsSecretAccessKey] = osAwsSecretKey
+// }
+// if osAwsSecretKey != "" && envData[constants.EnvAwsSecretAccessKey] != osAwsSecretKey {
+// envData[constants.EnvAwsSecretAccessKey] = osAwsSecretKey
+// }
+
+// if val, ok := envData[constants.EnvCouchbaseBucket]; !ok || val == "" {
+// envData[constants.EnvCouchbaseBucket] = osCouchbaseBucket
+// }
+// if osCouchbaseBucket != "" && envData[constants.EnvCouchbaseBucket] != osCouchbaseBucket {
+// envData[constants.EnvCouchbaseBucket] = osCouchbaseBucket
+// }
+
+// if val, ok := envData[constants.EnvCouchbaseBucketRAMQuotaMB]; !ok || val == "" {
+// envData[constants.EnvCouchbaseBucketRAMQuotaMB] = osCouchbaseBucketRAMQuotaMB
+// }
+// if osCouchbaseBucketRAMQuotaMB != "" && envData[constants.EnvCouchbaseBucketRAMQuotaMB] != osCouchbaseBucketRAMQuotaMB {
+// envData[constants.EnvCouchbaseBucketRAMQuotaMB] = osCouchbaseBucketRAMQuotaMB
+// }
+
+// if val, ok := envData[constants.EnvCouchbaseScope]; !ok || val == "" {
+// envData[constants.EnvCouchbaseScope] = osCouchbaseScope
+// }
+// if osCouchbaseScope != "" && envData[constants.EnvCouchbaseScope] != osCouchbaseScope {
+// envData[constants.EnvCouchbaseScope] = osCouchbaseScope
+// }
+
+// if val, ok := envData[constants.EnvKeyAppURL]; !ok || val == "" {
+// envData[constants.EnvKeyAppURL] = osAppURL
+// }
+// if osAppURL != "" && envData[constants.EnvKeyAppURL] != osAppURL {
+// envData[constants.EnvKeyAppURL] = osAppURL
+// }
+
+// if val, ok := envData[constants.EnvKeyAuthorizerURL]; !ok || val == "" {
+// envData[constants.EnvKeyAuthorizerURL] = osAuthorizerURL
+// }
+// if osAuthorizerURL != "" && envData[constants.EnvKeyAuthorizerURL] != osAuthorizerURL {
+// envData[constants.EnvKeyAuthorizerURL] = osAuthorizerURL
+// }
+
+// if val, ok := envData[constants.EnvKeyPort]; !ok || val == "" {
+// envData[constants.EnvKeyPort] = osPort
+// if envData[constants.EnvKeyPort] == "" {
+// envData[constants.EnvKeyPort] = "8080"
+// }
+// }
+// if osPort != "" && envData[constants.EnvKeyPort] != osPort {
+// envData[constants.EnvKeyPort] = osPort
+// }
+
+// if val, ok := envData[constants.EnvKeyAccessTokenExpiryTime]; !ok || val == "" {
+// envData[constants.EnvKeyAccessTokenExpiryTime] = osAccessTokenExpiryTime
+// if envData[constants.EnvKeyAccessTokenExpiryTime] == "" {
+// envData[constants.EnvKeyAccessTokenExpiryTime] = "30m"
+// }
+// }
+// if osAccessTokenExpiryTime != "" && envData[constants.EnvKeyAccessTokenExpiryTime] != osAccessTokenExpiryTime {
+// envData[constants.EnvKeyAccessTokenExpiryTime] = osAccessTokenExpiryTime
+// }
+
+// if val, ok := envData[constants.EnvKeyAdminSecret]; !ok || val == "" {
+// envData[constants.EnvKeyAdminSecret] = osAdminSecret
+// }
+// if osAdminSecret != "" && envData[constants.EnvKeyAdminSecret] != osAdminSecret {
+// envData[constants.EnvKeyAdminSecret] = osAdminSecret
+// }
+
+// if val, ok := envData[constants.EnvKeySmtpHost]; !ok || val == "" {
+// envData[constants.EnvKeySmtpHost] = osSmtpHost
+// }
+// if osSmtpHost != "" && envData[constants.EnvKeySmtpHost] != osSmtpHost {
+// envData[constants.EnvKeySmtpHost] = osSmtpHost
+// }
+
+// if val, ok := envData[constants.EnvKeySmtpPort]; !ok || val == "" {
+// envData[constants.EnvKeySmtpPort] = osSmtpPort
+// }
+// if osSmtpPort != "" && envData[constants.EnvKeySmtpPort] != osSmtpPort {
+// envData[constants.EnvKeySmtpPort] = osSmtpPort
+// }
+
+// if val, ok := envData[constants.EnvKeySmtpUsername]; !ok || val == "" {
+// envData[constants.EnvKeySmtpUsername] = osSmtpUsername
+// }
+// if osSmtpUsername != "" && envData[constants.EnvKeySmtpUsername] != osSmtpUsername {
+// 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
+// }
+// if osSmtpPassword != "" && envData[constants.EnvKeySmtpPassword] != osSmtpPassword {
+// envData[constants.EnvKeySmtpPassword] = osSmtpPassword
+// }
+
+// if val, ok := envData[constants.EnvKeySenderEmail]; !ok || val == "" {
+// envData[constants.EnvKeySenderEmail] = osSenderEmail
+// }
+// if osSenderEmail != "" && envData[constants.EnvKeySenderEmail] != osSenderEmail {
+// envData[constants.EnvKeySenderEmail] = osSenderEmail
+// }
+
+// if val, ok := envData[constants.EnvKeySenderName]; !ok || val == "" {
+// envData[constants.EnvKeySenderName] = osSenderName
+// }
+// if osSenderName != "" && envData[constants.EnvKeySenderName] != osSenderName {
+// envData[constants.EnvKeySenderName] = osSenderName
+// }
+
+// algoVal, ok := envData[constants.EnvKeyJwtType]
+// algo := ""
+// if !ok || algoVal == "" {
+// envData[constants.EnvKeyJwtType] = osJwtType
+// if envData[constants.EnvKeyJwtType] == "" {
+// envData[constants.EnvKeyJwtType] = "RS256"
+// algo = envData[constants.EnvKeyJwtType].(string)
+// }
+// } else {
+// algo = algoVal.(string)
+// if !crypto.IsHMACA(algo) && !crypto.IsRSA(algo) && !crypto.IsECDSA(algo) {
+// log.Debug("Invalid JWT Algorithm")
+// return errors.New("invalid JWT_TYPE")
+// }
+// }
+// if osJwtType != "" && osJwtType != algo {
+// if !crypto.IsHMACA(osJwtType) && !crypto.IsRSA(osJwtType) && !crypto.IsECDSA(osJwtType) {
+// log.Debug("Invalid JWT Algorithm")
+// return errors.New("invalid JWT_TYPE")
+// }
+// algo = osJwtType
+// envData[constants.EnvKeyJwtType] = osJwtType
+// }
+
+// if crypto.IsHMACA(algo) {
+// if val, ok := envData[constants.EnvKeyJwtSecret]; !ok || val == "" {
+// envData[constants.EnvKeyJwtSecret] = osJwtSecret
+// if envData[constants.EnvKeyJwtSecret] == "" {
+// envData[constants.EnvKeyJwtSecret], _, err = crypto.NewHMACKey(algo, clientID)
+// if err != nil {
+// return err
+// }
+// }
+// }
+// if osJwtSecret != "" && envData[constants.EnvKeyJwtSecret] != osJwtSecret {
+// envData[constants.EnvKeyJwtSecret] = osJwtSecret
+// }
+// }
+
+// if crypto.IsRSA(algo) || crypto.IsECDSA(algo) {
+// privateKey, publicKey := "", ""
+
+// if val, ok := envData[constants.EnvKeyJwtPrivateKey]; !ok || val == "" {
+// privateKey = osJwtPrivateKey
+// }
+// if osJwtPrivateKey != "" && privateKey != osJwtPrivateKey {
+// privateKey = osJwtPrivateKey
+// }
+
+// if val, ok := envData[constants.EnvKeyJwtPublicKey]; !ok || val == "" {
+// publicKey = osJwtPublicKey
+// }
+// if osJwtPublicKey != "" && publicKey != osJwtPublicKey {
+// publicKey = osJwtPublicKey
+// }
+
+// // if algo is RSA / ECDSA, then we need to have both private and public key
+// // if either of them is not present generate new keys
+// if privateKey == "" || publicKey == "" {
+// if crypto.IsRSA(algo) {
+// _, privateKey, publicKey, _, err = crypto.NewRSAKey(algo, clientID)
+// if err != nil {
+// return err
+// }
+// } else if crypto.IsECDSA(algo) {
+// _, privateKey, publicKey, _, err = crypto.NewECDSAKey(algo, clientID)
+// if err != nil {
+// return err
+// }
+// }
+// } else {
+// // parse keys to make sure they are valid
+// if crypto.IsRSA(algo) {
+// _, err = crypto.ParseRsaPrivateKeyFromPemStr(privateKey)
+// if err != nil {
+// return err
+// }
+
+// _, err := crypto.ParseRsaPublicKeyFromPemStr(publicKey)
+// if err != nil {
+// return err
+// }
+
+// } else if crypto.IsECDSA(algo) {
+// _, err = crypto.ParseEcdsaPrivateKeyFromPemStr(privateKey)
+// if err != nil {
+// return err
+// }
+
+// _, err := crypto.ParseEcdsaPublicKeyFromPemStr(publicKey)
+// if err != nil {
+// return err
+// }
+// }
+// }
+
+// envData[constants.EnvKeyJwtPrivateKey] = privateKey
+// envData[constants.EnvKeyJwtPublicKey] = publicKey
+
+// }
+
+// if val, ok := envData[constants.EnvKeyJwtRoleClaim]; !ok || val == "" {
+// envData[constants.EnvKeyJwtRoleClaim] = osJwtRoleClaim
+
+// if envData[constants.EnvKeyJwtRoleClaim] == "" {
+// envData[constants.EnvKeyJwtRoleClaim] = "roles"
+// }
+// }
+// if osJwtRoleClaim != "" && envData[constants.EnvKeyJwtRoleClaim] != osJwtRoleClaim {
+// envData[constants.EnvKeyJwtRoleClaim] = osJwtRoleClaim
+// }
+
+// if val, ok := envData[constants.EnvKeyCustomAccessTokenScript]; !ok || val == "" {
+// envData[constants.EnvKeyCustomAccessTokenScript] = osCustomAccessTokenScript
+// }
+// if osCustomAccessTokenScript != "" && envData[constants.EnvKeyCustomAccessTokenScript] != osCustomAccessTokenScript {
+// envData[constants.EnvKeyCustomAccessTokenScript] = osCustomAccessTokenScript
+// }
+
+// if val, ok := envData[constants.EnvKeyGoogleClientID]; !ok || val == "" {
+// envData[constants.EnvKeyGoogleClientID] = osGoogleClientID
+// }
+// if osGoogleClientID != "" && envData[constants.EnvKeyGoogleClientID] != osGoogleClientID {
+// envData[constants.EnvKeyGoogleClientID] = osGoogleClientID
+// }
+
+// if val, ok := envData[constants.EnvKeyGoogleClientSecret]; !ok || val == "" {
+// envData[constants.EnvKeyGoogleClientSecret] = osGoogleClientSecret
+// }
+// if osGoogleClientSecret != "" && envData[constants.EnvKeyGoogleClientSecret] != osGoogleClientSecret {
+// envData[constants.EnvKeyGoogleClientSecret] = osGoogleClientSecret
+// }
+
+// if val, ok := envData[constants.EnvKeyGithubClientID]; !ok || val == "" {
+// envData[constants.EnvKeyGithubClientID] = osGithubClientID
+// }
+// if osGithubClientID != "" && envData[constants.EnvKeyGithubClientID] != osGithubClientID {
+// envData[constants.EnvKeyGithubClientID] = osGithubClientID
+// }
+
+// if val, ok := envData[constants.EnvKeyGithubClientSecret]; !ok || val == "" {
+// envData[constants.EnvKeyGithubClientSecret] = osGithubClientSecret
+// }
+// if osGithubClientSecret != "" && envData[constants.EnvKeyGithubClientSecret] != osGithubClientSecret {
+// envData[constants.EnvKeyGithubClientSecret] = osGithubClientSecret
+// }
+
+// if val, ok := envData[constants.EnvKeyFacebookClientID]; !ok || val == "" {
+// envData[constants.EnvKeyFacebookClientID] = osFacebookClientID
+// }
+// if osFacebookClientID != "" && envData[constants.EnvKeyFacebookClientID] != osFacebookClientID {
+// envData[constants.EnvKeyFacebookClientID] = osFacebookClientID
+// }
+
+// if val, ok := envData[constants.EnvKeyFacebookClientSecret]; !ok || val == "" {
+// envData[constants.EnvKeyFacebookClientSecret] = osFacebookClientSecret
+// }
+// if osFacebookClientSecret != "" && envData[constants.EnvKeyFacebookClientSecret] != osFacebookClientSecret {
+// envData[constants.EnvKeyFacebookClientSecret] = osFacebookClientSecret
+// }
+
+// if val, ok := envData[constants.EnvKeyLinkedInClientID]; !ok || val == "" {
+// envData[constants.EnvKeyLinkedInClientID] = osLinkedInClientID
+// }
+// if osLinkedInClientID != "" && envData[constants.EnvKeyLinkedInClientID] != osLinkedInClientID {
+// envData[constants.EnvKeyLinkedInClientID] = osLinkedInClientID
+// }
+
+// if val, ok := envData[constants.EnvKeyLinkedInClientSecret]; !ok || val == "" {
+// envData[constants.EnvKeyLinkedInClientSecret] = osLinkedInClientSecret
+// }
+// if osLinkedInClientSecret != "" && envData[constants.EnvKeyLinkedInClientSecret] != osLinkedInClientSecret {
+// envData[constants.EnvKeyLinkedInClientSecret] = osLinkedInClientSecret
+// }
+
+// if val, ok := envData[constants.EnvKeyAppleClientID]; !ok || val == "" {
+// envData[constants.EnvKeyAppleClientID] = osAppleClientID
+// }
+// if osAppleClientID != "" && envData[constants.EnvKeyAppleClientID] != osAppleClientID {
+// envData[constants.EnvKeyAppleClientID] = osAppleClientID
+// }
+
+// if val, ok := envData[constants.EnvKeyAppleClientSecret]; !ok || val == "" {
+// envData[constants.EnvKeyAppleClientSecret] = osAppleClientSecret
+// }
+// if osAppleClientSecret != "" && envData[constants.EnvKeyAppleClientSecret] != osAppleClientSecret {
+// envData[constants.EnvKeyAppleClientSecret] = osAppleClientSecret
+// }
+
+// if val, ok := envData[constants.EnvKeyTwitterClientID]; !ok || val == "" {
+// envData[constants.EnvKeyTwitterClientID] = osTwitterClientID
+// }
+// if osTwitterClientID != "" && envData[constants.EnvKeyTwitterClientID] != osTwitterClientID {
+// envData[constants.EnvKeyTwitterClientID] = osTwitterClientID
+// }
+
+// if val, ok := envData[constants.EnvKeyTwitterClientSecret]; !ok || val == "" {
+// envData[constants.EnvKeyTwitterClientSecret] = osTwitterClientSecret
+// }
+// if osTwitterClientSecret != "" && envData[constants.EnvKeyTwitterClientSecret] != osTwitterClientSecret {
+// envData[constants.EnvKeyTwitterClientSecret] = osTwitterClientSecret
+// }
+
+// if val, ok := envData[constants.EnvKeyMicrosoftClientID]; !ok || val == "" {
+// envData[constants.EnvKeyMicrosoftClientID] = osMicrosoftClientID
+// }
+// if osMicrosoftClientID != "" && envData[constants.EnvKeyMicrosoftClientID] != osMicrosoftClientID {
+// envData[constants.EnvKeyMicrosoftClientID] = osMicrosoftClientID
+// }
+
+// if val, ok := envData[constants.EnvKeyMicrosoftClientSecret]; !ok || val == "" {
+// envData[constants.EnvKeyMicrosoftClientSecret] = osMicrosoftClientSecret
+// }
+// if osMicrosoftClientSecret != "" && envData[constants.EnvKeyMicrosoftClientSecret] != osMicrosoftClientSecret {
+// envData[constants.EnvKeyMicrosoftClientSecret] = osMicrosoftClientSecret
+// }
+
+// if val, ok := envData[constants.EnvKeyMicrosoftActiveDirectoryTenantID]; !ok || val == "" {
+// envData[constants.EnvKeyMicrosoftActiveDirectoryTenantID] = osMicrosoftActiveDirectoryTenantID
+// }
+// if osMicrosoftActiveDirectoryTenantID != "" && envData[constants.EnvKeyMicrosoftActiveDirectoryTenantID] != osMicrosoftActiveDirectoryTenantID {
+// envData[constants.EnvKeyMicrosoftActiveDirectoryTenantID] = osMicrosoftActiveDirectoryTenantID
+// }
+
+// if val, ok := envData[constants.EnvKeyTwitchClientID]; !ok || val == "" {
+// envData[constants.EnvKeyTwitchClientID] = osTwitchClientID
+// }
+// if osTwitchClientID != "" && envData[constants.EnvKeyTwitchClientID] != osTwitchClientID {
+// envData[constants.EnvKeyTwitchClientID] = osTwitchClientID
+// }
+
+// if val, ok := envData[constants.EnvKeyTwitchClientSecret]; !ok || val == "" {
+// envData[constants.EnvKeyTwitchClientSecret] = osTwitchClientSecret
+// }
+// if osTwitchClientSecret != "" && envData[constants.EnvKeyTwitchClientSecret] != osTwitchClientSecret {
+// envData[constants.EnvKeyTwitchClientSecret] = osTwitchClientSecret
+// }
+
+// if val, ok := envData[constants.EnvKeyRobloxClientID]; !ok || val == "" {
+// envData[constants.EnvKeyRobloxClientID] = osRobloxClientID
+// }
+// if osRobloxClientID != "" && envData[constants.EnvKeyRobloxClientID] != osRobloxClientID {
+// envData[constants.EnvKeyRobloxClientID] = osRobloxClientID
+// }
+
+// if val, ok := envData[constants.EnvKeyRobloxClientSecret]; !ok || val == "" {
+// envData[constants.EnvKeyRobloxClientSecret] = osRobloxClientSecret
+// }
+// if osRobloxClientSecret != "" && envData[constants.EnvKeyRobloxClientSecret] != osRobloxClientSecret {
+// envData[constants.EnvKeyRobloxClientSecret] = osRobloxClientSecret
+// }
+
+// if val, ok := envData[constants.EnvKeyResetPasswordURL]; !ok || val == "" {
+// envData[constants.EnvKeyResetPasswordURL] = strings.TrimPrefix(osResetPasswordURL, "/")
+// }
+// if osResetPasswordURL != "" && envData[constants.EnvKeyResetPasswordURL] != osResetPasswordURL {
+// envData[constants.EnvKeyResetPasswordURL] = osResetPasswordURL
+// }
+
+// if val, ok := envData[constants.EnvKeyOrganizationName]; !ok || val == "" {
+// envData[constants.EnvKeyOrganizationName] = osOrganizationName
+// }
+// if osOrganizationName != "" && envData[constants.EnvKeyOrganizationName] != osOrganizationName {
+// envData[constants.EnvKeyOrganizationName] = osOrganizationName
+// }
+
+// if val, ok := envData[constants.EnvKeyOrganizationLogo]; !ok || val == "" {
+// envData[constants.EnvKeyOrganizationLogo] = osOrganizationLogo
+// }
+// if osOrganizationLogo != "" && envData[constants.EnvKeyOrganizationLogo] != osOrganizationLogo {
+// envData[constants.EnvKeyOrganizationLogo] = osOrganizationLogo
+// }
+
+// if _, ok := envData[constants.EnvKeyAppCookieSecure]; !ok {
+// if osAppCookieSecure == "" {
+// envData[constants.EnvKeyAppCookieSecure] = true
+// } else {
+// envData[constants.EnvKeyAppCookieSecure] = osAppCookieSecure == "true"
+// }
+// }
+// if osAppCookieSecure != "" {
+// boolValue, err := strconv.ParseBool(osAppCookieSecure)
+// if err != nil {
+// return err
+// }
+// if boolValue != envData[constants.EnvKeyAppCookieSecure].(bool) {
+// envData[constants.EnvKeyAppCookieSecure] = boolValue
+// }
+// }
+
+// if _, ok := envData[constants.EnvKeyAdminCookieSecure]; !ok {
+// if osAdminCookieSecure == "" {
+// envData[constants.EnvKeyAdminCookieSecure] = true
+// } else {
+// envData[constants.EnvKeyAdminCookieSecure] = osAdminCookieSecure == "true"
+// }
+// }
+// if osAdminCookieSecure != "" {
+// boolValue, err := strconv.ParseBool(osAdminCookieSecure)
+// if err != nil {
+// return err
+// }
+// if boolValue != envData[constants.EnvKeyAdminCookieSecure].(bool) {
+// envData[constants.EnvKeyAdminCookieSecure] = boolValue
+// }
+// }
+
+// if _, ok := envData[constants.EnvKeyDisableBasicAuthentication]; !ok {
+// envData[constants.EnvKeyDisableBasicAuthentication] = osDisableBasicAuthentication == "true"
+// }
+// if osDisableBasicAuthentication != "" {
+// boolValue, err := strconv.ParseBool(osDisableBasicAuthentication)
+// if err != nil {
+// return err
+// }
+// if boolValue != envData[constants.EnvKeyDisableBasicAuthentication].(bool) {
+// envData[constants.EnvKeyDisableBasicAuthentication] = boolValue
+// }
+// }
+
+// if _, ok := envData[constants.EnvKeyDisableMobileBasicAuthentication]; !ok {
+// envData[constants.EnvKeyDisableMobileBasicAuthentication] = osDisableBasicAuthentication == "true"
+// }
+// if osDisableMobileBasicAuthentication != "" {
+// boolValue, err := strconv.ParseBool(osDisableMobileBasicAuthentication)
+// if err != nil {
+// return err
+// }
+// if boolValue != envData[constants.EnvKeyDisableMobileBasicAuthentication].(bool) {
+// envData[constants.EnvKeyDisableMobileBasicAuthentication] = boolValue
+// }
+// }
+
+// if _, ok := envData[constants.EnvKeyDisableEmailVerification]; !ok {
+// envData[constants.EnvKeyDisableEmailVerification] = osDisableEmailVerification == "true"
+// }
+// if osDisableEmailVerification != "" {
+// boolValue, err := strconv.ParseBool(osDisableEmailVerification)
+// if err != nil {
+// return err
+// }
+// if boolValue != envData[constants.EnvKeyDisableEmailVerification].(bool) {
+// envData[constants.EnvKeyDisableEmailVerification] = boolValue
+// }
+// }
+
+// if _, ok := envData[constants.EnvKeyDisableMagicLinkLogin]; !ok {
+// envData[constants.EnvKeyDisableMagicLinkLogin] = osDisableMagicLinkLogin == "true"
+// }
+// if osDisableMagicLinkLogin != "" {
+// boolValue, err := strconv.ParseBool(osDisableMagicLinkLogin)
+// if err != nil {
+// return err
+// }
+// if boolValue != envData[constants.EnvKeyDisableMagicLinkLogin] {
+// envData[constants.EnvKeyDisableMagicLinkLogin] = boolValue
+// }
+// }
+
+// if _, ok := envData[constants.EnvKeyDisableLoginPage]; !ok {
+// envData[constants.EnvKeyDisableLoginPage] = osDisableLoginPage == "true"
+// }
+// if osDisableLoginPage != "" {
+// boolValue, err := strconv.ParseBool(osDisableLoginPage)
+// if err != nil {
+// return err
+// }
+// if boolValue != envData[constants.EnvKeyDisableLoginPage].(bool) {
+// envData[constants.EnvKeyDisableLoginPage] = boolValue
+// }
+// }
+
+// if _, ok := envData[constants.EnvKeyDisableSignUp]; !ok {
+// envData[constants.EnvKeyDisableSignUp] = osDisableSignUp == "true"
+// }
+// if osDisableSignUp != "" {
+// boolValue, err := strconv.ParseBool(osDisableSignUp)
+// if err != nil {
+// return err
+// }
+// if boolValue != envData[constants.EnvKeyDisableSignUp].(bool) {
+// envData[constants.EnvKeyDisableSignUp] = boolValue
+// }
+// }
+
+// if _, ok := envData[constants.EnvKeyDisableRedisForEnv]; !ok {
+// envData[constants.EnvKeyDisableRedisForEnv] = osDisableRedisForEnv == "true"
+// }
+// if osDisableRedisForEnv != "" {
+// boolValue, err := strconv.ParseBool(osDisableRedisForEnv)
+// if err != nil {
+// return err
+// }
+// if boolValue != envData[constants.EnvKeyDisableRedisForEnv].(bool) {
+// envData[constants.EnvKeyDisableRedisForEnv] = boolValue
+// }
+// }
+
+// if _, ok := envData[constants.EnvKeyDisableStrongPassword]; !ok {
+// envData[constants.EnvKeyDisableStrongPassword] = osDisableStrongPassword == "true"
+// }
+// if osDisableStrongPassword != "" {
+// boolValue, err := strconv.ParseBool(osDisableStrongPassword)
+// if err != nil {
+// return err
+// }
+// if boolValue != envData[constants.EnvKeyDisableStrongPassword].(bool) {
+// envData[constants.EnvKeyDisableStrongPassword] = boolValue
+// }
+// }
+
+// if _, ok := envData[constants.EnvKeyEnforceMultiFactorAuthentication]; !ok {
+// envData[constants.EnvKeyEnforceMultiFactorAuthentication] = osEnforceMultiFactorAuthentication == "true"
+// }
+// if osEnforceMultiFactorAuthentication != "" {
+// boolValue, err := strconv.ParseBool(osEnforceMultiFactorAuthentication)
+// if err != nil {
+// return err
+// }
+// if boolValue != envData[constants.EnvKeyEnforceMultiFactorAuthentication].(bool) {
+// envData[constants.EnvKeyEnforceMultiFactorAuthentication] = boolValue
+// }
+// }
+
+// if _, ok := envData[constants.EnvKeyDisableMultiFactorAuthentication]; !ok {
+// envData[constants.EnvKeyDisableMultiFactorAuthentication] = osDisableMultiFactorAuthentication == "true"
+// }
+// if osDisableMultiFactorAuthentication != "" {
+// boolValue, err := strconv.ParseBool(osDisableMultiFactorAuthentication)
+// if err != nil {
+// return err
+// }
+// if boolValue != envData[constants.EnvKeyDisableMultiFactorAuthentication].(bool) {
+// envData[constants.EnvKeyDisableMultiFactorAuthentication] = boolValue
+// }
+// }
+
+// // no need to add nil check as its already done above
+// if envData[constants.EnvKeySmtpHost] == "" || envData[constants.EnvKeySmtpUsername] == "" || envData[constants.EnvKeySmtpPassword] == "" || envData[constants.EnvKeySenderEmail] == "" && envData[constants.EnvKeySmtpPort] == "" {
+// envData[constants.EnvKeyDisableEmailVerification] = true
+// envData[constants.EnvKeyDisableMagicLinkLogin] = true
+// envData[constants.EnvKeyIsEmailServiceEnabled] = false
+// envData[constants.EnvKeyDisableMailOTPLogin] = true
+// }
+
+// if envData[constants.EnvKeySmtpHost] != "" && envData[constants.EnvKeySmtpUsername] != "" && envData[constants.EnvKeySmtpPassword] != "" && envData[constants.EnvKeySenderEmail] != "" && envData[constants.EnvKeySmtpPort] != "" {
+// envData[constants.EnvKeyIsEmailServiceEnabled] = true
+// }
+
+// if envData[constants.EnvKeyDisableEmailVerification].(bool) {
+// envData[constants.EnvKeyDisableMagicLinkLogin] = true
+// }
+
+// if val, ok := envData[constants.EnvKeyAllowedOrigins]; !ok || val == "" {
+// envData[constants.EnvKeyAllowedOrigins] = osAllowedOrigins
+// if envData[constants.EnvKeyAllowedOrigins] == "" {
+// envData[constants.EnvKeyAllowedOrigins] = "*"
+// }
+// }
+// if osAllowedOrigins != "" && envData[constants.EnvKeyAllowedOrigins] != osAllowedOrigins {
+// envData[constants.EnvKeyAllowedOrigins] = osAllowedOrigins
+// }
+
+// if val, ok := envData[constants.EnvKeyRoles]; !ok || val == "" {
+// envData[constants.EnvKeyRoles] = osRoles
+// if envData[constants.EnvKeyRoles] == "" {
+// envData[constants.EnvKeyRoles] = "user"
+// }
+// }
+// if osRoles != "" && envData[constants.EnvKeyRoles] != osRoles {
+// envData[constants.EnvKeyRoles] = osRoles
+// }
+// roles := strings.Split(envData[constants.EnvKeyRoles].(string), ",")
+
+// if val, ok := envData[constants.EnvKeyDefaultRoles]; !ok || val == "" {
+// envData[constants.EnvKeyDefaultRoles] = osDefaultRoles
+// if envData[constants.EnvKeyDefaultRoles] == "" {
+// envData[constants.EnvKeyDefaultRoles] = "user"
+// }
+// }
+// if osDefaultRoles != "" && envData[constants.EnvKeyDefaultRoles] != osDefaultRoles {
+// envData[constants.EnvKeyDefaultRoles] = osDefaultRoles
+// }
+// defaultRoles := strings.Split(envData[constants.EnvKeyDefaultRoles].(string), ",")
+// if len(defaultRoles) == 0 {
+// defaultRoles = []string{roles[0]}
+// }
+
+// for _, role := range defaultRoles {
+// if !utils.StringSliceContains(roles, role) {
+// return fmt.Errorf("Default role %s is not defined in roles", role)
+// }
+// }
+
+// if val, ok := envData[constants.EnvKeyProtectedRoles]; !ok || val == "" {
+// envData[constants.EnvKeyProtectedRoles] = osProtectedRoles
+// }
+// if osProtectedRoles != "" && envData[constants.EnvKeyProtectedRoles] != osProtectedRoles {
+// envData[constants.EnvKeyProtectedRoles] = osProtectedRoles
+// }
+
+// if val, ok := envData[constants.EnvKeyDefaultAuthorizeResponseType]; !ok || val == "" {
+// envData[constants.EnvKeyDefaultAuthorizeResponseType] = osAuthorizeResponseType
+// // Set the default value to token type
+// if envData[constants.EnvKeyDefaultAuthorizeResponseType] == "" {
+// envData[constants.EnvKeyDefaultAuthorizeResponseType] = constants.ResponseTypeToken
+// }
+// }
+// if osAuthorizeResponseType != "" && envData[constants.EnvKeyDefaultAuthorizeResponseType] != osAuthorizeResponseType {
+// envData[constants.EnvKeyDefaultAuthorizeResponseType] = osAuthorizeResponseType
+// }
+
+// if val, ok := envData[constants.EnvKeyDefaultAuthorizeResponseMode]; !ok || val == "" {
+// envData[constants.EnvKeyDefaultAuthorizeResponseMode] = osAuthorizeResponseMode
+// // Set the default value to token type
+// if envData[constants.EnvKeyDefaultAuthorizeResponseMode] == "" {
+// envData[constants.EnvKeyDefaultAuthorizeResponseMode] = constants.ResponseModeQuery
+// }
+// }
+// if osAuthorizeResponseMode != "" && envData[constants.EnvKeyDefaultAuthorizeResponseMode] != osAuthorizeResponseMode {
+// envData[constants.EnvKeyDefaultAuthorizeResponseMode] = osAuthorizeResponseMode
+// }
+
+// if val, ok := envData[constants.EnvKeyTwilioAPISecret]; !ok || val == "" {
+// envData[constants.EnvKeyTwilioAPISecret] = osTwilioApiSecret
+// }
+// if osTwilioApiSecret != "" && envData[constants.EnvKeyTwilioAPISecret] != osTwilioApiSecret {
+// envData[constants.EnvKeyTwilioAPISecret] = osTwilioApiSecret
+// }
+
+// if val, ok := envData[constants.EnvKeyTwilioAPIKey]; !ok || val == "" {
+// envData[constants.EnvKeyTwilioAPIKey] = osTwilioApiKey
+// }
+// if osTwilioApiKey != "" && envData[constants.EnvKeyTwilioAPIKey] != osTwilioApiKey {
+// envData[constants.EnvKeyTwilioAPIKey] = osTwilioApiKey
+// }
+
+// if val, ok := envData[constants.EnvKeyTwilioAccountSID]; !ok || val == "" {
+// envData[constants.EnvKeyTwilioAccountSID] = osTwilioAccountSid
+// }
+// if osTwilioAccountSid != "" && envData[constants.EnvKeyTwilioAccountSID] != osTwilioAccountSid {
+// envData[constants.EnvKeyTwilioAccountSID] = osTwilioAccountSid
+// }
+
+// if val, ok := envData[constants.EnvKeyTwilioSender]; !ok || val == "" {
+// envData[constants.EnvKeyTwilioSender] = osTwilioSender
+// }
+// if osTwilioSender != "" && envData[constants.EnvKeyTwilioSender] != osTwilioSender {
+// envData[constants.EnvKeyTwilioSender] = osTwilioSender
+// }
+
+// if _, ok := envData[constants.EnvKeyDisablePhoneVerification]; !ok {
+// envData[constants.EnvKeyDisablePhoneVerification] = osDisablePhoneVerification == "false"
+// }
+// if osDisablePhoneVerification != "" {
+// boolValue, err := strconv.ParseBool(osDisablePhoneVerification)
+// if err != nil {
+// return err
+// }
+// if boolValue != envData[constants.EnvKeyDisablePhoneVerification] {
+// envData[constants.EnvKeyDisablePhoneVerification] = boolValue
+// }
+// }
+
+// if envData[constants.EnvKeyTwilioAPIKey] == "" || envData[constants.EnvKeyTwilioAPISecret] == "" || envData[constants.EnvKeyTwilioAccountSID] == "" || envData[constants.EnvKeyTwilioSender] == "" {
+// envData[constants.EnvKeyDisablePhoneVerification] = true
+// envData[constants.EnvKeyIsSMSServiceEnabled] = false
+// }
+// if envData[constants.EnvKeyTwilioAPIKey] != "" && envData[constants.EnvKeyTwilioAPISecret] != "" && envData[constants.EnvKeyTwilioAccountSID] != "" && envData[constants.EnvKeyTwilioSender] != "" {
+// envData[constants.EnvKeyDisablePhoneVerification] = false
+// envData[constants.EnvKeyIsSMSServiceEnabled] = true
+// }
+
+// if _, ok := envData[constants.EnvKeyDisablePlayGround]; !ok {
+// envData[constants.EnvKeyDisablePlayGround] = osDisablePlayground == "true"
+// }
+// if osDisablePlayground != "" {
+// boolValue, err := strconv.ParseBool(osDisablePlayground)
+// if err != nil {
+// return err
+// }
+// if boolValue != envData[constants.EnvKeyDisablePlayGround].(bool) {
+// envData[constants.EnvKeyDisablePlayGround] = boolValue
+// }
+// }
+// // TODO: remove after beta launch
+// envData[constants.EnvKeyDisableTOTPLogin] = true
+// if _, ok := envData[constants.EnvKeyDisableTOTPLogin]; !ok {
+// envData[constants.EnvKeyDisableTOTPLogin] = osDisableTOTPLogin == "true"
+// }
+// if osDisableTOTPLogin != "" {
+// boolValue, err := strconv.ParseBool(osDisableTOTPLogin)
+// if err != nil {
+// return err
+// }
+// if boolValue != envData[constants.EnvKeyDisableTOTPLogin].(bool) {
+// envData[constants.EnvKeyDisableTOTPLogin] = boolValue
+// }
+// }
+
+// if _, ok := envData[constants.EnvKeyDisableMailOTPLogin]; !ok {
+// envData[constants.EnvKeyDisableMailOTPLogin] = osDisableMailOTPLogin == "true"
+// }
+// if osDisableMailOTPLogin != "" {
+// boolValue, err := strconv.ParseBool(osDisableMailOTPLogin)
+// if err != nil {
+// return err
+// }
+// if boolValue != envData[constants.EnvKeyDisableMailOTPLogin].(bool) {
+// envData[constants.EnvKeyDisableMailOTPLogin] = boolValue
+// }
+// }
+
+// err = memorystore.Provider.UpdateEnvStore(envData)
+// if err != nil {
+// log.Debug("Error while updating env store: ", err)
+// return err
+// }
+// return nil
+// }
diff --git a/internal/env/persist_env.go b/internal/env/persist_env.go
new file mode 100644
index 000000000..ed827ca0a
--- /dev/null
+++ b/internal/env/persist_env.go
@@ -0,0 +1,249 @@
+package env
+
+// func fixBackwardCompatibility(data map[string]interface{}) (bool, map[string]interface{}) {
+// result := data
+// // check if env data is stored in older format
+// hasOlderFormat := false
+// if _, ok := result["bool_env"]; ok {
+// for key, value := range result["bool_env"].(map[string]interface{}) {
+// result[key] = value
+// }
+// hasOlderFormat = true
+// delete(result, "bool_env")
+// }
+
+// if _, ok := result["string_env"]; ok {
+// for key, value := range result["string_env"].(map[string]interface{}) {
+// result[key] = value
+// }
+// hasOlderFormat = true
+// delete(result, "string_env")
+// }
+
+// if _, ok := result["slice_env"]; ok {
+// for key, value := range result["slice_env"].(map[string]interface{}) {
+// typeOfValue := reflect.TypeOf(value)
+// if strings.Contains(typeOfValue.String(), "[]string") {
+// result[key] = strings.Join(value.([]string), ",")
+// }
+// if strings.Contains(typeOfValue.String(), "[]interface") {
+// result[key] = strings.Join(utils.ConvertInterfaceToStringSlice(value), ",")
+// }
+// }
+// hasOlderFormat = true
+// delete(result, "slice_env")
+// }
+
+// return hasOlderFormat, result
+// }
+
+// // GetEnvData returns the env data from database
+// func GetEnvData() (map[string]interface{}, error) {
+// var result map[string]interface{}
+// ctx := context.Background()
+// env, err := db.Provider.GetEnv(ctx)
+// // config not found in db
+// if err != nil || env == nil {
+// log.Debug("Error while getting env data from db: ", err)
+// return result, err
+// }
+
+// encryptionKey := env.Hash
+// decryptedEncryptionKey, err := crypto.DecryptB64(encryptionKey)
+// if err != nil {
+// log.Debug("Error while decrypting encryption key: ", err)
+// return result, err
+// }
+
+// memorystore.Provider.UpdateEnvVariable(constants.EnvKeyEncryptionKey, decryptedEncryptionKey)
+// b64DecryptedConfig, err := crypto.DecryptB64(env.EnvData)
+// if err != nil {
+// log.Debug("Error while decrypting env data from B64: ", err)
+// return result, err
+// }
+
+// decryptedConfigs, err := crypto.DecryptAESEnv([]byte(b64DecryptedConfig))
+// if err != nil {
+// log.Debug("Error while decrypting env data from AES: ", err)
+// return result, err
+// }
+
+// err = json.Unmarshal(decryptedConfigs, &result)
+// if err != nil {
+// log.Debug("Error while unmarshalling env data: ", err)
+// return result, err
+// }
+
+// hasOlderFormat, result := fixBackwardCompatibility(result)
+
+// if hasOlderFormat {
+// err = memorystore.Provider.UpdateEnvStore(result)
+// if err != nil {
+// log.Debug("Error while updating env store: ", err)
+// return result, err
+// }
+
+// }
+
+// return result, err
+// }
+
+// // PersistEnv persists the environment variables to the database
+// func PersistEnv() error {
+// ctx := context.Background()
+// env, err := db.Provider.GetEnv(ctx)
+// // config not found in db
+// if err != nil || env == nil {
+// // AES encryption needs 32 bit key only, so we chop off last 4 characters from 36 bit uuid
+// hash := uuid.New().String()[:36-4]
+// err := memorystore.Provider.UpdateEnvVariable(constants.EnvKeyEncryptionKey, hash)
+// if err != nil {
+// log.Debug("Error while updating encryption env variable: ", err)
+// return err
+// }
+// encodedHash := crypto.EncryptB64(hash)
+// res, err := memorystore.Provider.GetEnvStore()
+// if err != nil {
+// log.Debug("Error while getting env store: ", err)
+// return err
+// }
+// encryptedConfig, err := crypto.EncryptEnvData(res)
+// if err != nil {
+// log.Debug("Error while encrypting env data: ", err)
+// return err
+// }
+// env = &models.Env{
+// Hash: encodedHash,
+// EnvData: encryptedConfig,
+// }
+// _, err = db.Provider.AddEnv(ctx, env)
+// if err != nil {
+// log.Debug("Error while persisting env data to db: ", err)
+// return err
+// }
+// } else {
+// // decrypt the config data from db
+// // decryption can be done using the hash stored in db
+// encryptionKey := env.Hash
+// decryptedEncryptionKey, err := crypto.DecryptB64(encryptionKey)
+// if err != nil {
+// log.Debug("Error while decrypting encryption key: ", err)
+// return err
+// }
+
+// memorystore.Provider.UpdateEnvVariable(constants.EnvKeyEncryptionKey, decryptedEncryptionKey)
+
+// b64DecryptedConfig, err := crypto.DecryptB64(env.EnvData)
+// if err != nil {
+// log.Debug("Error while decrypting env data from B64: ", err)
+// return err
+// }
+
+// decryptedConfigs, err := crypto.DecryptAESEnv([]byte(b64DecryptedConfig))
+// if err != nil {
+// log.Debug("Error while decrypting env data from AES: ", err)
+// return err
+// }
+
+// // temp store variable
+// storeData := map[string]interface{}{}
+
+// err = json.Unmarshal(decryptedConfigs, &storeData)
+// if err != nil {
+// log.Debug("Error while un-marshalling env data: ", err)
+// return err
+// }
+
+// hasOlderFormat, result := fixBackwardCompatibility(storeData)
+// if hasOlderFormat {
+// err = memorystore.Provider.UpdateEnvStore(result)
+// if err != nil {
+// log.Debug("Error while updating env store: ", err)
+// return err
+// }
+
+// }
+
+// // if env is changed via env file or OS env
+// // give that higher preference and update db, but we don't recommend it
+
+// hasChanged := false
+// for key, value := range storeData {
+// // don't override unexposed envs
+// // check only for derivative keys
+// // No need to check for ENCRYPTION_KEY which special key we use for encrypting config data
+// // as we have removed it from json
+// if key != constants.EnvKeyEncryptionKey {
+// envValue := strings.TrimSpace(os.Getenv(key))
+// if envValue != "" {
+// switch key {
+// case constants.EnvKeyIsProd, constants.EnvKeyDisableBasicAuthentication, constants.EnvKeyDisableMobileBasicAuthentication, constants.EnvKeyDisableEmailVerification, constants.EnvKeyDisableLoginPage, constants.EnvKeyDisableMagicLinkLogin, constants.EnvKeyDisableSignUp, constants.EnvKeyDisableRedisForEnv, constants.EnvKeyDisableStrongPassword, constants.EnvKeyIsEmailServiceEnabled, constants.EnvKeyIsSMSServiceEnabled, constants.EnvKeyEnforceMultiFactorAuthentication, constants.EnvKeyDisableMultiFactorAuthentication, constants.EnvKeyAdminCookieSecure, constants.EnvKeyAppCookieSecure, constants.EnvKeyDisablePhoneVerification, constants.EnvKeyDisablePlayGround, constants.EnvKeyDisableTOTPLogin, constants.EnvKeyDisableMailOTPLogin:
+// if envValueBool, err := strconv.ParseBool(envValue); err == nil {
+// if value.(bool) != envValueBool {
+// storeData[key] = envValueBool
+// hasChanged = true
+// }
+// }
+// default:
+// if value != nil && value.(string) != envValue {
+// storeData[key] = envValue
+// hasChanged = true
+// }
+// }
+// }
+// }
+// }
+
+// // handle derivative cases like disabling email verification & magic login
+// // in case SMTP is off but env is set to true
+// if storeData[constants.EnvKeySmtpHost] == "" || storeData[constants.EnvKeySmtpUsername] == "" || storeData[constants.EnvKeySmtpPassword] == "" || storeData[constants.EnvKeySenderEmail] == "" && storeData[constants.EnvKeySmtpPort] == "" {
+// storeData[constants.EnvKeyIsEmailServiceEnabled] = false
+
+// if val, ok := storeData[constants.EnvKeyDisableEmailVerification]; ok && val != nil && !val.(bool) {
+// storeData[constants.EnvKeyDisableEmailVerification] = true
+// hasChanged = true
+// }
+
+// if val, ok := storeData[constants.EnvKeyDisableMagicLinkLogin]; ok && val != nil && !val.(bool) {
+// storeData[constants.EnvKeyDisableMagicLinkLogin] = true
+// hasChanged = true
+// }
+
+// if val, ok := storeData[constants.EnvKeyDisableMailOTPLogin]; ok && val != nil && !val.(bool) {
+// storeData[constants.EnvKeyDisableMailOTPLogin] = true
+// hasChanged = true
+// }
+// }
+
+// err = memorystore.Provider.UpdateEnvStore(storeData)
+// if err != nil {
+// log.Debug("Error while updating env store: ", err)
+// return err
+// }
+
+// jwk, err := crypto.GenerateJWKBasedOnEnv()
+// if err != nil {
+// log.Debug("Error while generating JWK: ", err)
+// return err
+// }
+// // updating jwk
+// memorystore.Provider.UpdateEnvVariable(constants.EnvKeyJWK, jwk)
+
+// if hasChanged {
+// encryptedConfig, err := crypto.EncryptEnvData(storeData)
+// if err != nil {
+// log.Debug("Error while encrypting env data: ", err)
+// return err
+// }
+
+// env.EnvData = encryptedConfig
+// _, err = db.Provider.UpdateEnv(ctx, env)
+// if err != nil {
+// log.Debug("Failed to Update Config: ", err)
+// return err
+// }
+// }
+// }
+
+// return nil
+// }
diff --git a/internal/events/events.go b/internal/events/events.go
new file mode 100644
index 000000000..5ab1d93b5
--- /dev/null
+++ b/internal/events/events.go
@@ -0,0 +1,142 @@
+package events
+
+import (
+ "bytes"
+ "context"
+ "encoding/json"
+ "io"
+ "net/http"
+ "time"
+
+ "github.com/rs/zerolog"
+
+ "github.com/authorizerdev/authorizer/internal/config"
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/storage"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
+)
+
+// Dependencies for events
+type Dependencies struct {
+ Log *zerolog.Logger
+ StorageProvider storage.Provider
+}
+
+// Provider interface for registering events
+type Provider interface {
+ // RegisterEvent to register event and add webhook logs
+ RegisterEvent(ctx context.Context, eventName string, authRecipe string, user *schemas.User) error
+}
+
+type provider struct {
+ config *config.Config
+ deps *Dependencies
+}
+
+// New returns a new events provider
+func New(config *config.Config, deps *Dependencies) (Provider, error) {
+ return &provider{
+ config: config,
+ deps: deps,
+ }, nil
+}
+
+// RegisterEvent util to register event
+func (p *provider) RegisterEvent(ctx context.Context, eventName string, authRecipe string, user *schemas.User) error {
+ log := p.deps.Log.With().Str("func", "RegisterEvent").Str("event", eventName).Logger()
+ webhooks, err := p.deps.StorageProvider.GetWebhookByEventName(ctx, eventName)
+ if err != nil {
+ log.Debug().Err(err).Msg("error getting webhook")
+ return err
+ }
+ for _, webhook := range webhooks {
+ if !webhook.Enabled {
+ continue
+ }
+ userBytes, err := json.Marshal(user.AsAPIUser())
+ if err != nil {
+ log.Debug().Err(err).Msg("error marshalling user obj")
+ continue
+ }
+ userMap := map[string]interface{}{}
+ err = json.Unmarshal(userBytes, &userMap)
+ if err != nil {
+ log.Debug().Err(err).Msg("error un-marshalling user obj")
+ continue
+ }
+
+ reqBody := map[string]interface{}{
+ "webhook_id": webhook.ID,
+ "event_name": eventName,
+ "event_description": webhook.EventDescription,
+ "user": userMap,
+ }
+
+ if eventName == constants.UserLoginWebhookEvent || eventName == constants.UserSignUpWebhookEvent {
+ reqBody["auth_recipe"] = authRecipe
+ }
+
+ requestBody, err := json.Marshal(reqBody)
+ if err != nil {
+ log.Debug().Err(err).Msg("error marshalling requestBody obj")
+ continue
+ }
+
+ // don't trigger webhook call in case of test
+ if p.config.Env == constants.TestEnv {
+ _, err := p.deps.StorageProvider.AddWebhookLog(ctx, &schemas.WebhookLog{
+ HttpStatus: 200,
+ Request: string(requestBody),
+ Response: string(`{"message": "test"}`),
+ WebhookID: webhook.ID,
+ })
+ if err != nil {
+ log.Debug().Err(err).Msg("error saving webhook log")
+ }
+ continue
+ }
+
+ requestBytesBuffer := bytes.NewBuffer(requestBody)
+ req, err := http.NewRequest("POST", webhook.EndPoint, requestBytesBuffer)
+ if err != nil {
+ log.Debug().Err(err).Msg("error creating request")
+ continue
+ }
+ req.Header.Set("Content-Type", "application/json")
+ headersMap := make(map[string]interface{})
+ err = json.Unmarshal([]byte(webhook.Headers), &headersMap)
+ if err != nil {
+ log.Debug().Err(err).Msg("error un-marshalling headers")
+ }
+ for key, val := range headersMap {
+ req.Header.Set(key, val.(string))
+ }
+
+ client := &http.Client{Timeout: time.Second * 30}
+ resp, err := client.Do(req)
+ if err != nil {
+ log.Debug().Err(err).Msg("error making request")
+ continue
+ }
+ defer resp.Body.Close()
+
+ responseBytes, err := io.ReadAll(resp.Body)
+ if err != nil {
+ log.Debug().Err(err).Msg("error reading response")
+ continue
+ }
+
+ statusCode := int64(resp.StatusCode)
+ _, err = p.deps.StorageProvider.AddWebhookLog(ctx, &schemas.WebhookLog{
+ HttpStatus: statusCode,
+ Request: string(requestBody),
+ Response: string(responseBytes),
+ WebhookID: webhook.ID,
+ })
+ if err != nil {
+ log.Debug().Err(err).Msg("error saving webhook log")
+ continue
+ }
+ }
+ return nil
+}
diff --git a/server/graph/generated/generated.go b/internal/graph/generated/generated.go
similarity index 86%
rename from server/graph/generated/generated.go
rename to internal/graph/generated/generated.go
index fe4c09eed..2f8ea7905 100644
--- a/server/graph/generated/generated.go
+++ b/internal/graph/generated/generated.go
@@ -13,7 +13,7 @@ import (
"github.com/99designs/gqlgen/graphql"
"github.com/99designs/gqlgen/graphql/introspection"
- "github.com/authorizerdev/authorizer/server/graph/model"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
gqlparser "github.com/vektah/gqlparser/v2"
"github.com/vektah/gqlparser/v2/ast"
)
@@ -197,35 +197,35 @@ type ComplexityRoot struct {
Mutation struct {
AddEmailTemplate func(childComplexity int, params model.AddEmailTemplateRequest) int
AddWebhook func(childComplexity int, params model.AddWebhookRequest) int
- AdminLogin func(childComplexity int, params model.AdminLoginInput) int
+ AdminLogin func(childComplexity int, params model.AdminLoginRequest) int
AdminLogout func(childComplexity int) int
- AdminSignup func(childComplexity int, params model.AdminSignupInput) int
+ AdminSignup func(childComplexity int, params model.AdminSignupRequest) int
DeactivateAccount func(childComplexity int) int
DeleteEmailTemplate func(childComplexity int, params model.DeleteEmailTemplateRequest) int
- DeleteUser func(childComplexity int, params model.DeleteUserInput) int
+ DeleteUser func(childComplexity int, params model.DeleteUserRequest) int
DeleteWebhook func(childComplexity int, params model.WebhookRequest) int
- EnableAccess func(childComplexity int, param model.UpdateAccessInput) int
- ForgotPassword func(childComplexity int, params model.ForgotPasswordInput) int
- GenerateJwtKeys func(childComplexity int, params model.GenerateJWTKeysInput) int
- InviteMembers func(childComplexity int, params model.InviteMemberInput) int
- Login func(childComplexity int, params model.LoginInput) int
+ EnableAccess func(childComplexity int, param model.UpdateAccessRequest) int
+ ForgotPassword func(childComplexity int, params model.ForgotPasswordRequest) int
+ GenerateJwtKeys func(childComplexity int, params model.GenerateJWTKeysRequest) int
+ InviteMembers func(childComplexity int, params model.InviteMemberRequest) int
+ Login func(childComplexity int, params model.LoginRequest) int
Logout func(childComplexity int) int
- MagicLinkLogin func(childComplexity int, params model.MagicLinkLoginInput) int
- MobileLogin func(childComplexity int, params model.MobileLoginInput) int
- MobileSignup func(childComplexity int, params *model.MobileSignUpInput) int
+ MagicLinkLogin func(childComplexity int, params model.MagicLinkLoginRequest) int
+ MobileLogin func(childComplexity int, params model.MobileLoginRequest) int
+ MobileSignup func(childComplexity int, params *model.MobileSignUpRequest) int
ResendOtp func(childComplexity int, params model.ResendOTPRequest) int
- ResendVerifyEmail func(childComplexity int, params model.ResendVerifyEmailInput) int
- ResetPassword func(childComplexity int, params model.ResetPasswordInput) int
- Revoke func(childComplexity int, params model.OAuthRevokeInput) int
- RevokeAccess func(childComplexity int, param model.UpdateAccessInput) int
- Signup func(childComplexity int, params model.SignUpInput) int
+ ResendVerifyEmail func(childComplexity int, params model.ResendVerifyEmailRequest) int
+ ResetPassword func(childComplexity int, params model.ResetPasswordRequest) int
+ Revoke func(childComplexity int, params model.OAuthRevokeRequest) int
+ RevokeAccess func(childComplexity int, param model.UpdateAccessRequest) int
+ Signup func(childComplexity int, params model.SignUpRequest) int
TestEndpoint func(childComplexity int, params model.TestEndpointRequest) int
UpdateEmailTemplate func(childComplexity int, params model.UpdateEmailTemplateRequest) int
- UpdateEnv func(childComplexity int, params model.UpdateEnvInput) int
- UpdateProfile func(childComplexity int, params model.UpdateProfileInput) int
- UpdateUser func(childComplexity int, params model.UpdateUserInput) int
+ UpdateEnv func(childComplexity int, params model.UpdateEnvRequest) int
+ UpdateProfile func(childComplexity int, params model.UpdateProfileRequest) int
+ UpdateUser func(childComplexity int, params model.UpdateUserRequest) int
UpdateWebhook func(childComplexity int, params model.UpdateWebhookRequest) int
- VerifyEmail func(childComplexity int, params model.VerifyEmailInput) int
+ VerifyEmail func(childComplexity int, params model.VerifyEmailRequest) int
VerifyOtp func(childComplexity int, params model.VerifyOTPRequest) int
}
@@ -238,34 +238,25 @@ type ComplexityRoot struct {
Query struct {
AdminSession func(childComplexity int) int
- EmailTemplates func(childComplexity int, params *model.PaginatedInput) int
+ EmailTemplates func(childComplexity int, params *model.PaginatedRequest) int
Env func(childComplexity int) int
Meta func(childComplexity int) int
Profile func(childComplexity int) int
- Session func(childComplexity int, params *model.SessionQueryInput) int
+ Session func(childComplexity int, params *model.SessionQueryRequest) int
User func(childComplexity int, params model.GetUserRequest) int
- Users func(childComplexity int, params *model.PaginatedInput) int
- ValidateJwtToken func(childComplexity int, params model.ValidateJWTTokenInput) int
- ValidateSession func(childComplexity int, params *model.ValidateSessionInput) int
- VerificationRequests func(childComplexity int, params *model.PaginatedInput) int
+ Users func(childComplexity int, params *model.PaginatedRequest) int
+ ValidateJwtToken func(childComplexity int, params model.ValidateJWTTokenRequest) int
+ ValidateSession func(childComplexity int, params *model.ValidateSessionRequest) int
+ VerificationRequests func(childComplexity int, params *model.PaginatedRequest) int
Webhook func(childComplexity int, params model.WebhookRequest) int
WebhookLogs func(childComplexity int, params *model.ListWebhookLogRequest) int
- Webhooks func(childComplexity int, params *model.PaginatedInput) int
+ Webhooks func(childComplexity int, params *model.PaginatedRequest) int
}
Response struct {
Message func(childComplexity int) int
}
- SMSVerificationRequests struct {
- Code func(childComplexity int) int
- CodeExpiresAt func(childComplexity int) int
- CreatedAt func(childComplexity int) int
- ID func(childComplexity int) int
- PhoneNumber func(childComplexity int) int
- UpdatedAt func(childComplexity int) int
- }
-
TestEndpointResponse struct {
HTTPStatus func(childComplexity int) int
Response func(childComplexity int) int
@@ -359,31 +350,31 @@ type ComplexityRoot struct {
}
type MutationResolver interface {
- Signup(ctx context.Context, params model.SignUpInput) (*model.AuthResponse, error)
- MobileSignup(ctx context.Context, params *model.MobileSignUpInput) (*model.AuthResponse, error)
- Login(ctx context.Context, params model.LoginInput) (*model.AuthResponse, error)
- MobileLogin(ctx context.Context, params model.MobileLoginInput) (*model.AuthResponse, error)
- MagicLinkLogin(ctx context.Context, params model.MagicLinkLoginInput) (*model.Response, error)
+ Signup(ctx context.Context, params model.SignUpRequest) (*model.AuthResponse, error)
+ MobileSignup(ctx context.Context, params *model.MobileSignUpRequest) (*model.AuthResponse, error)
+ Login(ctx context.Context, params model.LoginRequest) (*model.AuthResponse, error)
+ MobileLogin(ctx context.Context, params model.MobileLoginRequest) (*model.AuthResponse, error)
+ MagicLinkLogin(ctx context.Context, params model.MagicLinkLoginRequest) (*model.Response, error)
Logout(ctx context.Context) (*model.Response, error)
- UpdateProfile(ctx context.Context, params model.UpdateProfileInput) (*model.Response, error)
- VerifyEmail(ctx context.Context, params model.VerifyEmailInput) (*model.AuthResponse, error)
- ResendVerifyEmail(ctx context.Context, params model.ResendVerifyEmailInput) (*model.Response, error)
- ForgotPassword(ctx context.Context, params model.ForgotPasswordInput) (*model.ForgotPasswordResponse, error)
- ResetPassword(ctx context.Context, params model.ResetPasswordInput) (*model.Response, error)
- Revoke(ctx context.Context, params model.OAuthRevokeInput) (*model.Response, error)
+ UpdateProfile(ctx context.Context, params model.UpdateProfileRequest) (*model.Response, error)
+ VerifyEmail(ctx context.Context, params model.VerifyEmailRequest) (*model.AuthResponse, error)
+ ResendVerifyEmail(ctx context.Context, params model.ResendVerifyEmailRequest) (*model.Response, error)
+ ForgotPassword(ctx context.Context, params model.ForgotPasswordRequest) (*model.ForgotPasswordResponse, error)
+ ResetPassword(ctx context.Context, params model.ResetPasswordRequest) (*model.Response, error)
+ Revoke(ctx context.Context, params model.OAuthRevokeRequest) (*model.Response, error)
VerifyOtp(ctx context.Context, params model.VerifyOTPRequest) (*model.AuthResponse, error)
ResendOtp(ctx context.Context, params model.ResendOTPRequest) (*model.Response, error)
DeactivateAccount(ctx context.Context) (*model.Response, error)
- DeleteUser(ctx context.Context, params model.DeleteUserInput) (*model.Response, error)
- UpdateUser(ctx context.Context, params model.UpdateUserInput) (*model.User, error)
- AdminSignup(ctx context.Context, params model.AdminSignupInput) (*model.Response, error)
- AdminLogin(ctx context.Context, params model.AdminLoginInput) (*model.Response, error)
+ DeleteUser(ctx context.Context, params model.DeleteUserRequest) (*model.Response, error)
+ UpdateUser(ctx context.Context, params model.UpdateUserRequest) (*model.User, error)
+ AdminSignup(ctx context.Context, params model.AdminSignupRequest) (*model.Response, error)
+ AdminLogin(ctx context.Context, params model.AdminLoginRequest) (*model.Response, error)
AdminLogout(ctx context.Context) (*model.Response, error)
- UpdateEnv(ctx context.Context, params model.UpdateEnvInput) (*model.Response, error)
- InviteMembers(ctx context.Context, params model.InviteMemberInput) (*model.InviteMembersResponse, error)
- RevokeAccess(ctx context.Context, param model.UpdateAccessInput) (*model.Response, error)
- EnableAccess(ctx context.Context, param model.UpdateAccessInput) (*model.Response, error)
- GenerateJwtKeys(ctx context.Context, params model.GenerateJWTKeysInput) (*model.GenerateJWTKeysResponse, error)
+ UpdateEnv(ctx context.Context, params model.UpdateEnvRequest) (*model.Response, error)
+ InviteMembers(ctx context.Context, params model.InviteMemberRequest) (*model.InviteMembersResponse, error)
+ RevokeAccess(ctx context.Context, param model.UpdateAccessRequest) (*model.Response, error)
+ EnableAccess(ctx context.Context, param model.UpdateAccessRequest) (*model.Response, error)
+ GenerateJwtKeys(ctx context.Context, params model.GenerateJWTKeysRequest) (*model.GenerateJWTKeysResponse, error)
AddWebhook(ctx context.Context, params model.AddWebhookRequest) (*model.Response, error)
UpdateWebhook(ctx context.Context, params model.UpdateWebhookRequest) (*model.Response, error)
DeleteWebhook(ctx context.Context, params model.WebhookRequest) (*model.Response, error)
@@ -394,19 +385,19 @@ type MutationResolver interface {
}
type QueryResolver interface {
Meta(ctx context.Context) (*model.Meta, error)
- Session(ctx context.Context, params *model.SessionQueryInput) (*model.AuthResponse, error)
+ Session(ctx context.Context, params *model.SessionQueryRequest) (*model.AuthResponse, error)
Profile(ctx context.Context) (*model.User, error)
- ValidateJwtToken(ctx context.Context, params model.ValidateJWTTokenInput) (*model.ValidateJWTTokenResponse, error)
- ValidateSession(ctx context.Context, params *model.ValidateSessionInput) (*model.ValidateSessionResponse, error)
- Users(ctx context.Context, params *model.PaginatedInput) (*model.Users, error)
+ ValidateJwtToken(ctx context.Context, params model.ValidateJWTTokenRequest) (*model.ValidateJWTTokenResponse, error)
+ ValidateSession(ctx context.Context, params *model.ValidateSessionRequest) (*model.ValidateSessionResponse, error)
+ Users(ctx context.Context, params *model.PaginatedRequest) (*model.Users, error)
User(ctx context.Context, params model.GetUserRequest) (*model.User, error)
- VerificationRequests(ctx context.Context, params *model.PaginatedInput) (*model.VerificationRequests, error)
+ VerificationRequests(ctx context.Context, params *model.PaginatedRequest) (*model.VerificationRequests, error)
AdminSession(ctx context.Context) (*model.Response, error)
Env(ctx context.Context) (*model.Env, error)
Webhook(ctx context.Context, params model.WebhookRequest) (*model.Webhook, error)
- Webhooks(ctx context.Context, params *model.PaginatedInput) (*model.Webhooks, error)
+ Webhooks(ctx context.Context, params *model.PaginatedRequest) (*model.Webhooks, error)
WebhookLogs(ctx context.Context, params *model.ListWebhookLogRequest) (*model.WebhookLogs, error)
- EmailTemplates(ctx context.Context, params *model.PaginatedInput) (*model.EmailTemplates, error)
+ EmailTemplates(ctx context.Context, params *model.PaginatedRequest) (*model.EmailTemplates, error)
}
type executableSchema struct {
@@ -423,7 +414,7 @@ func (e *executableSchema) Schema() *ast.Schema {
return parsedSchema
}
-func (e *executableSchema) Complexity(typeName, field string, childComplexity int, rawArgs map[string]interface{}) (int, bool) {
+func (e *executableSchema) Complexity(ctx context.Context, typeName, field string, childComplexity int, rawArgs map[string]any) (int, bool) {
ec := executionContext{nil, e, 0, 0, nil}
_ = ec
switch typeName + "." + field {
@@ -1280,7 +1271,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
break
}
- args, err := ec.field_Mutation__add_email_template_args(context.TODO(), rawArgs)
+ args, err := ec.field_Mutation__add_email_template_args(ctx, rawArgs)
if err != nil {
return 0, false
}
@@ -1292,7 +1283,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
break
}
- args, err := ec.field_Mutation__add_webhook_args(context.TODO(), rawArgs)
+ args, err := ec.field_Mutation__add_webhook_args(ctx, rawArgs)
if err != nil {
return 0, false
}
@@ -1304,12 +1295,12 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
break
}
- args, err := ec.field_Mutation__admin_login_args(context.TODO(), rawArgs)
+ args, err := ec.field_Mutation__admin_login_args(ctx, rawArgs)
if err != nil {
return 0, false
}
- return e.complexity.Mutation.AdminLogin(childComplexity, args["params"].(model.AdminLoginInput)), true
+ return e.complexity.Mutation.AdminLogin(childComplexity, args["params"].(model.AdminLoginRequest)), true
case "Mutation._admin_logout":
if e.complexity.Mutation.AdminLogout == nil {
@@ -1323,12 +1314,12 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
break
}
- args, err := ec.field_Mutation__admin_signup_args(context.TODO(), rawArgs)
+ args, err := ec.field_Mutation__admin_signup_args(ctx, rawArgs)
if err != nil {
return 0, false
}
- return e.complexity.Mutation.AdminSignup(childComplexity, args["params"].(model.AdminSignupInput)), true
+ return e.complexity.Mutation.AdminSignup(childComplexity, args["params"].(model.AdminSignupRequest)), true
case "Mutation.deactivate_account":
if e.complexity.Mutation.DeactivateAccount == nil {
@@ -1342,7 +1333,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
break
}
- args, err := ec.field_Mutation__delete_email_template_args(context.TODO(), rawArgs)
+ args, err := ec.field_Mutation__delete_email_template_args(ctx, rawArgs)
if err != nil {
return 0, false
}
@@ -1354,19 +1345,19 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
break
}
- args, err := ec.field_Mutation__delete_user_args(context.TODO(), rawArgs)
+ args, err := ec.field_Mutation__delete_user_args(ctx, rawArgs)
if err != nil {
return 0, false
}
- return e.complexity.Mutation.DeleteUser(childComplexity, args["params"].(model.DeleteUserInput)), true
+ return e.complexity.Mutation.DeleteUser(childComplexity, args["params"].(model.DeleteUserRequest)), true
case "Mutation._delete_webhook":
if e.complexity.Mutation.DeleteWebhook == nil {
break
}
- args, err := ec.field_Mutation__delete_webhook_args(context.TODO(), rawArgs)
+ args, err := ec.field_Mutation__delete_webhook_args(ctx, rawArgs)
if err != nil {
return 0, false
}
@@ -1378,60 +1369,60 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
break
}
- args, err := ec.field_Mutation__enable_access_args(context.TODO(), rawArgs)
+ args, err := ec.field_Mutation__enable_access_args(ctx, rawArgs)
if err != nil {
return 0, false
}
- return e.complexity.Mutation.EnableAccess(childComplexity, args["param"].(model.UpdateAccessInput)), true
+ return e.complexity.Mutation.EnableAccess(childComplexity, args["param"].(model.UpdateAccessRequest)), true
case "Mutation.forgot_password":
if e.complexity.Mutation.ForgotPassword == nil {
break
}
- args, err := ec.field_Mutation_forgot_password_args(context.TODO(), rawArgs)
+ args, err := ec.field_Mutation_forgot_password_args(ctx, rawArgs)
if err != nil {
return 0, false
}
- return e.complexity.Mutation.ForgotPassword(childComplexity, args["params"].(model.ForgotPasswordInput)), true
+ return e.complexity.Mutation.ForgotPassword(childComplexity, args["params"].(model.ForgotPasswordRequest)), true
case "Mutation._generate_jwt_keys":
if e.complexity.Mutation.GenerateJwtKeys == nil {
break
}
- args, err := ec.field_Mutation__generate_jwt_keys_args(context.TODO(), rawArgs)
+ args, err := ec.field_Mutation__generate_jwt_keys_args(ctx, rawArgs)
if err != nil {
return 0, false
}
- return e.complexity.Mutation.GenerateJwtKeys(childComplexity, args["params"].(model.GenerateJWTKeysInput)), true
+ return e.complexity.Mutation.GenerateJwtKeys(childComplexity, args["params"].(model.GenerateJWTKeysRequest)), true
case "Mutation._invite_members":
if e.complexity.Mutation.InviteMembers == nil {
break
}
- args, err := ec.field_Mutation__invite_members_args(context.TODO(), rawArgs)
+ args, err := ec.field_Mutation__invite_members_args(ctx, rawArgs)
if err != nil {
return 0, false
}
- return e.complexity.Mutation.InviteMembers(childComplexity, args["params"].(model.InviteMemberInput)), true
+ return e.complexity.Mutation.InviteMembers(childComplexity, args["params"].(model.InviteMemberRequest)), true
case "Mutation.login":
if e.complexity.Mutation.Login == nil {
break
}
- args, err := ec.field_Mutation_login_args(context.TODO(), rawArgs)
+ args, err := ec.field_Mutation_login_args(ctx, rawArgs)
if err != nil {
return 0, false
}
- return e.complexity.Mutation.Login(childComplexity, args["params"].(model.LoginInput)), true
+ return e.complexity.Mutation.Login(childComplexity, args["params"].(model.LoginRequest)), true
case "Mutation.logout":
if e.complexity.Mutation.Logout == nil {
@@ -1445,43 +1436,43 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
break
}
- args, err := ec.field_Mutation_magic_link_login_args(context.TODO(), rawArgs)
+ args, err := ec.field_Mutation_magic_link_login_args(ctx, rawArgs)
if err != nil {
return 0, false
}
- return e.complexity.Mutation.MagicLinkLogin(childComplexity, args["params"].(model.MagicLinkLoginInput)), true
+ return e.complexity.Mutation.MagicLinkLogin(childComplexity, args["params"].(model.MagicLinkLoginRequest)), true
case "Mutation.mobile_login":
if e.complexity.Mutation.MobileLogin == nil {
break
}
- args, err := ec.field_Mutation_mobile_login_args(context.TODO(), rawArgs)
+ args, err := ec.field_Mutation_mobile_login_args(ctx, rawArgs)
if err != nil {
return 0, false
}
- return e.complexity.Mutation.MobileLogin(childComplexity, args["params"].(model.MobileLoginInput)), true
+ return e.complexity.Mutation.MobileLogin(childComplexity, args["params"].(model.MobileLoginRequest)), true
case "Mutation.mobile_signup":
if e.complexity.Mutation.MobileSignup == nil {
break
}
- args, err := ec.field_Mutation_mobile_signup_args(context.TODO(), rawArgs)
+ args, err := ec.field_Mutation_mobile_signup_args(ctx, rawArgs)
if err != nil {
return 0, false
}
- return e.complexity.Mutation.MobileSignup(childComplexity, args["params"].(*model.MobileSignUpInput)), true
+ return e.complexity.Mutation.MobileSignup(childComplexity, args["params"].(*model.MobileSignUpRequest)), true
case "Mutation.resend_otp":
if e.complexity.Mutation.ResendOtp == nil {
break
}
- args, err := ec.field_Mutation_resend_otp_args(context.TODO(), rawArgs)
+ args, err := ec.field_Mutation_resend_otp_args(ctx, rawArgs)
if err != nil {
return 0, false
}
@@ -1493,67 +1484,67 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
break
}
- args, err := ec.field_Mutation_resend_verify_email_args(context.TODO(), rawArgs)
+ args, err := ec.field_Mutation_resend_verify_email_args(ctx, rawArgs)
if err != nil {
return 0, false
}
- return e.complexity.Mutation.ResendVerifyEmail(childComplexity, args["params"].(model.ResendVerifyEmailInput)), true
+ return e.complexity.Mutation.ResendVerifyEmail(childComplexity, args["params"].(model.ResendVerifyEmailRequest)), true
case "Mutation.reset_password":
if e.complexity.Mutation.ResetPassword == nil {
break
}
- args, err := ec.field_Mutation_reset_password_args(context.TODO(), rawArgs)
+ args, err := ec.field_Mutation_reset_password_args(ctx, rawArgs)
if err != nil {
return 0, false
}
- return e.complexity.Mutation.ResetPassword(childComplexity, args["params"].(model.ResetPasswordInput)), true
+ return e.complexity.Mutation.ResetPassword(childComplexity, args["params"].(model.ResetPasswordRequest)), true
case "Mutation.revoke":
if e.complexity.Mutation.Revoke == nil {
break
}
- args, err := ec.field_Mutation_revoke_args(context.TODO(), rawArgs)
+ args, err := ec.field_Mutation_revoke_args(ctx, rawArgs)
if err != nil {
return 0, false
}
- return e.complexity.Mutation.Revoke(childComplexity, args["params"].(model.OAuthRevokeInput)), true
+ return e.complexity.Mutation.Revoke(childComplexity, args["params"].(model.OAuthRevokeRequest)), true
case "Mutation._revoke_access":
if e.complexity.Mutation.RevokeAccess == nil {
break
}
- args, err := ec.field_Mutation__revoke_access_args(context.TODO(), rawArgs)
+ args, err := ec.field_Mutation__revoke_access_args(ctx, rawArgs)
if err != nil {
return 0, false
}
- return e.complexity.Mutation.RevokeAccess(childComplexity, args["param"].(model.UpdateAccessInput)), true
+ return e.complexity.Mutation.RevokeAccess(childComplexity, args["param"].(model.UpdateAccessRequest)), true
case "Mutation.signup":
if e.complexity.Mutation.Signup == nil {
break
}
- args, err := ec.field_Mutation_signup_args(context.TODO(), rawArgs)
+ args, err := ec.field_Mutation_signup_args(ctx, rawArgs)
if err != nil {
return 0, false
}
- return e.complexity.Mutation.Signup(childComplexity, args["params"].(model.SignUpInput)), true
+ return e.complexity.Mutation.Signup(childComplexity, args["params"].(model.SignUpRequest)), true
case "Mutation._test_endpoint":
if e.complexity.Mutation.TestEndpoint == nil {
break
}
- args, err := ec.field_Mutation__test_endpoint_args(context.TODO(), rawArgs)
+ args, err := ec.field_Mutation__test_endpoint_args(ctx, rawArgs)
if err != nil {
return 0, false
}
@@ -1565,7 +1556,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
break
}
- args, err := ec.field_Mutation__update_email_template_args(context.TODO(), rawArgs)
+ args, err := ec.field_Mutation__update_email_template_args(ctx, rawArgs)
if err != nil {
return 0, false
}
@@ -1577,43 +1568,43 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
break
}
- args, err := ec.field_Mutation__update_env_args(context.TODO(), rawArgs)
+ args, err := ec.field_Mutation__update_env_args(ctx, rawArgs)
if err != nil {
return 0, false
}
- return e.complexity.Mutation.UpdateEnv(childComplexity, args["params"].(model.UpdateEnvInput)), true
+ return e.complexity.Mutation.UpdateEnv(childComplexity, args["params"].(model.UpdateEnvRequest)), true
case "Mutation.update_profile":
if e.complexity.Mutation.UpdateProfile == nil {
break
}
- args, err := ec.field_Mutation_update_profile_args(context.TODO(), rawArgs)
+ args, err := ec.field_Mutation_update_profile_args(ctx, rawArgs)
if err != nil {
return 0, false
}
- return e.complexity.Mutation.UpdateProfile(childComplexity, args["params"].(model.UpdateProfileInput)), true
+ return e.complexity.Mutation.UpdateProfile(childComplexity, args["params"].(model.UpdateProfileRequest)), true
case "Mutation._update_user":
if e.complexity.Mutation.UpdateUser == nil {
break
}
- args, err := ec.field_Mutation__update_user_args(context.TODO(), rawArgs)
+ args, err := ec.field_Mutation__update_user_args(ctx, rawArgs)
if err != nil {
return 0, false
}
- return e.complexity.Mutation.UpdateUser(childComplexity, args["params"].(model.UpdateUserInput)), true
+ return e.complexity.Mutation.UpdateUser(childComplexity, args["params"].(model.UpdateUserRequest)), true
case "Mutation._update_webhook":
if e.complexity.Mutation.UpdateWebhook == nil {
break
}
- args, err := ec.field_Mutation__update_webhook_args(context.TODO(), rawArgs)
+ args, err := ec.field_Mutation__update_webhook_args(ctx, rawArgs)
if err != nil {
return 0, false
}
@@ -1625,19 +1616,19 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
break
}
- args, err := ec.field_Mutation_verify_email_args(context.TODO(), rawArgs)
+ args, err := ec.field_Mutation_verify_email_args(ctx, rawArgs)
if err != nil {
return 0, false
}
- return e.complexity.Mutation.VerifyEmail(childComplexity, args["params"].(model.VerifyEmailInput)), true
+ return e.complexity.Mutation.VerifyEmail(childComplexity, args["params"].(model.VerifyEmailRequest)), true
case "Mutation.verify_otp":
if e.complexity.Mutation.VerifyOtp == nil {
break
}
- args, err := ec.field_Mutation_verify_otp_args(context.TODO(), rawArgs)
+ args, err := ec.field_Mutation_verify_otp_args(ctx, rawArgs)
if err != nil {
return 0, false
}
@@ -1684,12 +1675,12 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
break
}
- args, err := ec.field_Query__email_templates_args(context.TODO(), rawArgs)
+ args, err := ec.field_Query__email_templates_args(ctx, rawArgs)
if err != nil {
return 0, false
}
- return e.complexity.Query.EmailTemplates(childComplexity, args["params"].(*model.PaginatedInput)), true
+ return e.complexity.Query.EmailTemplates(childComplexity, args["params"].(*model.PaginatedRequest)), true
case "Query._env":
if e.complexity.Query.Env == nil {
@@ -1717,19 +1708,19 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
break
}
- args, err := ec.field_Query_session_args(context.TODO(), rawArgs)
+ args, err := ec.field_Query_session_args(ctx, rawArgs)
if err != nil {
return 0, false
}
- return e.complexity.Query.Session(childComplexity, args["params"].(*model.SessionQueryInput)), true
+ return e.complexity.Query.Session(childComplexity, args["params"].(*model.SessionQueryRequest)), true
case "Query._user":
if e.complexity.Query.User == nil {
break
}
- args, err := ec.field_Query__user_args(context.TODO(), rawArgs)
+ args, err := ec.field_Query__user_args(ctx, rawArgs)
if err != nil {
return 0, false
}
@@ -1741,55 +1732,55 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
break
}
- args, err := ec.field_Query__users_args(context.TODO(), rawArgs)
+ args, err := ec.field_Query__users_args(ctx, rawArgs)
if err != nil {
return 0, false
}
- return e.complexity.Query.Users(childComplexity, args["params"].(*model.PaginatedInput)), true
+ return e.complexity.Query.Users(childComplexity, args["params"].(*model.PaginatedRequest)), true
case "Query.validate_jwt_token":
if e.complexity.Query.ValidateJwtToken == nil {
break
}
- args, err := ec.field_Query_validate_jwt_token_args(context.TODO(), rawArgs)
+ args, err := ec.field_Query_validate_jwt_token_args(ctx, rawArgs)
if err != nil {
return 0, false
}
- return e.complexity.Query.ValidateJwtToken(childComplexity, args["params"].(model.ValidateJWTTokenInput)), true
+ return e.complexity.Query.ValidateJwtToken(childComplexity, args["params"].(model.ValidateJWTTokenRequest)), true
case "Query.validate_session":
if e.complexity.Query.ValidateSession == nil {
break
}
- args, err := ec.field_Query_validate_session_args(context.TODO(), rawArgs)
+ args, err := ec.field_Query_validate_session_args(ctx, rawArgs)
if err != nil {
return 0, false
}
- return e.complexity.Query.ValidateSession(childComplexity, args["params"].(*model.ValidateSessionInput)), true
+ return e.complexity.Query.ValidateSession(childComplexity, args["params"].(*model.ValidateSessionRequest)), true
case "Query._verification_requests":
if e.complexity.Query.VerificationRequests == nil {
break
}
- args, err := ec.field_Query__verification_requests_args(context.TODO(), rawArgs)
+ args, err := ec.field_Query__verification_requests_args(ctx, rawArgs)
if err != nil {
return 0, false
}
- return e.complexity.Query.VerificationRequests(childComplexity, args["params"].(*model.PaginatedInput)), true
+ return e.complexity.Query.VerificationRequests(childComplexity, args["params"].(*model.PaginatedRequest)), true
case "Query._webhook":
if e.complexity.Query.Webhook == nil {
break
}
- args, err := ec.field_Query__webhook_args(context.TODO(), rawArgs)
+ args, err := ec.field_Query__webhook_args(ctx, rawArgs)
if err != nil {
return 0, false
}
@@ -1801,7 +1792,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
break
}
- args, err := ec.field_Query__webhook_logs_args(context.TODO(), rawArgs)
+ args, err := ec.field_Query__webhook_logs_args(ctx, rawArgs)
if err != nil {
return 0, false
}
@@ -1813,12 +1804,12 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
break
}
- args, err := ec.field_Query__webhooks_args(context.TODO(), rawArgs)
+ args, err := ec.field_Query__webhooks_args(ctx, rawArgs)
if err != nil {
return 0, false
}
- return e.complexity.Query.Webhooks(childComplexity, args["params"].(*model.PaginatedInput)), true
+ return e.complexity.Query.Webhooks(childComplexity, args["params"].(*model.PaginatedRequest)), true
case "Response.message":
if e.complexity.Response.Message == nil {
@@ -1827,48 +1818,6 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.Response.Message(childComplexity), true
- case "SMSVerificationRequests.code":
- if e.complexity.SMSVerificationRequests.Code == nil {
- break
- }
-
- return e.complexity.SMSVerificationRequests.Code(childComplexity), true
-
- case "SMSVerificationRequests.code_expires_at":
- if e.complexity.SMSVerificationRequests.CodeExpiresAt == nil {
- break
- }
-
- return e.complexity.SMSVerificationRequests.CodeExpiresAt(childComplexity), true
-
- case "SMSVerificationRequests.created_at":
- if e.complexity.SMSVerificationRequests.CreatedAt == nil {
- break
- }
-
- return e.complexity.SMSVerificationRequests.CreatedAt(childComplexity), true
-
- case "SMSVerificationRequests.id":
- if e.complexity.SMSVerificationRequests.ID == nil {
- break
- }
-
- return e.complexity.SMSVerificationRequests.ID(childComplexity), true
-
- case "SMSVerificationRequests.phone_number":
- if e.complexity.SMSVerificationRequests.PhoneNumber == nil {
- break
- }
-
- return e.complexity.SMSVerificationRequests.PhoneNumber(childComplexity), true
-
- case "SMSVerificationRequests.updated_at":
- if e.complexity.SMSVerificationRequests.UpdatedAt == nil {
- break
- }
-
- return e.complexity.SMSVerificationRequests.UpdatedAt(childComplexity), true
-
case "TestEndpointResponse.http_status":
if e.complexity.TestEndpointResponse.HTTPStatus == nil {
break
@@ -2280,48 +2229,48 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
}
func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler {
- rc := graphql.GetOperationContext(ctx)
- ec := executionContext{rc, e, 0, 0, make(chan graphql.DeferredResult)}
+ opCtx := graphql.GetOperationContext(ctx)
+ ec := executionContext{opCtx, e, 0, 0, make(chan graphql.DeferredResult)}
inputUnmarshalMap := graphql.BuildUnmarshalerMap(
ec.unmarshalInputAddEmailTemplateRequest,
ec.unmarshalInputAddWebhookRequest,
- ec.unmarshalInputAdminLoginInput,
- ec.unmarshalInputAdminSignupInput,
+ ec.unmarshalInputAdminLoginRequest,
+ ec.unmarshalInputAdminSignupRequest,
ec.unmarshalInputDeleteEmailTemplateRequest,
- ec.unmarshalInputDeleteUserInput,
- ec.unmarshalInputForgotPasswordInput,
- ec.unmarshalInputGenerateJWTKeysInput,
+ ec.unmarshalInputDeleteUserRequest,
+ ec.unmarshalInputForgotPasswordRequest,
+ ec.unmarshalInputGenerateJWTKeysRequest,
ec.unmarshalInputGetUserRequest,
- ec.unmarshalInputInviteMemberInput,
+ ec.unmarshalInputInviteMemberRequest,
ec.unmarshalInputListWebhookLogRequest,
- ec.unmarshalInputLoginInput,
- ec.unmarshalInputMagicLinkLoginInput,
- ec.unmarshalInputMobileLoginInput,
- ec.unmarshalInputMobileSignUpInput,
- ec.unmarshalInputOAuthRevokeInput,
- ec.unmarshalInputPaginatedInput,
- ec.unmarshalInputPaginationInput,
+ ec.unmarshalInputLoginRequest,
+ ec.unmarshalInputMagicLinkLoginRequest,
+ ec.unmarshalInputMobileLoginRequest,
+ ec.unmarshalInputMobileSignUpRequest,
+ ec.unmarshalInputOAuthRevokeRequest,
+ ec.unmarshalInputPaginatedRequest,
+ ec.unmarshalInputPaginationRequest,
ec.unmarshalInputResendOTPRequest,
- ec.unmarshalInputResendVerifyEmailInput,
- ec.unmarshalInputResetPasswordInput,
- ec.unmarshalInputSessionQueryInput,
- ec.unmarshalInputSignUpInput,
+ ec.unmarshalInputResendVerifyEmailRequest,
+ ec.unmarshalInputResetPasswordRequest,
+ ec.unmarshalInputSessionQueryRequest,
+ ec.unmarshalInputSignUpRequest,
ec.unmarshalInputTestEndpointRequest,
- ec.unmarshalInputUpdateAccessInput,
+ ec.unmarshalInputUpdateAccessRequest,
ec.unmarshalInputUpdateEmailTemplateRequest,
- ec.unmarshalInputUpdateEnvInput,
- ec.unmarshalInputUpdateProfileInput,
- ec.unmarshalInputUpdateUserInput,
+ ec.unmarshalInputUpdateEnvRequest,
+ ec.unmarshalInputUpdateProfileRequest,
+ ec.unmarshalInputUpdateUserRequest,
ec.unmarshalInputUpdateWebhookRequest,
- ec.unmarshalInputValidateJWTTokenInput,
- ec.unmarshalInputValidateSessionInput,
- ec.unmarshalInputVerifyEmailInput,
+ ec.unmarshalInputValidateJWTTokenRequest,
+ ec.unmarshalInputValidateSessionRequest,
+ ec.unmarshalInputVerifyEmailRequest,
ec.unmarshalInputVerifyOTPRequest,
ec.unmarshalInputWebhookRequest,
)
first := true
- switch rc.Operation.Operation {
+ switch opCtx.Operation.Operation {
case ast.Query:
return func(ctx context.Context) *graphql.Response {
var response graphql.Response
@@ -2329,7 +2278,7 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler {
if first {
first = false
ctx = graphql.WithUnmarshalerMap(ctx, inputUnmarshalMap)
- data = ec._Query(ctx, rc.Operation.SelectionSet)
+ data = ec._Query(ctx, opCtx.Operation.SelectionSet)
} else {
if atomic.LoadInt32(&ec.pendingDeferred) > 0 {
result := <-ec.deferredResults
@@ -2359,7 +2308,7 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler {
}
first = false
ctx = graphql.WithUnmarshalerMap(ctx, inputUnmarshalMap)
- data := ec._Mutation(ctx, rc.Operation.SelectionSet)
+ data := ec._Mutation(ctx, opCtx.Operation.SelectionSet)
var buf bytes.Buffer
data.MarshalGQL(&buf)
@@ -2467,7 +2416,7 @@ type User {
gender: String
birthdate: String
phone_number: String
- phone_number_verified: Boolean
+ phone_number_verified: Boolean!
picture: String
roles: [String!]!
created_at: Int64
@@ -2499,15 +2448,6 @@ type VerificationRequests {
verification_requests: [VerificationRequest!]!
}
-type SMSVerificationRequests {
- id: ID!
- code: String!
- code_expires_at: Int64!
- phone_number: String!
- created_at: Int64!
- updated_at: Int64
-}
-
type Error {
message: String!
reason: String!
@@ -2687,7 +2627,7 @@ type EmailTemplates {
email_templates: [EmailTemplate!]!
}
-input UpdateEnvInput {
+input UpdateEnvRequest {
ACCESS_TOKEN_EXPIRY_TIME: String
ADMIN_SECRET: String
CUSTOM_ACCESS_TOKEN_SCRIPT: String
@@ -2752,16 +2692,16 @@ input UpdateEnvInput {
DISABLE_TOTP_LOGIN: Boolean
}
-input AdminLoginInput {
+input AdminLoginRequest {
admin_secret: String!
}
-input AdminSignupInput {
+input AdminSignupRequest {
admin_secret: String!
}
# Deprecated from v1.2.0
-input MobileSignUpInput {
+input MobileSignUpRequest {
email: String
given_name: String
family_name: String
@@ -2784,7 +2724,7 @@ input MobileSignUpInput {
app_data: Map
}
-input SignUpInput {
+input SignUpRequest {
email: String
given_name: String
family_name: String
@@ -2807,7 +2747,7 @@ input SignUpInput {
app_data: Map
}
-input LoginInput {
+input LoginRequest {
email: String
phone_number: String
password: String!
@@ -2820,7 +2760,7 @@ input LoginInput {
}
# Deprecated from v1.2.0
-input MobileLoginInput {
+input MobileLoginRequest {
phone_number: String!
password: String!
roles: [String!]
@@ -2831,7 +2771,7 @@ input MobileLoginInput {
state: String
}
-input VerifyEmailInput {
+input VerifyEmailRequest {
token: String!
# state is used for authorization code grant flow
# it is used to get code for an on-going auth process during login
@@ -2839,7 +2779,7 @@ input VerifyEmailInput {
state: String
}
-input ResendVerifyEmailInput {
+input ResendVerifyEmailRequest {
email: String!
identifier: String!
# state is used for authorization code grant flow
@@ -2848,7 +2788,7 @@ input ResendVerifyEmailInput {
state: String
}
-input UpdateProfileInput {
+input UpdateProfileRequest {
old_password: String
new_password: String
confirm_new_password: String
@@ -2865,7 +2805,7 @@ input UpdateProfileInput {
app_data: Map
}
-input UpdateUserInput {
+input UpdateUserRequest {
id: ID!
email: String
email_verified: Boolean
@@ -2883,14 +2823,14 @@ input UpdateUserInput {
app_data: Map
}
-input ForgotPasswordInput {
+input ForgotPasswordRequest {
email: String
phone_number: String
state: String
redirect_uri: String
}
-input ResetPasswordInput {
+input ResetPasswordRequest {
token: String
otp: String
phone_number: String
@@ -2898,11 +2838,11 @@ input ResetPasswordInput {
confirm_password: String!
}
-input DeleteUserInput {
+input DeleteUserRequest {
email: String!
}
-input MagicLinkLoginInput {
+input MagicLinkLoginRequest {
email: String!
roles: [String!]
scope: [String!]
@@ -2910,50 +2850,50 @@ input MagicLinkLoginInput {
redirect_uri: String
}
-input SessionQueryInput {
+input SessionQueryRequest {
roles: [String!]
scope: [String!]
}
-input PaginationInput {
+input PaginationRequest {
limit: Int64
page: Int64
}
-input PaginatedInput {
- pagination: PaginationInput
+input PaginatedRequest {
+ pagination: PaginationRequest
}
-input OAuthRevokeInput {
+input OAuthRevokeRequest {
refresh_token: String!
}
-input InviteMemberInput {
+input InviteMemberRequest {
emails: [String!]!
redirect_uri: String
}
-input UpdateAccessInput {
+input UpdateAccessRequest {
user_id: String!
}
-input ValidateJWTTokenInput {
+input ValidateJWTTokenRequest {
token_type: String!
token: String!
roles: [String!]
}
-input ValidateSessionInput {
+input ValidateSessionRequest {
cookie: String!
roles: [String!]
}
-input GenerateJWTKeysInput {
+input GenerateJWTKeysRequest {
type: String!
}
input ListWebhookLogRequest {
- pagination: PaginationInput
+ pagination: PaginationRequest
webhook_id: String
}
@@ -3035,34 +2975,37 @@ input GetUserRequest {
}
type Mutation {
- signup(params: SignUpInput!): AuthResponse!
+ signup(params: SignUpRequest!): AuthResponse!
# Deprecated from v1.2.0
- mobile_signup(params: MobileSignUpInput): AuthResponse!
- login(params: LoginInput!): AuthResponse!
+ mobile_signup(params: MobileSignUpRequest): AuthResponse!
+ login(params: LoginRequest!): AuthResponse!
# Deprecated from v1.2.0
- mobile_login(params: MobileLoginInput!): AuthResponse!
- magic_link_login(params: MagicLinkLoginInput!): Response!
+ mobile_login(params: MobileLoginRequest!): AuthResponse!
+ magic_link_login(params: MagicLinkLoginRequest!): Response!
logout: Response!
- update_profile(params: UpdateProfileInput!): Response!
- verify_email(params: VerifyEmailInput!): AuthResponse!
- resend_verify_email(params: ResendVerifyEmailInput!): Response!
- forgot_password(params: ForgotPasswordInput!): ForgotPasswordResponse!
- reset_password(params: ResetPasswordInput!): Response!
- revoke(params: OAuthRevokeInput!): Response!
+ update_profile(params: UpdateProfileRequest!): Response!
+ verify_email(params: VerifyEmailRequest!): AuthResponse!
+ resend_verify_email(params: ResendVerifyEmailRequest!): Response!
+ forgot_password(params: ForgotPasswordRequest!): ForgotPasswordResponse!
+ reset_password(params: ResetPasswordRequest!): Response!
+ revoke(params: OAuthRevokeRequest!): Response!
verify_otp(params: VerifyOTPRequest!): AuthResponse!
resend_otp(params: ResendOTPRequest!): Response!
deactivate_account: Response!
# admin only apis
- _delete_user(params: DeleteUserInput!): Response!
- _update_user(params: UpdateUserInput!): User!
- _admin_signup(params: AdminSignupInput!): Response!
- _admin_login(params: AdminLoginInput!): Response!
+ _delete_user(params: DeleteUserRequest!): Response!
+ _update_user(params: UpdateUserRequest!): User!
+ # deprecated from v2.0.0
+ _admin_signup(params: AdminSignupRequest!): Response!
+ _admin_login(params: AdminLoginRequest!): Response!
_admin_logout: Response!
- _update_env(params: UpdateEnvInput!): Response!
- _invite_members(params: InviteMemberInput!): InviteMembersResponse!
- _revoke_access(param: UpdateAccessInput!): Response!
- _enable_access(param: UpdateAccessInput!): Response!
- _generate_jwt_keys(params: GenerateJWTKeysInput!): GenerateJWTKeysResponse!
+ # Deprecated from v2.0.0
+ _update_env(params: UpdateEnvRequest!): Response!
+ _invite_members(params: InviteMemberRequest!): InviteMembersResponse!
+ _revoke_access(param: UpdateAccessRequest!): Response!
+ _enable_access(param: UpdateAccessRequest!): Response!
+ # Deprecated from v2.0.0
+ _generate_jwt_keys(params: GenerateJWTKeysRequest!): GenerateJWTKeysResponse!
_add_webhook(params: AddWebhookRequest!): Response!
_update_webhook(params: UpdateWebhookRequest!): Response!
_delete_webhook(params: WebhookRequest!): Response!
@@ -3074,20 +3017,21 @@ type Mutation {
type Query {
meta: Meta!
- session(params: SessionQueryInput): AuthResponse!
+ session(params: SessionQueryRequest): AuthResponse!
profile: User!
- validate_jwt_token(params: ValidateJWTTokenInput!): ValidateJWTTokenResponse!
- validate_session(params: ValidateSessionInput): ValidateSessionResponse!
+ validate_jwt_token(params: ValidateJWTTokenRequest!): ValidateJWTTokenResponse!
+ validate_session(params: ValidateSessionRequest): ValidateSessionResponse!
# admin only apis
- _users(params: PaginatedInput): Users!
+ _users(params: PaginatedRequest): Users!
_user(params: GetUserRequest!): User!
- _verification_requests(params: PaginatedInput): VerificationRequests!
+ _verification_requests(params: PaginatedRequest): VerificationRequests!
_admin_session: Response!
+ # Deprecated from v2.0.0
_env: Env!
_webhook(params: WebhookRequest!): Webhook!
- _webhooks(params: PaginatedInput): Webhooks!
+ _webhooks(params: PaginatedRequest): Webhooks!
_webhook_logs(params: ListWebhookLogRequest): WebhookLogs!
- _email_templates(params: PaginatedInput): EmailTemplates!
+ _email_templates(params: PaginatedRequest): EmailTemplates!
}
`, BuiltIn: false},
}
@@ -3097,774 +3041,1250 @@ var parsedSchema = gqlparser.MustLoadSchema(sources...)
// region ***************************** args.gotpl *****************************
-func (ec *executionContext) field_Mutation__add_email_template_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
+func (ec *executionContext) field_Mutation__add_email_template_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
var err error
- args := map[string]interface{}{}
- var arg0 model.AddEmailTemplateRequest
- if tmp, ok := rawArgs["params"]; ok {
- ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
- arg0, err = ec.unmarshalNAddEmailTemplateRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐAddEmailTemplateRequest(ctx, tmp)
- if err != nil {
- return nil, err
- }
+ args := map[string]any{}
+ arg0, err := ec.field_Mutation__add_email_template_argsParams(ctx, rawArgs)
+ if err != nil {
+ return nil, err
}
args["params"] = arg0
return args, nil
}
+func (ec *executionContext) field_Mutation__add_email_template_argsParams(
+ ctx context.Context,
+ rawArgs map[string]any,
+) (model.AddEmailTemplateRequest, error) {
+ if _, ok := rawArgs["params"]; !ok {
+ var zeroVal model.AddEmailTemplateRequest
+ return zeroVal, nil
+ }
-func (ec *executionContext) field_Mutation__add_webhook_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
- var err error
- args := map[string]interface{}{}
- var arg0 model.AddWebhookRequest
+ ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
if tmp, ok := rawArgs["params"]; ok {
- ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
- arg0, err = ec.unmarshalNAddWebhookRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐAddWebhookRequest(ctx, tmp)
- if err != nil {
- return nil, err
- }
+ return ec.unmarshalNAddEmailTemplateRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐAddEmailTemplateRequest(ctx, tmp)
}
- args["params"] = arg0
- return args, nil
+
+ var zeroVal model.AddEmailTemplateRequest
+ return zeroVal, nil
}
-func (ec *executionContext) field_Mutation__admin_login_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
+func (ec *executionContext) field_Mutation__add_webhook_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
var err error
- args := map[string]interface{}{}
- var arg0 model.AdminLoginInput
- if tmp, ok := rawArgs["params"]; ok {
- ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
- arg0, err = ec.unmarshalNAdminLoginInput2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐAdminLoginInput(ctx, tmp)
- if err != nil {
- return nil, err
- }
+ args := map[string]any{}
+ arg0, err := ec.field_Mutation__add_webhook_argsParams(ctx, rawArgs)
+ if err != nil {
+ return nil, err
}
args["params"] = arg0
return args, nil
}
+func (ec *executionContext) field_Mutation__add_webhook_argsParams(
+ ctx context.Context,
+ rawArgs map[string]any,
+) (model.AddWebhookRequest, error) {
+ if _, ok := rawArgs["params"]; !ok {
+ var zeroVal model.AddWebhookRequest
+ return zeroVal, nil
+ }
-func (ec *executionContext) field_Mutation__admin_signup_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
- var err error
- args := map[string]interface{}{}
- var arg0 model.AdminSignupInput
+ ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
if tmp, ok := rawArgs["params"]; ok {
- ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
- arg0, err = ec.unmarshalNAdminSignupInput2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐAdminSignupInput(ctx, tmp)
- if err != nil {
- return nil, err
- }
+ return ec.unmarshalNAddWebhookRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐAddWebhookRequest(ctx, tmp)
}
- args["params"] = arg0
- return args, nil
+
+ var zeroVal model.AddWebhookRequest
+ return zeroVal, nil
}
-func (ec *executionContext) field_Mutation__delete_email_template_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
+func (ec *executionContext) field_Mutation__admin_login_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
var err error
- args := map[string]interface{}{}
- var arg0 model.DeleteEmailTemplateRequest
- if tmp, ok := rawArgs["params"]; ok {
- ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
- arg0, err = ec.unmarshalNDeleteEmailTemplateRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐDeleteEmailTemplateRequest(ctx, tmp)
- if err != nil {
- return nil, err
- }
+ args := map[string]any{}
+ arg0, err := ec.field_Mutation__admin_login_argsParams(ctx, rawArgs)
+ if err != nil {
+ return nil, err
}
args["params"] = arg0
return args, nil
}
+func (ec *executionContext) field_Mutation__admin_login_argsParams(
+ ctx context.Context,
+ rawArgs map[string]any,
+) (model.AdminLoginRequest, error) {
+ if _, ok := rawArgs["params"]; !ok {
+ var zeroVal model.AdminLoginRequest
+ return zeroVal, nil
+ }
-func (ec *executionContext) field_Mutation__delete_user_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
- var err error
- args := map[string]interface{}{}
- var arg0 model.DeleteUserInput
+ ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
if tmp, ok := rawArgs["params"]; ok {
- ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
- arg0, err = ec.unmarshalNDeleteUserInput2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐDeleteUserInput(ctx, tmp)
- if err != nil {
- return nil, err
- }
+ return ec.unmarshalNAdminLoginRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐAdminLoginRequest(ctx, tmp)
}
- args["params"] = arg0
- return args, nil
+
+ var zeroVal model.AdminLoginRequest
+ return zeroVal, nil
}
-func (ec *executionContext) field_Mutation__delete_webhook_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
+func (ec *executionContext) field_Mutation__admin_signup_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
var err error
- args := map[string]interface{}{}
- var arg0 model.WebhookRequest
- if tmp, ok := rawArgs["params"]; ok {
- ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
- arg0, err = ec.unmarshalNWebhookRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐWebhookRequest(ctx, tmp)
- if err != nil {
- return nil, err
- }
+ args := map[string]any{}
+ arg0, err := ec.field_Mutation__admin_signup_argsParams(ctx, rawArgs)
+ if err != nil {
+ return nil, err
}
args["params"] = arg0
return args, nil
}
+func (ec *executionContext) field_Mutation__admin_signup_argsParams(
+ ctx context.Context,
+ rawArgs map[string]any,
+) (model.AdminSignupRequest, error) {
+ if _, ok := rawArgs["params"]; !ok {
+ var zeroVal model.AdminSignupRequest
+ return zeroVal, nil
+ }
-func (ec *executionContext) field_Mutation__enable_access_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
- var err error
- args := map[string]interface{}{}
- var arg0 model.UpdateAccessInput
- if tmp, ok := rawArgs["param"]; ok {
- ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("param"))
- arg0, err = ec.unmarshalNUpdateAccessInput2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐUpdateAccessInput(ctx, tmp)
- if err != nil {
- return nil, err
- }
+ ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
+ if tmp, ok := rawArgs["params"]; ok {
+ return ec.unmarshalNAdminSignupRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐAdminSignupRequest(ctx, tmp)
}
- args["param"] = arg0
- return args, nil
+
+ var zeroVal model.AdminSignupRequest
+ return zeroVal, nil
}
-func (ec *executionContext) field_Mutation__generate_jwt_keys_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
+func (ec *executionContext) field_Mutation__delete_email_template_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
var err error
- args := map[string]interface{}{}
- var arg0 model.GenerateJWTKeysInput
- if tmp, ok := rawArgs["params"]; ok {
- ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
- arg0, err = ec.unmarshalNGenerateJWTKeysInput2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐGenerateJWTKeysInput(ctx, tmp)
- if err != nil {
- return nil, err
- }
+ args := map[string]any{}
+ arg0, err := ec.field_Mutation__delete_email_template_argsParams(ctx, rawArgs)
+ if err != nil {
+ return nil, err
}
args["params"] = arg0
return args, nil
}
+func (ec *executionContext) field_Mutation__delete_email_template_argsParams(
+ ctx context.Context,
+ rawArgs map[string]any,
+) (model.DeleteEmailTemplateRequest, error) {
+ if _, ok := rawArgs["params"]; !ok {
+ var zeroVal model.DeleteEmailTemplateRequest
+ return zeroVal, nil
+ }
-func (ec *executionContext) field_Mutation__invite_members_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
- var err error
- args := map[string]interface{}{}
- var arg0 model.InviteMemberInput
+ ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
if tmp, ok := rawArgs["params"]; ok {
- ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
- arg0, err = ec.unmarshalNInviteMemberInput2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐInviteMemberInput(ctx, tmp)
- if err != nil {
- return nil, err
- }
+ return ec.unmarshalNDeleteEmailTemplateRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐDeleteEmailTemplateRequest(ctx, tmp)
}
- args["params"] = arg0
- return args, nil
+
+ var zeroVal model.DeleteEmailTemplateRequest
+ return zeroVal, nil
}
-func (ec *executionContext) field_Mutation__revoke_access_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
+func (ec *executionContext) field_Mutation__delete_user_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
var err error
- args := map[string]interface{}{}
- var arg0 model.UpdateAccessInput
- if tmp, ok := rawArgs["param"]; ok {
- ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("param"))
- arg0, err = ec.unmarshalNUpdateAccessInput2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐUpdateAccessInput(ctx, tmp)
- if err != nil {
- return nil, err
- }
+ args := map[string]any{}
+ arg0, err := ec.field_Mutation__delete_user_argsParams(ctx, rawArgs)
+ if err != nil {
+ return nil, err
}
- args["param"] = arg0
+ args["params"] = arg0
return args, nil
}
+func (ec *executionContext) field_Mutation__delete_user_argsParams(
+ ctx context.Context,
+ rawArgs map[string]any,
+) (model.DeleteUserRequest, error) {
+ if _, ok := rawArgs["params"]; !ok {
+ var zeroVal model.DeleteUserRequest
+ return zeroVal, nil
+ }
-func (ec *executionContext) field_Mutation__test_endpoint_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
- var err error
- args := map[string]interface{}{}
- var arg0 model.TestEndpointRequest
+ ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
if tmp, ok := rawArgs["params"]; ok {
- ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
- arg0, err = ec.unmarshalNTestEndpointRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐTestEndpointRequest(ctx, tmp)
- if err != nil {
- return nil, err
- }
+ return ec.unmarshalNDeleteUserRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐDeleteUserRequest(ctx, tmp)
}
- args["params"] = arg0
- return args, nil
+
+ var zeroVal model.DeleteUserRequest
+ return zeroVal, nil
}
-func (ec *executionContext) field_Mutation__update_email_template_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
+func (ec *executionContext) field_Mutation__delete_webhook_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
var err error
- args := map[string]interface{}{}
- var arg0 model.UpdateEmailTemplateRequest
- if tmp, ok := rawArgs["params"]; ok {
- ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
- arg0, err = ec.unmarshalNUpdateEmailTemplateRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐUpdateEmailTemplateRequest(ctx, tmp)
- if err != nil {
- return nil, err
- }
+ args := map[string]any{}
+ arg0, err := ec.field_Mutation__delete_webhook_argsParams(ctx, rawArgs)
+ if err != nil {
+ return nil, err
}
args["params"] = arg0
return args, nil
}
+func (ec *executionContext) field_Mutation__delete_webhook_argsParams(
+ ctx context.Context,
+ rawArgs map[string]any,
+) (model.WebhookRequest, error) {
+ if _, ok := rawArgs["params"]; !ok {
+ var zeroVal model.WebhookRequest
+ return zeroVal, nil
+ }
-func (ec *executionContext) field_Mutation__update_env_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
- var err error
- args := map[string]interface{}{}
- var arg0 model.UpdateEnvInput
+ ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
if tmp, ok := rawArgs["params"]; ok {
- ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
- arg0, err = ec.unmarshalNUpdateEnvInput2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐUpdateEnvInput(ctx, tmp)
- if err != nil {
- return nil, err
- }
+ return ec.unmarshalNWebhookRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐWebhookRequest(ctx, tmp)
}
- args["params"] = arg0
- return args, nil
+
+ var zeroVal model.WebhookRequest
+ return zeroVal, nil
}
-func (ec *executionContext) field_Mutation__update_user_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
+func (ec *executionContext) field_Mutation__enable_access_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
var err error
- args := map[string]interface{}{}
- var arg0 model.UpdateUserInput
- if tmp, ok := rawArgs["params"]; ok {
- ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
- arg0, err = ec.unmarshalNUpdateUserInput2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐUpdateUserInput(ctx, tmp)
- if err != nil {
- return nil, err
- }
+ args := map[string]any{}
+ arg0, err := ec.field_Mutation__enable_access_argsParam(ctx, rawArgs)
+ if err != nil {
+ return nil, err
}
- args["params"] = arg0
+ args["param"] = arg0
return args, nil
}
+func (ec *executionContext) field_Mutation__enable_access_argsParam(
+ ctx context.Context,
+ rawArgs map[string]any,
+) (model.UpdateAccessRequest, error) {
+ if _, ok := rawArgs["param"]; !ok {
+ var zeroVal model.UpdateAccessRequest
+ return zeroVal, nil
+ }
-func (ec *executionContext) field_Mutation__update_webhook_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
- var err error
- args := map[string]interface{}{}
- var arg0 model.UpdateWebhookRequest
- if tmp, ok := rawArgs["params"]; ok {
- ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
- arg0, err = ec.unmarshalNUpdateWebhookRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐUpdateWebhookRequest(ctx, tmp)
- if err != nil {
- return nil, err
- }
+ ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("param"))
+ if tmp, ok := rawArgs["param"]; ok {
+ return ec.unmarshalNUpdateAccessRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐUpdateAccessRequest(ctx, tmp)
}
- args["params"] = arg0
- return args, nil
+
+ var zeroVal model.UpdateAccessRequest
+ return zeroVal, nil
}
-func (ec *executionContext) field_Mutation_forgot_password_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
+func (ec *executionContext) field_Mutation__generate_jwt_keys_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
var err error
- args := map[string]interface{}{}
- var arg0 model.ForgotPasswordInput
- if tmp, ok := rawArgs["params"]; ok {
- ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
- arg0, err = ec.unmarshalNForgotPasswordInput2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐForgotPasswordInput(ctx, tmp)
- if err != nil {
- return nil, err
- }
+ args := map[string]any{}
+ arg0, err := ec.field_Mutation__generate_jwt_keys_argsParams(ctx, rawArgs)
+ if err != nil {
+ return nil, err
}
args["params"] = arg0
return args, nil
}
+func (ec *executionContext) field_Mutation__generate_jwt_keys_argsParams(
+ ctx context.Context,
+ rawArgs map[string]any,
+) (model.GenerateJWTKeysRequest, error) {
+ if _, ok := rawArgs["params"]; !ok {
+ var zeroVal model.GenerateJWTKeysRequest
+ return zeroVal, nil
+ }
-func (ec *executionContext) field_Mutation_login_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
- var err error
- args := map[string]interface{}{}
- var arg0 model.LoginInput
+ ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
if tmp, ok := rawArgs["params"]; ok {
- ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
- arg0, err = ec.unmarshalNLoginInput2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐLoginInput(ctx, tmp)
- if err != nil {
- return nil, err
- }
+ return ec.unmarshalNGenerateJWTKeysRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐGenerateJWTKeysRequest(ctx, tmp)
}
- args["params"] = arg0
- return args, nil
+
+ var zeroVal model.GenerateJWTKeysRequest
+ return zeroVal, nil
}
-func (ec *executionContext) field_Mutation_magic_link_login_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
+func (ec *executionContext) field_Mutation__invite_members_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
var err error
- args := map[string]interface{}{}
- var arg0 model.MagicLinkLoginInput
- if tmp, ok := rawArgs["params"]; ok {
- ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
- arg0, err = ec.unmarshalNMagicLinkLoginInput2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐMagicLinkLoginInput(ctx, tmp)
- if err != nil {
- return nil, err
- }
+ args := map[string]any{}
+ arg0, err := ec.field_Mutation__invite_members_argsParams(ctx, rawArgs)
+ if err != nil {
+ return nil, err
}
args["params"] = arg0
return args, nil
}
+func (ec *executionContext) field_Mutation__invite_members_argsParams(
+ ctx context.Context,
+ rawArgs map[string]any,
+) (model.InviteMemberRequest, error) {
+ if _, ok := rawArgs["params"]; !ok {
+ var zeroVal model.InviteMemberRequest
+ return zeroVal, nil
+ }
-func (ec *executionContext) field_Mutation_mobile_login_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
- var err error
- args := map[string]interface{}{}
- var arg0 model.MobileLoginInput
+ ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
if tmp, ok := rawArgs["params"]; ok {
- ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
- arg0, err = ec.unmarshalNMobileLoginInput2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐMobileLoginInput(ctx, tmp)
- if err != nil {
- return nil, err
- }
+ return ec.unmarshalNInviteMemberRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐInviteMemberRequest(ctx, tmp)
}
- args["params"] = arg0
- return args, nil
+
+ var zeroVal model.InviteMemberRequest
+ return zeroVal, nil
}
-func (ec *executionContext) field_Mutation_mobile_signup_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
+func (ec *executionContext) field_Mutation__revoke_access_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
var err error
- args := map[string]interface{}{}
- var arg0 *model.MobileSignUpInput
- if tmp, ok := rawArgs["params"]; ok {
- ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
- arg0, err = ec.unmarshalOMobileSignUpInput2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐMobileSignUpInput(ctx, tmp)
- if err != nil {
- return nil, err
- }
+ args := map[string]any{}
+ arg0, err := ec.field_Mutation__revoke_access_argsParam(ctx, rawArgs)
+ if err != nil {
+ return nil, err
}
- args["params"] = arg0
+ args["param"] = arg0
return args, nil
}
+func (ec *executionContext) field_Mutation__revoke_access_argsParam(
+ ctx context.Context,
+ rawArgs map[string]any,
+) (model.UpdateAccessRequest, error) {
+ if _, ok := rawArgs["param"]; !ok {
+ var zeroVal model.UpdateAccessRequest
+ return zeroVal, nil
+ }
+
+ ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("param"))
+ if tmp, ok := rawArgs["param"]; ok {
+ return ec.unmarshalNUpdateAccessRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐUpdateAccessRequest(ctx, tmp)
+ }
+
+ var zeroVal model.UpdateAccessRequest
+ return zeroVal, nil
+}
-func (ec *executionContext) field_Mutation_resend_otp_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
+func (ec *executionContext) field_Mutation__test_endpoint_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
var err error
- args := map[string]interface{}{}
- var arg0 model.ResendOTPRequest
- if tmp, ok := rawArgs["params"]; ok {
- ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
- arg0, err = ec.unmarshalNResendOTPRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐResendOTPRequest(ctx, tmp)
- if err != nil {
- return nil, err
- }
+ args := map[string]any{}
+ arg0, err := ec.field_Mutation__test_endpoint_argsParams(ctx, rawArgs)
+ if err != nil {
+ return nil, err
}
args["params"] = arg0
return args, nil
}
+func (ec *executionContext) field_Mutation__test_endpoint_argsParams(
+ ctx context.Context,
+ rawArgs map[string]any,
+) (model.TestEndpointRequest, error) {
+ if _, ok := rawArgs["params"]; !ok {
+ var zeroVal model.TestEndpointRequest
+ return zeroVal, nil
+ }
-func (ec *executionContext) field_Mutation_resend_verify_email_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
- var err error
- args := map[string]interface{}{}
- var arg0 model.ResendVerifyEmailInput
+ ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
if tmp, ok := rawArgs["params"]; ok {
- ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
- arg0, err = ec.unmarshalNResendVerifyEmailInput2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐResendVerifyEmailInput(ctx, tmp)
- if err != nil {
- return nil, err
- }
+ return ec.unmarshalNTestEndpointRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐTestEndpointRequest(ctx, tmp)
}
- args["params"] = arg0
- return args, nil
+
+ var zeroVal model.TestEndpointRequest
+ return zeroVal, nil
}
-func (ec *executionContext) field_Mutation_reset_password_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
+func (ec *executionContext) field_Mutation__update_email_template_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
var err error
- args := map[string]interface{}{}
- var arg0 model.ResetPasswordInput
- if tmp, ok := rawArgs["params"]; ok {
- ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
- arg0, err = ec.unmarshalNResetPasswordInput2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐResetPasswordInput(ctx, tmp)
- if err != nil {
- return nil, err
- }
+ args := map[string]any{}
+ arg0, err := ec.field_Mutation__update_email_template_argsParams(ctx, rawArgs)
+ if err != nil {
+ return nil, err
}
args["params"] = arg0
return args, nil
}
+func (ec *executionContext) field_Mutation__update_email_template_argsParams(
+ ctx context.Context,
+ rawArgs map[string]any,
+) (model.UpdateEmailTemplateRequest, error) {
+ if _, ok := rawArgs["params"]; !ok {
+ var zeroVal model.UpdateEmailTemplateRequest
+ return zeroVal, nil
+ }
-func (ec *executionContext) field_Mutation_revoke_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
- var err error
- args := map[string]interface{}{}
- var arg0 model.OAuthRevokeInput
+ ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
if tmp, ok := rawArgs["params"]; ok {
- ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
- arg0, err = ec.unmarshalNOAuthRevokeInput2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐOAuthRevokeInput(ctx, tmp)
- if err != nil {
- return nil, err
- }
+ return ec.unmarshalNUpdateEmailTemplateRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐUpdateEmailTemplateRequest(ctx, tmp)
}
- args["params"] = arg0
- return args, nil
+
+ var zeroVal model.UpdateEmailTemplateRequest
+ return zeroVal, nil
}
-func (ec *executionContext) field_Mutation_signup_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
+func (ec *executionContext) field_Mutation__update_env_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
var err error
- args := map[string]interface{}{}
- var arg0 model.SignUpInput
- if tmp, ok := rawArgs["params"]; ok {
- ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
- arg0, err = ec.unmarshalNSignUpInput2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐSignUpInput(ctx, tmp)
- if err != nil {
- return nil, err
- }
+ args := map[string]any{}
+ arg0, err := ec.field_Mutation__update_env_argsParams(ctx, rawArgs)
+ if err != nil {
+ return nil, err
}
args["params"] = arg0
return args, nil
}
+func (ec *executionContext) field_Mutation__update_env_argsParams(
+ ctx context.Context,
+ rawArgs map[string]any,
+) (model.UpdateEnvRequest, error) {
+ if _, ok := rawArgs["params"]; !ok {
+ var zeroVal model.UpdateEnvRequest
+ return zeroVal, nil
+ }
-func (ec *executionContext) field_Mutation_update_profile_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
- var err error
- args := map[string]interface{}{}
- var arg0 model.UpdateProfileInput
+ ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
if tmp, ok := rawArgs["params"]; ok {
- ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
- arg0, err = ec.unmarshalNUpdateProfileInput2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐUpdateProfileInput(ctx, tmp)
- if err != nil {
- return nil, err
- }
+ return ec.unmarshalNUpdateEnvRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐUpdateEnvRequest(ctx, tmp)
}
- args["params"] = arg0
- return args, nil
+
+ var zeroVal model.UpdateEnvRequest
+ return zeroVal, nil
}
-func (ec *executionContext) field_Mutation_verify_email_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
+func (ec *executionContext) field_Mutation__update_user_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
var err error
- args := map[string]interface{}{}
- var arg0 model.VerifyEmailInput
- if tmp, ok := rawArgs["params"]; ok {
- ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
- arg0, err = ec.unmarshalNVerifyEmailInput2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐVerifyEmailInput(ctx, tmp)
- if err != nil {
- return nil, err
- }
+ args := map[string]any{}
+ arg0, err := ec.field_Mutation__update_user_argsParams(ctx, rawArgs)
+ if err != nil {
+ return nil, err
}
args["params"] = arg0
return args, nil
}
+func (ec *executionContext) field_Mutation__update_user_argsParams(
+ ctx context.Context,
+ rawArgs map[string]any,
+) (model.UpdateUserRequest, error) {
+ if _, ok := rawArgs["params"]; !ok {
+ var zeroVal model.UpdateUserRequest
+ return zeroVal, nil
+ }
-func (ec *executionContext) field_Mutation_verify_otp_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
- var err error
- args := map[string]interface{}{}
- var arg0 model.VerifyOTPRequest
+ ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
if tmp, ok := rawArgs["params"]; ok {
- ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
- arg0, err = ec.unmarshalNVerifyOTPRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐVerifyOTPRequest(ctx, tmp)
- if err != nil {
- return nil, err
- }
+ return ec.unmarshalNUpdateUserRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐUpdateUserRequest(ctx, tmp)
}
- args["params"] = arg0
- return args, nil
+
+ var zeroVal model.UpdateUserRequest
+ return zeroVal, nil
}
-func (ec *executionContext) field_Query___type_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
+func (ec *executionContext) field_Mutation__update_webhook_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
var err error
- args := map[string]interface{}{}
- var arg0 string
- if tmp, ok := rawArgs["name"]; ok {
- ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("name"))
- arg0, err = ec.unmarshalNString2string(ctx, tmp)
- if err != nil {
- return nil, err
- }
+ args := map[string]any{}
+ arg0, err := ec.field_Mutation__update_webhook_argsParams(ctx, rawArgs)
+ if err != nil {
+ return nil, err
}
- args["name"] = arg0
+ args["params"] = arg0
return args, nil
}
+func (ec *executionContext) field_Mutation__update_webhook_argsParams(
+ ctx context.Context,
+ rawArgs map[string]any,
+) (model.UpdateWebhookRequest, error) {
+ if _, ok := rawArgs["params"]; !ok {
+ var zeroVal model.UpdateWebhookRequest
+ return zeroVal, nil
+ }
-func (ec *executionContext) field_Query__email_templates_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
- var err error
- args := map[string]interface{}{}
- var arg0 *model.PaginatedInput
+ ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
if tmp, ok := rawArgs["params"]; ok {
- ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
- arg0, err = ec.unmarshalOPaginatedInput2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐPaginatedInput(ctx, tmp)
- if err != nil {
- return nil, err
- }
+ return ec.unmarshalNUpdateWebhookRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐUpdateWebhookRequest(ctx, tmp)
}
- args["params"] = arg0
- return args, nil
+
+ var zeroVal model.UpdateWebhookRequest
+ return zeroVal, nil
}
-func (ec *executionContext) field_Query__user_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
+func (ec *executionContext) field_Mutation_forgot_password_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
var err error
- args := map[string]interface{}{}
- var arg0 model.GetUserRequest
- if tmp, ok := rawArgs["params"]; ok {
- ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
- arg0, err = ec.unmarshalNGetUserRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐGetUserRequest(ctx, tmp)
- if err != nil {
- return nil, err
- }
+ args := map[string]any{}
+ arg0, err := ec.field_Mutation_forgot_password_argsParams(ctx, rawArgs)
+ if err != nil {
+ return nil, err
}
args["params"] = arg0
return args, nil
}
+func (ec *executionContext) field_Mutation_forgot_password_argsParams(
+ ctx context.Context,
+ rawArgs map[string]any,
+) (model.ForgotPasswordRequest, error) {
+ if _, ok := rawArgs["params"]; !ok {
+ var zeroVal model.ForgotPasswordRequest
+ return zeroVal, nil
+ }
-func (ec *executionContext) field_Query__users_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
- var err error
- args := map[string]interface{}{}
- var arg0 *model.PaginatedInput
+ ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
if tmp, ok := rawArgs["params"]; ok {
- ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
- arg0, err = ec.unmarshalOPaginatedInput2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐPaginatedInput(ctx, tmp)
- if err != nil {
- return nil, err
- }
+ return ec.unmarshalNForgotPasswordRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐForgotPasswordRequest(ctx, tmp)
}
- args["params"] = arg0
- return args, nil
+
+ var zeroVal model.ForgotPasswordRequest
+ return zeroVal, nil
}
-func (ec *executionContext) field_Query__verification_requests_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
+func (ec *executionContext) field_Mutation_login_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
var err error
- args := map[string]interface{}{}
- var arg0 *model.PaginatedInput
- if tmp, ok := rawArgs["params"]; ok {
- ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
- arg0, err = ec.unmarshalOPaginatedInput2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐPaginatedInput(ctx, tmp)
- if err != nil {
- return nil, err
- }
+ args := map[string]any{}
+ arg0, err := ec.field_Mutation_login_argsParams(ctx, rawArgs)
+ if err != nil {
+ return nil, err
}
args["params"] = arg0
return args, nil
}
+func (ec *executionContext) field_Mutation_login_argsParams(
+ ctx context.Context,
+ rawArgs map[string]any,
+) (model.LoginRequest, error) {
+ if _, ok := rawArgs["params"]; !ok {
+ var zeroVal model.LoginRequest
+ return zeroVal, nil
+ }
-func (ec *executionContext) field_Query__webhook_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
- var err error
- args := map[string]interface{}{}
- var arg0 model.WebhookRequest
+ ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
if tmp, ok := rawArgs["params"]; ok {
- ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
- arg0, err = ec.unmarshalNWebhookRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐWebhookRequest(ctx, tmp)
- if err != nil {
- return nil, err
- }
+ return ec.unmarshalNLoginRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐLoginRequest(ctx, tmp)
+ }
+
+ var zeroVal model.LoginRequest
+ return zeroVal, nil
+}
+
+func (ec *executionContext) field_Mutation_magic_link_login_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
+ var err error
+ args := map[string]any{}
+ arg0, err := ec.field_Mutation_magic_link_login_argsParams(ctx, rawArgs)
+ if err != nil {
+ return nil, err
}
args["params"] = arg0
return args, nil
}
+func (ec *executionContext) field_Mutation_magic_link_login_argsParams(
+ ctx context.Context,
+ rawArgs map[string]any,
+) (model.MagicLinkLoginRequest, error) {
+ if _, ok := rawArgs["params"]; !ok {
+ var zeroVal model.MagicLinkLoginRequest
+ return zeroVal, nil
+ }
-func (ec *executionContext) field_Query__webhook_logs_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
- var err error
- args := map[string]interface{}{}
- var arg0 *model.ListWebhookLogRequest
+ ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
if tmp, ok := rawArgs["params"]; ok {
- ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
- arg0, err = ec.unmarshalOListWebhookLogRequest2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐListWebhookLogRequest(ctx, tmp)
- if err != nil {
- return nil, err
- }
+ return ec.unmarshalNMagicLinkLoginRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐMagicLinkLoginRequest(ctx, tmp)
+ }
+
+ var zeroVal model.MagicLinkLoginRequest
+ return zeroVal, nil
+}
+
+func (ec *executionContext) field_Mutation_mobile_login_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
+ var err error
+ args := map[string]any{}
+ arg0, err := ec.field_Mutation_mobile_login_argsParams(ctx, rawArgs)
+ if err != nil {
+ return nil, err
}
args["params"] = arg0
return args, nil
}
+func (ec *executionContext) field_Mutation_mobile_login_argsParams(
+ ctx context.Context,
+ rawArgs map[string]any,
+) (model.MobileLoginRequest, error) {
+ if _, ok := rawArgs["params"]; !ok {
+ var zeroVal model.MobileLoginRequest
+ return zeroVal, nil
+ }
-func (ec *executionContext) field_Query__webhooks_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
- var err error
- args := map[string]interface{}{}
- var arg0 *model.PaginatedInput
+ ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
if tmp, ok := rawArgs["params"]; ok {
- ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
- arg0, err = ec.unmarshalOPaginatedInput2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐPaginatedInput(ctx, tmp)
- if err != nil {
- return nil, err
- }
+ return ec.unmarshalNMobileLoginRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐMobileLoginRequest(ctx, tmp)
+ }
+
+ var zeroVal model.MobileLoginRequest
+ return zeroVal, nil
+}
+
+func (ec *executionContext) field_Mutation_mobile_signup_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
+ var err error
+ args := map[string]any{}
+ arg0, err := ec.field_Mutation_mobile_signup_argsParams(ctx, rawArgs)
+ if err != nil {
+ return nil, err
}
args["params"] = arg0
return args, nil
}
+func (ec *executionContext) field_Mutation_mobile_signup_argsParams(
+ ctx context.Context,
+ rawArgs map[string]any,
+) (*model.MobileSignUpRequest, error) {
+ if _, ok := rawArgs["params"]; !ok {
+ var zeroVal *model.MobileSignUpRequest
+ return zeroVal, nil
+ }
-func (ec *executionContext) field_Query_session_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
- var err error
- args := map[string]interface{}{}
- var arg0 *model.SessionQueryInput
+ ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
if tmp, ok := rawArgs["params"]; ok {
- ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
- arg0, err = ec.unmarshalOSessionQueryInput2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐSessionQueryInput(ctx, tmp)
- if err != nil {
- return nil, err
- }
+ return ec.unmarshalOMobileSignUpRequest2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐMobileSignUpRequest(ctx, tmp)
+ }
+
+ var zeroVal *model.MobileSignUpRequest
+ return zeroVal, nil
+}
+
+func (ec *executionContext) field_Mutation_resend_otp_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
+ var err error
+ args := map[string]any{}
+ arg0, err := ec.field_Mutation_resend_otp_argsParams(ctx, rawArgs)
+ if err != nil {
+ return nil, err
}
args["params"] = arg0
return args, nil
}
+func (ec *executionContext) field_Mutation_resend_otp_argsParams(
+ ctx context.Context,
+ rawArgs map[string]any,
+) (model.ResendOTPRequest, error) {
+ if _, ok := rawArgs["params"]; !ok {
+ var zeroVal model.ResendOTPRequest
+ return zeroVal, nil
+ }
-func (ec *executionContext) field_Query_validate_jwt_token_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
- var err error
- args := map[string]interface{}{}
- var arg0 model.ValidateJWTTokenInput
+ ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
if tmp, ok := rawArgs["params"]; ok {
- ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
- arg0, err = ec.unmarshalNValidateJWTTokenInput2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐValidateJWTTokenInput(ctx, tmp)
- if err != nil {
- return nil, err
- }
+ return ec.unmarshalNResendOTPRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐResendOTPRequest(ctx, tmp)
+ }
+
+ var zeroVal model.ResendOTPRequest
+ return zeroVal, nil
+}
+
+func (ec *executionContext) field_Mutation_resend_verify_email_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
+ var err error
+ args := map[string]any{}
+ arg0, err := ec.field_Mutation_resend_verify_email_argsParams(ctx, rawArgs)
+ if err != nil {
+ return nil, err
}
args["params"] = arg0
return args, nil
}
+func (ec *executionContext) field_Mutation_resend_verify_email_argsParams(
+ ctx context.Context,
+ rawArgs map[string]any,
+) (model.ResendVerifyEmailRequest, error) {
+ if _, ok := rawArgs["params"]; !ok {
+ var zeroVal model.ResendVerifyEmailRequest
+ return zeroVal, nil
+ }
-func (ec *executionContext) field_Query_validate_session_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
- var err error
- args := map[string]interface{}{}
- var arg0 *model.ValidateSessionInput
+ ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
if tmp, ok := rawArgs["params"]; ok {
- ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
- arg0, err = ec.unmarshalOValidateSessionInput2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐValidateSessionInput(ctx, tmp)
- if err != nil {
- return nil, err
- }
+ return ec.unmarshalNResendVerifyEmailRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐResendVerifyEmailRequest(ctx, tmp)
+ }
+
+ var zeroVal model.ResendVerifyEmailRequest
+ return zeroVal, nil
+}
+
+func (ec *executionContext) field_Mutation_reset_password_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
+ var err error
+ args := map[string]any{}
+ arg0, err := ec.field_Mutation_reset_password_argsParams(ctx, rawArgs)
+ if err != nil {
+ return nil, err
}
args["params"] = arg0
return args, nil
}
+func (ec *executionContext) field_Mutation_reset_password_argsParams(
+ ctx context.Context,
+ rawArgs map[string]any,
+) (model.ResetPasswordRequest, error) {
+ if _, ok := rawArgs["params"]; !ok {
+ var zeroVal model.ResetPasswordRequest
+ return zeroVal, nil
+ }
+
+ ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
+ if tmp, ok := rawArgs["params"]; ok {
+ return ec.unmarshalNResetPasswordRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐResetPasswordRequest(ctx, tmp)
+ }
+
+ var zeroVal model.ResetPasswordRequest
+ return zeroVal, nil
+}
-func (ec *executionContext) field___Type_enumValues_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
+func (ec *executionContext) field_Mutation_revoke_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
var err error
- args := map[string]interface{}{}
- var arg0 bool
- if tmp, ok := rawArgs["includeDeprecated"]; ok {
- ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("includeDeprecated"))
- arg0, err = ec.unmarshalOBoolean2bool(ctx, tmp)
- if err != nil {
- return nil, err
- }
+ args := map[string]any{}
+ arg0, err := ec.field_Mutation_revoke_argsParams(ctx, rawArgs)
+ if err != nil {
+ return nil, err
}
- args["includeDeprecated"] = arg0
+ args["params"] = arg0
return args, nil
}
+func (ec *executionContext) field_Mutation_revoke_argsParams(
+ ctx context.Context,
+ rawArgs map[string]any,
+) (model.OAuthRevokeRequest, error) {
+ if _, ok := rawArgs["params"]; !ok {
+ var zeroVal model.OAuthRevokeRequest
+ return zeroVal, nil
+ }
+
+ ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
+ if tmp, ok := rawArgs["params"]; ok {
+ return ec.unmarshalNOAuthRevokeRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐOAuthRevokeRequest(ctx, tmp)
+ }
+
+ var zeroVal model.OAuthRevokeRequest
+ return zeroVal, nil
+}
-func (ec *executionContext) field___Type_fields_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
+func (ec *executionContext) field_Mutation_signup_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
var err error
- args := map[string]interface{}{}
- var arg0 bool
- if tmp, ok := rawArgs["includeDeprecated"]; ok {
- ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("includeDeprecated"))
- arg0, err = ec.unmarshalOBoolean2bool(ctx, tmp)
- if err != nil {
- return nil, err
- }
+ args := map[string]any{}
+ arg0, err := ec.field_Mutation_signup_argsParams(ctx, rawArgs)
+ if err != nil {
+ return nil, err
}
- args["includeDeprecated"] = arg0
+ args["params"] = arg0
return args, nil
}
+func (ec *executionContext) field_Mutation_signup_argsParams(
+ ctx context.Context,
+ rawArgs map[string]any,
+) (model.SignUpRequest, error) {
+ if _, ok := rawArgs["params"]; !ok {
+ var zeroVal model.SignUpRequest
+ return zeroVal, nil
+ }
-// endregion ***************************** args.gotpl *****************************
+ ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
+ if tmp, ok := rawArgs["params"]; ok {
+ return ec.unmarshalNSignUpRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐSignUpRequest(ctx, tmp)
+ }
-// region ************************** directives.gotpl **************************
+ var zeroVal model.SignUpRequest
+ return zeroVal, nil
+}
-// endregion ************************** directives.gotpl **************************
+func (ec *executionContext) field_Mutation_update_profile_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
+ var err error
+ args := map[string]any{}
+ arg0, err := ec.field_Mutation_update_profile_argsParams(ctx, rawArgs)
+ if err != nil {
+ return nil, err
+ }
+ args["params"] = arg0
+ return args, nil
+}
+func (ec *executionContext) field_Mutation_update_profile_argsParams(
+ ctx context.Context,
+ rawArgs map[string]any,
+) (model.UpdateProfileRequest, error) {
+ if _, ok := rawArgs["params"]; !ok {
+ var zeroVal model.UpdateProfileRequest
+ return zeroVal, nil
+ }
-// region **************************** field.gotpl *****************************
+ ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
+ if tmp, ok := rawArgs["params"]; ok {
+ return ec.unmarshalNUpdateProfileRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐUpdateProfileRequest(ctx, tmp)
+ }
-func (ec *executionContext) _AuthResponse_message(ctx context.Context, field graphql.CollectedField, obj *model.AuthResponse) (ret graphql.Marshaler) {
- fc, err := ec.fieldContext_AuthResponse_message(ctx, field)
+ var zeroVal model.UpdateProfileRequest
+ return zeroVal, nil
+}
+
+func (ec *executionContext) field_Mutation_verify_email_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
+ var err error
+ args := map[string]any{}
+ arg0, err := ec.field_Mutation_verify_email_argsParams(ctx, rawArgs)
if err != nil {
- return graphql.Null
+ return nil, err
}
- ctx = graphql.WithFieldContext(ctx, fc)
- defer func() {
- if r := recover(); r != nil {
- ec.Error(ctx, ec.Recover(ctx, r))
- ret = graphql.Null
- }
- }()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
- ctx = rctx // use context from middleware stack in children
- return obj.Message, nil
- })
- if err != nil {
- ec.Error(ctx, err)
- return graphql.Null
+ args["params"] = arg0
+ return args, nil
+}
+func (ec *executionContext) field_Mutation_verify_email_argsParams(
+ ctx context.Context,
+ rawArgs map[string]any,
+) (model.VerifyEmailRequest, error) {
+ if _, ok := rawArgs["params"]; !ok {
+ var zeroVal model.VerifyEmailRequest
+ return zeroVal, nil
}
- if resTmp == nil {
- if !graphql.HasFieldError(ctx, fc) {
- ec.Errorf(ctx, "must not be null")
- }
- return graphql.Null
+
+ ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
+ if tmp, ok := rawArgs["params"]; ok {
+ return ec.unmarshalNVerifyEmailRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐVerifyEmailRequest(ctx, tmp)
}
- res := resTmp.(string)
- fc.Result = res
- return ec.marshalNString2string(ctx, field.Selections, res)
+
+ var zeroVal model.VerifyEmailRequest
+ return zeroVal, nil
}
-func (ec *executionContext) fieldContext_AuthResponse_message(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
- fc = &graphql.FieldContext{
- Object: "AuthResponse",
- Field: field,
- IsMethod: false,
- IsResolver: false,
- Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
- return nil, errors.New("field of type String does not have child fields")
- },
+func (ec *executionContext) field_Mutation_verify_otp_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
+ var err error
+ args := map[string]any{}
+ arg0, err := ec.field_Mutation_verify_otp_argsParams(ctx, rawArgs)
+ if err != nil {
+ return nil, err
}
- return fc, nil
+ args["params"] = arg0
+ return args, nil
}
+func (ec *executionContext) field_Mutation_verify_otp_argsParams(
+ ctx context.Context,
+ rawArgs map[string]any,
+) (model.VerifyOTPRequest, error) {
+ if _, ok := rawArgs["params"]; !ok {
+ var zeroVal model.VerifyOTPRequest
+ return zeroVal, nil
+ }
-func (ec *executionContext) _AuthResponse_should_show_email_otp_screen(ctx context.Context, field graphql.CollectedField, obj *model.AuthResponse) (ret graphql.Marshaler) {
- fc, err := ec.fieldContext_AuthResponse_should_show_email_otp_screen(ctx, field)
- if err != nil {
- return graphql.Null
+ ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
+ if tmp, ok := rawArgs["params"]; ok {
+ return ec.unmarshalNVerifyOTPRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐVerifyOTPRequest(ctx, tmp)
}
- ctx = graphql.WithFieldContext(ctx, fc)
- defer func() {
- if r := recover(); r != nil {
- ec.Error(ctx, ec.Recover(ctx, r))
- ret = graphql.Null
- }
- }()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
- ctx = rctx // use context from middleware stack in children
- return obj.ShouldShowEmailOtpScreen, nil
- })
+
+ var zeroVal model.VerifyOTPRequest
+ return zeroVal, nil
+}
+
+func (ec *executionContext) field_Query___type_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
+ var err error
+ args := map[string]any{}
+ arg0, err := ec.field_Query___type_argsName(ctx, rawArgs)
if err != nil {
- ec.Error(ctx, err)
- return graphql.Null
- }
- if resTmp == nil {
- return graphql.Null
+ return nil, err
}
- res := resTmp.(*bool)
- fc.Result = res
- return ec.marshalOBoolean2ᚖbool(ctx, field.Selections, res)
+ args["name"] = arg0
+ return args, nil
}
+func (ec *executionContext) field_Query___type_argsName(
+ ctx context.Context,
+ rawArgs map[string]any,
+) (string, error) {
+ if _, ok := rawArgs["name"]; !ok {
+ var zeroVal string
+ return zeroVal, nil
+ }
-func (ec *executionContext) fieldContext_AuthResponse_should_show_email_otp_screen(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
- fc = &graphql.FieldContext{
- Object: "AuthResponse",
- Field: field,
- IsMethod: false,
- IsResolver: false,
- Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
- return nil, errors.New("field of type Boolean does not have child fields")
- },
+ ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("name"))
+ if tmp, ok := rawArgs["name"]; ok {
+ return ec.unmarshalNString2string(ctx, tmp)
}
- return fc, nil
+
+ var zeroVal string
+ return zeroVal, nil
}
-func (ec *executionContext) _AuthResponse_should_show_mobile_otp_screen(ctx context.Context, field graphql.CollectedField, obj *model.AuthResponse) (ret graphql.Marshaler) {
- fc, err := ec.fieldContext_AuthResponse_should_show_mobile_otp_screen(ctx, field)
+func (ec *executionContext) field_Query__email_templates_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
+ var err error
+ args := map[string]any{}
+ arg0, err := ec.field_Query__email_templates_argsParams(ctx, rawArgs)
if err != nil {
- return graphql.Null
+ return nil, err
}
- ctx = graphql.WithFieldContext(ctx, fc)
- defer func() {
- if r := recover(); r != nil {
- ec.Error(ctx, ec.Recover(ctx, r))
- ret = graphql.Null
- }
- }()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
- ctx = rctx // use context from middleware stack in children
- return obj.ShouldShowMobileOtpScreen, nil
- })
- if err != nil {
- ec.Error(ctx, err)
- return graphql.Null
+ args["params"] = arg0
+ return args, nil
+}
+func (ec *executionContext) field_Query__email_templates_argsParams(
+ ctx context.Context,
+ rawArgs map[string]any,
+) (*model.PaginatedRequest, error) {
+ if _, ok := rawArgs["params"]; !ok {
+ var zeroVal *model.PaginatedRequest
+ return zeroVal, nil
}
- if resTmp == nil {
- return graphql.Null
+
+ ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
+ if tmp, ok := rawArgs["params"]; ok {
+ return ec.unmarshalOPaginatedRequest2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐPaginatedRequest(ctx, tmp)
}
- res := resTmp.(*bool)
- fc.Result = res
- return ec.marshalOBoolean2ᚖbool(ctx, field.Selections, res)
+
+ var zeroVal *model.PaginatedRequest
+ return zeroVal, nil
}
-func (ec *executionContext) fieldContext_AuthResponse_should_show_mobile_otp_screen(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
- fc = &graphql.FieldContext{
- Object: "AuthResponse",
- Field: field,
- IsMethod: false,
- IsResolver: false,
- Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
- return nil, errors.New("field of type Boolean does not have child fields")
- },
+func (ec *executionContext) field_Query__user_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
+ var err error
+ args := map[string]any{}
+ arg0, err := ec.field_Query__user_argsParams(ctx, rawArgs)
+ if err != nil {
+ return nil, err
}
- return fc, nil
+ args["params"] = arg0
+ return args, nil
}
+func (ec *executionContext) field_Query__user_argsParams(
+ ctx context.Context,
+ rawArgs map[string]any,
+) (model.GetUserRequest, error) {
+ if _, ok := rawArgs["params"]; !ok {
+ var zeroVal model.GetUserRequest
+ return zeroVal, nil
+ }
-func (ec *executionContext) _AuthResponse_should_show_totp_screen(ctx context.Context, field graphql.CollectedField, obj *model.AuthResponse) (ret graphql.Marshaler) {
- fc, err := ec.fieldContext_AuthResponse_should_show_totp_screen(ctx, field)
- if err != nil {
- return graphql.Null
+ ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
+ if tmp, ok := rawArgs["params"]; ok {
+ return ec.unmarshalNGetUserRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐGetUserRequest(ctx, tmp)
+ }
+
+ var zeroVal model.GetUserRequest
+ return zeroVal, nil
+}
+
+func (ec *executionContext) field_Query__users_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
+ var err error
+ args := map[string]any{}
+ arg0, err := ec.field_Query__users_argsParams(ctx, rawArgs)
+ if err != nil {
+ return nil, err
+ }
+ args["params"] = arg0
+ return args, nil
+}
+func (ec *executionContext) field_Query__users_argsParams(
+ ctx context.Context,
+ rawArgs map[string]any,
+) (*model.PaginatedRequest, error) {
+ if _, ok := rawArgs["params"]; !ok {
+ var zeroVal *model.PaginatedRequest
+ return zeroVal, nil
+ }
+
+ ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
+ if tmp, ok := rawArgs["params"]; ok {
+ return ec.unmarshalOPaginatedRequest2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐPaginatedRequest(ctx, tmp)
+ }
+
+ var zeroVal *model.PaginatedRequest
+ return zeroVal, nil
+}
+
+func (ec *executionContext) field_Query__verification_requests_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
+ var err error
+ args := map[string]any{}
+ arg0, err := ec.field_Query__verification_requests_argsParams(ctx, rawArgs)
+ if err != nil {
+ return nil, err
+ }
+ args["params"] = arg0
+ return args, nil
+}
+func (ec *executionContext) field_Query__verification_requests_argsParams(
+ ctx context.Context,
+ rawArgs map[string]any,
+) (*model.PaginatedRequest, error) {
+ if _, ok := rawArgs["params"]; !ok {
+ var zeroVal *model.PaginatedRequest
+ return zeroVal, nil
+ }
+
+ ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
+ if tmp, ok := rawArgs["params"]; ok {
+ return ec.unmarshalOPaginatedRequest2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐPaginatedRequest(ctx, tmp)
+ }
+
+ var zeroVal *model.PaginatedRequest
+ return zeroVal, nil
+}
+
+func (ec *executionContext) field_Query__webhook_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
+ var err error
+ args := map[string]any{}
+ arg0, err := ec.field_Query__webhook_argsParams(ctx, rawArgs)
+ if err != nil {
+ return nil, err
+ }
+ args["params"] = arg0
+ return args, nil
+}
+func (ec *executionContext) field_Query__webhook_argsParams(
+ ctx context.Context,
+ rawArgs map[string]any,
+) (model.WebhookRequest, error) {
+ if _, ok := rawArgs["params"]; !ok {
+ var zeroVal model.WebhookRequest
+ return zeroVal, nil
+ }
+
+ ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
+ if tmp, ok := rawArgs["params"]; ok {
+ return ec.unmarshalNWebhookRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐWebhookRequest(ctx, tmp)
+ }
+
+ var zeroVal model.WebhookRequest
+ return zeroVal, nil
+}
+
+func (ec *executionContext) field_Query__webhook_logs_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
+ var err error
+ args := map[string]any{}
+ arg0, err := ec.field_Query__webhook_logs_argsParams(ctx, rawArgs)
+ if err != nil {
+ return nil, err
+ }
+ args["params"] = arg0
+ return args, nil
+}
+func (ec *executionContext) field_Query__webhook_logs_argsParams(
+ ctx context.Context,
+ rawArgs map[string]any,
+) (*model.ListWebhookLogRequest, error) {
+ if _, ok := rawArgs["params"]; !ok {
+ var zeroVal *model.ListWebhookLogRequest
+ return zeroVal, nil
+ }
+
+ ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
+ if tmp, ok := rawArgs["params"]; ok {
+ return ec.unmarshalOListWebhookLogRequest2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐListWebhookLogRequest(ctx, tmp)
+ }
+
+ var zeroVal *model.ListWebhookLogRequest
+ return zeroVal, nil
+}
+
+func (ec *executionContext) field_Query__webhooks_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
+ var err error
+ args := map[string]any{}
+ arg0, err := ec.field_Query__webhooks_argsParams(ctx, rawArgs)
+ if err != nil {
+ return nil, err
+ }
+ args["params"] = arg0
+ return args, nil
+}
+func (ec *executionContext) field_Query__webhooks_argsParams(
+ ctx context.Context,
+ rawArgs map[string]any,
+) (*model.PaginatedRequest, error) {
+ if _, ok := rawArgs["params"]; !ok {
+ var zeroVal *model.PaginatedRequest
+ return zeroVal, nil
+ }
+
+ ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
+ if tmp, ok := rawArgs["params"]; ok {
+ return ec.unmarshalOPaginatedRequest2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐPaginatedRequest(ctx, tmp)
+ }
+
+ var zeroVal *model.PaginatedRequest
+ return zeroVal, nil
+}
+
+func (ec *executionContext) field_Query_session_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
+ var err error
+ args := map[string]any{}
+ arg0, err := ec.field_Query_session_argsParams(ctx, rawArgs)
+ if err != nil {
+ return nil, err
+ }
+ args["params"] = arg0
+ return args, nil
+}
+func (ec *executionContext) field_Query_session_argsParams(
+ ctx context.Context,
+ rawArgs map[string]any,
+) (*model.SessionQueryRequest, error) {
+ if _, ok := rawArgs["params"]; !ok {
+ var zeroVal *model.SessionQueryRequest
+ return zeroVal, nil
+ }
+
+ ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
+ if tmp, ok := rawArgs["params"]; ok {
+ return ec.unmarshalOSessionQueryRequest2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐSessionQueryRequest(ctx, tmp)
+ }
+
+ var zeroVal *model.SessionQueryRequest
+ return zeroVal, nil
+}
+
+func (ec *executionContext) field_Query_validate_jwt_token_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
+ var err error
+ args := map[string]any{}
+ arg0, err := ec.field_Query_validate_jwt_token_argsParams(ctx, rawArgs)
+ if err != nil {
+ return nil, err
+ }
+ args["params"] = arg0
+ return args, nil
+}
+func (ec *executionContext) field_Query_validate_jwt_token_argsParams(
+ ctx context.Context,
+ rawArgs map[string]any,
+) (model.ValidateJWTTokenRequest, error) {
+ if _, ok := rawArgs["params"]; !ok {
+ var zeroVal model.ValidateJWTTokenRequest
+ return zeroVal, nil
+ }
+
+ ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
+ if tmp, ok := rawArgs["params"]; ok {
+ return ec.unmarshalNValidateJWTTokenRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐValidateJWTTokenRequest(ctx, tmp)
+ }
+
+ var zeroVal model.ValidateJWTTokenRequest
+ return zeroVal, nil
+}
+
+func (ec *executionContext) field_Query_validate_session_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
+ var err error
+ args := map[string]any{}
+ arg0, err := ec.field_Query_validate_session_argsParams(ctx, rawArgs)
+ if err != nil {
+ return nil, err
+ }
+ args["params"] = arg0
+ return args, nil
+}
+func (ec *executionContext) field_Query_validate_session_argsParams(
+ ctx context.Context,
+ rawArgs map[string]any,
+) (*model.ValidateSessionRequest, error) {
+ if _, ok := rawArgs["params"]; !ok {
+ var zeroVal *model.ValidateSessionRequest
+ return zeroVal, nil
+ }
+
+ ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
+ if tmp, ok := rawArgs["params"]; ok {
+ return ec.unmarshalOValidateSessionRequest2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐValidateSessionRequest(ctx, tmp)
+ }
+
+ var zeroVal *model.ValidateSessionRequest
+ return zeroVal, nil
+}
+
+func (ec *executionContext) field___Directive_args_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
+ var err error
+ args := map[string]any{}
+ arg0, err := ec.field___Directive_args_argsIncludeDeprecated(ctx, rawArgs)
+ if err != nil {
+ return nil, err
+ }
+ args["includeDeprecated"] = arg0
+ return args, nil
+}
+func (ec *executionContext) field___Directive_args_argsIncludeDeprecated(
+ ctx context.Context,
+ rawArgs map[string]any,
+) (*bool, error) {
+ if _, ok := rawArgs["includeDeprecated"]; !ok {
+ var zeroVal *bool
+ return zeroVal, nil
+ }
+
+ ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("includeDeprecated"))
+ if tmp, ok := rawArgs["includeDeprecated"]; ok {
+ return ec.unmarshalOBoolean2ᚖbool(ctx, tmp)
+ }
+
+ var zeroVal *bool
+ return zeroVal, nil
+}
+
+func (ec *executionContext) field___Field_args_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
+ var err error
+ args := map[string]any{}
+ arg0, err := ec.field___Field_args_argsIncludeDeprecated(ctx, rawArgs)
+ if err != nil {
+ return nil, err
+ }
+ args["includeDeprecated"] = arg0
+ return args, nil
+}
+func (ec *executionContext) field___Field_args_argsIncludeDeprecated(
+ ctx context.Context,
+ rawArgs map[string]any,
+) (*bool, error) {
+ if _, ok := rawArgs["includeDeprecated"]; !ok {
+ var zeroVal *bool
+ return zeroVal, nil
+ }
+
+ ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("includeDeprecated"))
+ if tmp, ok := rawArgs["includeDeprecated"]; ok {
+ return ec.unmarshalOBoolean2ᚖbool(ctx, tmp)
+ }
+
+ var zeroVal *bool
+ return zeroVal, nil
+}
+
+func (ec *executionContext) field___Type_enumValues_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
+ var err error
+ args := map[string]any{}
+ arg0, err := ec.field___Type_enumValues_argsIncludeDeprecated(ctx, rawArgs)
+ if err != nil {
+ return nil, err
+ }
+ args["includeDeprecated"] = arg0
+ return args, nil
+}
+func (ec *executionContext) field___Type_enumValues_argsIncludeDeprecated(
+ ctx context.Context,
+ rawArgs map[string]any,
+) (bool, error) {
+ if _, ok := rawArgs["includeDeprecated"]; !ok {
+ var zeroVal bool
+ return zeroVal, nil
+ }
+
+ ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("includeDeprecated"))
+ if tmp, ok := rawArgs["includeDeprecated"]; ok {
+ return ec.unmarshalOBoolean2bool(ctx, tmp)
+ }
+
+ var zeroVal bool
+ return zeroVal, nil
+}
+
+func (ec *executionContext) field___Type_fields_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
+ var err error
+ args := map[string]any{}
+ arg0, err := ec.field___Type_fields_argsIncludeDeprecated(ctx, rawArgs)
+ if err != nil {
+ return nil, err
+ }
+ args["includeDeprecated"] = arg0
+ return args, nil
+}
+func (ec *executionContext) field___Type_fields_argsIncludeDeprecated(
+ ctx context.Context,
+ rawArgs map[string]any,
+) (bool, error) {
+ if _, ok := rawArgs["includeDeprecated"]; !ok {
+ var zeroVal bool
+ return zeroVal, nil
+ }
+
+ ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("includeDeprecated"))
+ if tmp, ok := rawArgs["includeDeprecated"]; ok {
+ return ec.unmarshalOBoolean2bool(ctx, tmp)
+ }
+
+ var zeroVal bool
+ return zeroVal, nil
+}
+
+// endregion ***************************** args.gotpl *****************************
+
+// region ************************** directives.gotpl **************************
+
+// endregion ************************** directives.gotpl **************************
+
+// region **************************** field.gotpl *****************************
+
+func (ec *executionContext) _AuthResponse_message(ctx context.Context, field graphql.CollectedField, obj *model.AuthResponse) (ret graphql.Marshaler) {
+ fc, err := ec.fieldContext_AuthResponse_message(ctx, field)
+ if err != nil {
+ return graphql.Null
}
ctx = graphql.WithFieldContext(ctx, fc)
defer func() {
@@ -3873,37 +4293,40 @@ func (ec *executionContext) _AuthResponse_should_show_totp_screen(ctx context.Co
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
- return obj.ShouldShowTotpScreen, nil
+ return obj.Message, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
+ if !graphql.HasFieldError(ctx, fc) {
+ ec.Errorf(ctx, "must not be null")
+ }
return graphql.Null
}
- res := resTmp.(*bool)
+ res := resTmp.(string)
fc.Result = res
- return ec.marshalOBoolean2ᚖbool(ctx, field.Selections, res)
+ return ec.marshalNString2string(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_AuthResponse_should_show_totp_screen(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_AuthResponse_message(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "AuthResponse",
Field: field,
IsMethod: false,
IsResolver: false,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
- return nil, errors.New("field of type Boolean does not have child fields")
+ return nil, errors.New("field of type String does not have child fields")
},
}
return fc, nil
}
-func (ec *executionContext) _AuthResponse_access_token(ctx context.Context, field graphql.CollectedField, obj *model.AuthResponse) (ret graphql.Marshaler) {
- fc, err := ec.fieldContext_AuthResponse_access_token(ctx, field)
+func (ec *executionContext) _AuthResponse_should_show_email_otp_screen(ctx context.Context, field graphql.CollectedField, obj *model.AuthResponse) (ret graphql.Marshaler) {
+ fc, err := ec.fieldContext_AuthResponse_should_show_email_otp_screen(ctx, field)
if err != nil {
return graphql.Null
}
@@ -3914,9 +4337,9 @@ func (ec *executionContext) _AuthResponse_access_token(ctx context.Context, fiel
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
- return obj.AccessToken, nil
+ return obj.ShouldShowEmailOtpScreen, nil
})
if err != nil {
ec.Error(ctx, err)
@@ -3925,26 +4348,26 @@ func (ec *executionContext) _AuthResponse_access_token(ctx context.Context, fiel
if resTmp == nil {
return graphql.Null
}
- res := resTmp.(*string)
+ res := resTmp.(*bool)
fc.Result = res
- return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
+ return ec.marshalOBoolean2ᚖbool(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_AuthResponse_access_token(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_AuthResponse_should_show_email_otp_screen(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "AuthResponse",
Field: field,
IsMethod: false,
IsResolver: false,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
- return nil, errors.New("field of type String does not have child fields")
+ return nil, errors.New("field of type Boolean does not have child fields")
},
}
return fc, nil
}
-func (ec *executionContext) _AuthResponse_id_token(ctx context.Context, field graphql.CollectedField, obj *model.AuthResponse) (ret graphql.Marshaler) {
- fc, err := ec.fieldContext_AuthResponse_id_token(ctx, field)
+func (ec *executionContext) _AuthResponse_should_show_mobile_otp_screen(ctx context.Context, field graphql.CollectedField, obj *model.AuthResponse) (ret graphql.Marshaler) {
+ fc, err := ec.fieldContext_AuthResponse_should_show_mobile_otp_screen(ctx, field)
if err != nil {
return graphql.Null
}
@@ -3955,9 +4378,9 @@ func (ec *executionContext) _AuthResponse_id_token(ctx context.Context, field gr
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
- return obj.IDToken, nil
+ return obj.ShouldShowMobileOtpScreen, nil
})
if err != nil {
ec.Error(ctx, err)
@@ -3966,26 +4389,26 @@ func (ec *executionContext) _AuthResponse_id_token(ctx context.Context, field gr
if resTmp == nil {
return graphql.Null
}
- res := resTmp.(*string)
+ res := resTmp.(*bool)
fc.Result = res
- return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
+ return ec.marshalOBoolean2ᚖbool(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_AuthResponse_id_token(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_AuthResponse_should_show_mobile_otp_screen(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "AuthResponse",
Field: field,
IsMethod: false,
IsResolver: false,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
- return nil, errors.New("field of type String does not have child fields")
+ return nil, errors.New("field of type Boolean does not have child fields")
},
}
return fc, nil
}
-func (ec *executionContext) _AuthResponse_refresh_token(ctx context.Context, field graphql.CollectedField, obj *model.AuthResponse) (ret graphql.Marshaler) {
- fc, err := ec.fieldContext_AuthResponse_refresh_token(ctx, field)
+func (ec *executionContext) _AuthResponse_should_show_totp_screen(ctx context.Context, field graphql.CollectedField, obj *model.AuthResponse) (ret graphql.Marshaler) {
+ fc, err := ec.fieldContext_AuthResponse_should_show_totp_screen(ctx, field)
if err != nil {
return graphql.Null
}
@@ -3996,9 +4419,9 @@ func (ec *executionContext) _AuthResponse_refresh_token(ctx context.Context, fie
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
- return obj.RefreshToken, nil
+ return obj.ShouldShowTotpScreen, nil
})
if err != nil {
ec.Error(ctx, err)
@@ -4007,26 +4430,26 @@ func (ec *executionContext) _AuthResponse_refresh_token(ctx context.Context, fie
if resTmp == nil {
return graphql.Null
}
- res := resTmp.(*string)
+ res := resTmp.(*bool)
fc.Result = res
- return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
+ return ec.marshalOBoolean2ᚖbool(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_AuthResponse_refresh_token(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_AuthResponse_should_show_totp_screen(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "AuthResponse",
Field: field,
IsMethod: false,
IsResolver: false,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
- return nil, errors.New("field of type String does not have child fields")
+ return nil, errors.New("field of type Boolean does not have child fields")
},
}
return fc, nil
}
-func (ec *executionContext) _AuthResponse_expires_in(ctx context.Context, field graphql.CollectedField, obj *model.AuthResponse) (ret graphql.Marshaler) {
- fc, err := ec.fieldContext_AuthResponse_expires_in(ctx, field)
+func (ec *executionContext) _AuthResponse_access_token(ctx context.Context, field graphql.CollectedField, obj *model.AuthResponse) (ret graphql.Marshaler) {
+ fc, err := ec.fieldContext_AuthResponse_access_token(ctx, field)
if err != nil {
return graphql.Null
}
@@ -4037,9 +4460,9 @@ func (ec *executionContext) _AuthResponse_expires_in(ctx context.Context, field
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
- return obj.ExpiresIn, nil
+ return obj.AccessToken, nil
})
if err != nil {
ec.Error(ctx, err)
@@ -4048,26 +4471,26 @@ func (ec *executionContext) _AuthResponse_expires_in(ctx context.Context, field
if resTmp == nil {
return graphql.Null
}
- res := resTmp.(*int64)
+ res := resTmp.(*string)
fc.Result = res
- return ec.marshalOInt642ᚖint64(ctx, field.Selections, res)
+ return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_AuthResponse_expires_in(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_AuthResponse_access_token(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "AuthResponse",
Field: field,
IsMethod: false,
IsResolver: false,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
- return nil, errors.New("field of type Int64 does not have child fields")
+ return nil, errors.New("field of type String does not have child fields")
},
}
return fc, nil
}
-func (ec *executionContext) _AuthResponse_user(ctx context.Context, field graphql.CollectedField, obj *model.AuthResponse) (ret graphql.Marshaler) {
- fc, err := ec.fieldContext_AuthResponse_user(ctx, field)
+func (ec *executionContext) _AuthResponse_id_token(ctx context.Context, field graphql.CollectedField, obj *model.AuthResponse) (ret graphql.Marshaler) {
+ fc, err := ec.fieldContext_AuthResponse_id_token(ctx, field)
if err != nil {
return graphql.Null
}
@@ -4078,9 +4501,9 @@ func (ec *executionContext) _AuthResponse_user(ctx context.Context, field graphq
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
- return obj.User, nil
+ return obj.IDToken, nil
})
if err != nil {
ec.Error(ctx, err)
@@ -4089,34 +4512,157 @@ func (ec *executionContext) _AuthResponse_user(ctx context.Context, field graphq
if resTmp == nil {
return graphql.Null
}
- res := resTmp.(*model.User)
+ res := resTmp.(*string)
fc.Result = res
- return ec.marshalOUser2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐUser(ctx, field.Selections, res)
+ return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_AuthResponse_user(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_AuthResponse_id_token(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "AuthResponse",
Field: field,
IsMethod: false,
IsResolver: false,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
- switch field.Name {
- case "id":
- return ec.fieldContext_User_id(ctx, field)
- case "email":
- return ec.fieldContext_User_email(ctx, field)
- case "email_verified":
- return ec.fieldContext_User_email_verified(ctx, field)
- case "signup_methods":
- return ec.fieldContext_User_signup_methods(ctx, field)
- case "given_name":
- return ec.fieldContext_User_given_name(ctx, field)
- case "family_name":
- return ec.fieldContext_User_family_name(ctx, field)
- case "middle_name":
- return ec.fieldContext_User_middle_name(ctx, field)
- case "nickname":
+ return nil, errors.New("field of type String does not have child fields")
+ },
+ }
+ return fc, nil
+}
+
+func (ec *executionContext) _AuthResponse_refresh_token(ctx context.Context, field graphql.CollectedField, obj *model.AuthResponse) (ret graphql.Marshaler) {
+ fc, err := ec.fieldContext_AuthResponse_refresh_token(ctx, field)
+ if err != nil {
+ return graphql.Null
+ }
+ ctx = graphql.WithFieldContext(ctx, fc)
+ defer func() {
+ if r := recover(); r != nil {
+ ec.Error(ctx, ec.Recover(ctx, r))
+ ret = graphql.Null
+ }
+ }()
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
+ ctx = rctx // use context from middleware stack in children
+ return obj.RefreshToken, nil
+ })
+ if err != nil {
+ ec.Error(ctx, err)
+ return graphql.Null
+ }
+ if resTmp == nil {
+ return graphql.Null
+ }
+ res := resTmp.(*string)
+ fc.Result = res
+ return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
+}
+
+func (ec *executionContext) fieldContext_AuthResponse_refresh_token(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+ fc = &graphql.FieldContext{
+ Object: "AuthResponse",
+ Field: field,
+ IsMethod: false,
+ IsResolver: false,
+ Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
+ return nil, errors.New("field of type String does not have child fields")
+ },
+ }
+ return fc, nil
+}
+
+func (ec *executionContext) _AuthResponse_expires_in(ctx context.Context, field graphql.CollectedField, obj *model.AuthResponse) (ret graphql.Marshaler) {
+ fc, err := ec.fieldContext_AuthResponse_expires_in(ctx, field)
+ if err != nil {
+ return graphql.Null
+ }
+ ctx = graphql.WithFieldContext(ctx, fc)
+ defer func() {
+ if r := recover(); r != nil {
+ ec.Error(ctx, ec.Recover(ctx, r))
+ ret = graphql.Null
+ }
+ }()
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
+ ctx = rctx // use context from middleware stack in children
+ return obj.ExpiresIn, nil
+ })
+ if err != nil {
+ ec.Error(ctx, err)
+ return graphql.Null
+ }
+ if resTmp == nil {
+ return graphql.Null
+ }
+ res := resTmp.(*int64)
+ fc.Result = res
+ return ec.marshalOInt642ᚖint64(ctx, field.Selections, res)
+}
+
+func (ec *executionContext) fieldContext_AuthResponse_expires_in(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+ fc = &graphql.FieldContext{
+ Object: "AuthResponse",
+ Field: field,
+ IsMethod: false,
+ IsResolver: false,
+ Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
+ return nil, errors.New("field of type Int64 does not have child fields")
+ },
+ }
+ return fc, nil
+}
+
+func (ec *executionContext) _AuthResponse_user(ctx context.Context, field graphql.CollectedField, obj *model.AuthResponse) (ret graphql.Marshaler) {
+ fc, err := ec.fieldContext_AuthResponse_user(ctx, field)
+ if err != nil {
+ return graphql.Null
+ }
+ ctx = graphql.WithFieldContext(ctx, fc)
+ defer func() {
+ if r := recover(); r != nil {
+ ec.Error(ctx, ec.Recover(ctx, r))
+ ret = graphql.Null
+ }
+ }()
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
+ ctx = rctx // use context from middleware stack in children
+ return obj.User, nil
+ })
+ if err != nil {
+ ec.Error(ctx, err)
+ return graphql.Null
+ }
+ if resTmp == nil {
+ return graphql.Null
+ }
+ res := resTmp.(*model.User)
+ fc.Result = res
+ return ec.marshalOUser2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐUser(ctx, field.Selections, res)
+}
+
+func (ec *executionContext) fieldContext_AuthResponse_user(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+ fc = &graphql.FieldContext{
+ Object: "AuthResponse",
+ Field: field,
+ IsMethod: false,
+ IsResolver: false,
+ Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
+ switch field.Name {
+ case "id":
+ return ec.fieldContext_User_id(ctx, field)
+ case "email":
+ return ec.fieldContext_User_email(ctx, field)
+ case "email_verified":
+ return ec.fieldContext_User_email_verified(ctx, field)
+ case "signup_methods":
+ return ec.fieldContext_User_signup_methods(ctx, field)
+ case "given_name":
+ return ec.fieldContext_User_given_name(ctx, field)
+ case "family_name":
+ return ec.fieldContext_User_family_name(ctx, field)
+ case "middle_name":
+ return ec.fieldContext_User_middle_name(ctx, field)
+ case "nickname":
return ec.fieldContext_User_nickname(ctx, field)
case "preferred_username":
return ec.fieldContext_User_preferred_username(ctx, field)
@@ -4161,7 +4707,7 @@ func (ec *executionContext) _AuthResponse_authenticator_scanner_image(ctx contex
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.AuthenticatorScannerImage, nil
})
@@ -4177,7 +4723,7 @@ func (ec *executionContext) _AuthResponse_authenticator_scanner_image(ctx contex
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_AuthResponse_authenticator_scanner_image(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_AuthResponse_authenticator_scanner_image(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "AuthResponse",
Field: field,
@@ -4202,7 +4748,7 @@ func (ec *executionContext) _AuthResponse_authenticator_secret(ctx context.Conte
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.AuthenticatorSecret, nil
})
@@ -4218,7 +4764,7 @@ func (ec *executionContext) _AuthResponse_authenticator_secret(ctx context.Conte
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_AuthResponse_authenticator_secret(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_AuthResponse_authenticator_secret(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "AuthResponse",
Field: field,
@@ -4243,7 +4789,7 @@ func (ec *executionContext) _AuthResponse_authenticator_recovery_codes(ctx conte
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.AuthenticatorRecoveryCodes, nil
})
@@ -4259,7 +4805,7 @@ func (ec *executionContext) _AuthResponse_authenticator_recovery_codes(ctx conte
return ec.marshalOString2ᚕᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_AuthResponse_authenticator_recovery_codes(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_AuthResponse_authenticator_recovery_codes(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "AuthResponse",
Field: field,
@@ -4284,7 +4830,7 @@ func (ec *executionContext) _EmailTemplate_id(ctx context.Context, field graphql
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.ID, nil
})
@@ -4303,7 +4849,7 @@ func (ec *executionContext) _EmailTemplate_id(ctx context.Context, field graphql
return ec.marshalNID2string(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_EmailTemplate_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_EmailTemplate_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "EmailTemplate",
Field: field,
@@ -4328,7 +4874,7 @@ func (ec *executionContext) _EmailTemplate_event_name(ctx context.Context, field
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.EventName, nil
})
@@ -4347,7 +4893,7 @@ func (ec *executionContext) _EmailTemplate_event_name(ctx context.Context, field
return ec.marshalNString2string(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_EmailTemplate_event_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_EmailTemplate_event_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "EmailTemplate",
Field: field,
@@ -4372,7 +4918,7 @@ func (ec *executionContext) _EmailTemplate_template(ctx context.Context, field g
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Template, nil
})
@@ -4391,7 +4937,7 @@ func (ec *executionContext) _EmailTemplate_template(ctx context.Context, field g
return ec.marshalNString2string(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_EmailTemplate_template(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_EmailTemplate_template(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "EmailTemplate",
Field: field,
@@ -4416,7 +4962,7 @@ func (ec *executionContext) _EmailTemplate_design(ctx context.Context, field gra
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Design, nil
})
@@ -4435,7 +4981,7 @@ func (ec *executionContext) _EmailTemplate_design(ctx context.Context, field gra
return ec.marshalNString2string(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_EmailTemplate_design(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_EmailTemplate_design(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "EmailTemplate",
Field: field,
@@ -4460,7 +5006,7 @@ func (ec *executionContext) _EmailTemplate_subject(ctx context.Context, field gr
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Subject, nil
})
@@ -4479,7 +5025,7 @@ func (ec *executionContext) _EmailTemplate_subject(ctx context.Context, field gr
return ec.marshalNString2string(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_EmailTemplate_subject(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_EmailTemplate_subject(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "EmailTemplate",
Field: field,
@@ -4504,7 +5050,7 @@ func (ec *executionContext) _EmailTemplate_created_at(ctx context.Context, field
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.CreatedAt, nil
})
@@ -4520,7 +5066,7 @@ func (ec *executionContext) _EmailTemplate_created_at(ctx context.Context, field
return ec.marshalOInt642ᚖint64(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_EmailTemplate_created_at(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_EmailTemplate_created_at(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "EmailTemplate",
Field: field,
@@ -4545,7 +5091,7 @@ func (ec *executionContext) _EmailTemplate_updated_at(ctx context.Context, field
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.UpdatedAt, nil
})
@@ -4561,7 +5107,7 @@ func (ec *executionContext) _EmailTemplate_updated_at(ctx context.Context, field
return ec.marshalOInt642ᚖint64(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_EmailTemplate_updated_at(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_EmailTemplate_updated_at(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "EmailTemplate",
Field: field,
@@ -4586,7 +5132,7 @@ func (ec *executionContext) _EmailTemplates_pagination(ctx context.Context, fiel
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Pagination, nil
})
@@ -4602,10 +5148,10 @@ func (ec *executionContext) _EmailTemplates_pagination(ctx context.Context, fiel
}
res := resTmp.(*model.Pagination)
fc.Result = res
- return ec.marshalNPagination2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐPagination(ctx, field.Selections, res)
+ return ec.marshalNPagination2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐPagination(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_EmailTemplates_pagination(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_EmailTemplates_pagination(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "EmailTemplates",
Field: field,
@@ -4640,7 +5186,7 @@ func (ec *executionContext) _EmailTemplates_email_templates(ctx context.Context,
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.EmailTemplates, nil
})
@@ -4656,10 +5202,10 @@ func (ec *executionContext) _EmailTemplates_email_templates(ctx context.Context,
}
res := resTmp.([]*model.EmailTemplate)
fc.Result = res
- return ec.marshalNEmailTemplate2ᚕᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐEmailTemplateᚄ(ctx, field.Selections, res)
+ return ec.marshalNEmailTemplate2ᚕᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐEmailTemplateᚄ(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_EmailTemplates_email_templates(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_EmailTemplates_email_templates(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "EmailTemplates",
Field: field,
@@ -4700,7 +5246,7 @@ func (ec *executionContext) _Env_ACCESS_TOKEN_EXPIRY_TIME(ctx context.Context, f
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.AccessTokenExpiryTime, nil
})
@@ -4716,7 +5262,7 @@ func (ec *executionContext) _Env_ACCESS_TOKEN_EXPIRY_TIME(ctx context.Context, f
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_ACCESS_TOKEN_EXPIRY_TIME(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_ACCESS_TOKEN_EXPIRY_TIME(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -4741,7 +5287,7 @@ func (ec *executionContext) _Env_ADMIN_SECRET(ctx context.Context, field graphql
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.AdminSecret, nil
})
@@ -4757,7 +5303,7 @@ func (ec *executionContext) _Env_ADMIN_SECRET(ctx context.Context, field graphql
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_ADMIN_SECRET(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_ADMIN_SECRET(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -4782,7 +5328,7 @@ func (ec *executionContext) _Env_DATABASE_NAME(ctx context.Context, field graphq
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.DatabaseName, nil
})
@@ -4798,7 +5344,7 @@ func (ec *executionContext) _Env_DATABASE_NAME(ctx context.Context, field graphq
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_DATABASE_NAME(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_DATABASE_NAME(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -4823,7 +5369,7 @@ func (ec *executionContext) _Env_DATABASE_URL(ctx context.Context, field graphql
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.DatabaseURL, nil
})
@@ -4839,7 +5385,7 @@ func (ec *executionContext) _Env_DATABASE_URL(ctx context.Context, field graphql
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_DATABASE_URL(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_DATABASE_URL(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -4864,7 +5410,7 @@ func (ec *executionContext) _Env_DATABASE_TYPE(ctx context.Context, field graphq
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.DatabaseType, nil
})
@@ -4880,7 +5426,7 @@ func (ec *executionContext) _Env_DATABASE_TYPE(ctx context.Context, field graphq
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_DATABASE_TYPE(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_DATABASE_TYPE(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -4905,7 +5451,7 @@ func (ec *executionContext) _Env_DATABASE_USERNAME(ctx context.Context, field gr
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.DatabaseUsername, nil
})
@@ -4921,7 +5467,7 @@ func (ec *executionContext) _Env_DATABASE_USERNAME(ctx context.Context, field gr
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_DATABASE_USERNAME(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_DATABASE_USERNAME(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -4946,7 +5492,7 @@ func (ec *executionContext) _Env_DATABASE_PASSWORD(ctx context.Context, field gr
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.DatabasePassword, nil
})
@@ -4962,7 +5508,7 @@ func (ec *executionContext) _Env_DATABASE_PASSWORD(ctx context.Context, field gr
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_DATABASE_PASSWORD(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_DATABASE_PASSWORD(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -4987,7 +5533,7 @@ func (ec *executionContext) _Env_DATABASE_HOST(ctx context.Context, field graphq
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.DatabaseHost, nil
})
@@ -5003,7 +5549,7 @@ func (ec *executionContext) _Env_DATABASE_HOST(ctx context.Context, field graphq
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_DATABASE_HOST(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_DATABASE_HOST(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -5028,7 +5574,7 @@ func (ec *executionContext) _Env_DATABASE_PORT(ctx context.Context, field graphq
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.DatabasePort, nil
})
@@ -5044,7 +5590,7 @@ func (ec *executionContext) _Env_DATABASE_PORT(ctx context.Context, field graphq
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_DATABASE_PORT(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_DATABASE_PORT(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -5069,7 +5615,7 @@ func (ec *executionContext) _Env_CLIENT_ID(ctx context.Context, field graphql.Co
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.ClientID, nil
})
@@ -5088,7 +5634,7 @@ func (ec *executionContext) _Env_CLIENT_ID(ctx context.Context, field graphql.Co
return ec.marshalNString2string(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_CLIENT_ID(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_CLIENT_ID(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -5113,7 +5659,7 @@ func (ec *executionContext) _Env_CLIENT_SECRET(ctx context.Context, field graphq
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.ClientSecret, nil
})
@@ -5132,7 +5678,7 @@ func (ec *executionContext) _Env_CLIENT_SECRET(ctx context.Context, field graphq
return ec.marshalNString2string(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_CLIENT_SECRET(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_CLIENT_SECRET(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -5157,7 +5703,7 @@ func (ec *executionContext) _Env_CUSTOM_ACCESS_TOKEN_SCRIPT(ctx context.Context,
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.CustomAccessTokenScript, nil
})
@@ -5173,7 +5719,7 @@ func (ec *executionContext) _Env_CUSTOM_ACCESS_TOKEN_SCRIPT(ctx context.Context,
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_CUSTOM_ACCESS_TOKEN_SCRIPT(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_CUSTOM_ACCESS_TOKEN_SCRIPT(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -5198,7 +5744,7 @@ func (ec *executionContext) _Env_SMTP_HOST(ctx context.Context, field graphql.Co
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.SMTPHost, nil
})
@@ -5214,7 +5760,7 @@ func (ec *executionContext) _Env_SMTP_HOST(ctx context.Context, field graphql.Co
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_SMTP_HOST(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_SMTP_HOST(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -5239,7 +5785,7 @@ func (ec *executionContext) _Env_SMTP_PORT(ctx context.Context, field graphql.Co
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.SMTPPort, nil
})
@@ -5255,7 +5801,7 @@ func (ec *executionContext) _Env_SMTP_PORT(ctx context.Context, field graphql.Co
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_SMTP_PORT(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_SMTP_PORT(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -5280,7 +5826,7 @@ func (ec *executionContext) _Env_SMTP_USERNAME(ctx context.Context, field graphq
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.SMTPUsername, nil
})
@@ -5296,7 +5842,7 @@ func (ec *executionContext) _Env_SMTP_USERNAME(ctx context.Context, field graphq
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_SMTP_USERNAME(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_SMTP_USERNAME(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -5321,7 +5867,7 @@ func (ec *executionContext) _Env_SMTP_PASSWORD(ctx context.Context, field graphq
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.SMTPPassword, nil
})
@@ -5337,7 +5883,7 @@ func (ec *executionContext) _Env_SMTP_PASSWORD(ctx context.Context, field graphq
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_SMTP_PASSWORD(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_SMTP_PASSWORD(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -5362,7 +5908,7 @@ func (ec *executionContext) _Env_SMTP_LOCAL_NAME(ctx context.Context, field grap
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.SMTPLocalName, nil
})
@@ -5378,7 +5924,7 @@ func (ec *executionContext) _Env_SMTP_LOCAL_NAME(ctx context.Context, field grap
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_SMTP_LOCAL_NAME(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_SMTP_LOCAL_NAME(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -5403,7 +5949,7 @@ func (ec *executionContext) _Env_SENDER_EMAIL(ctx context.Context, field graphql
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.SenderEmail, nil
})
@@ -5419,7 +5965,7 @@ func (ec *executionContext) _Env_SENDER_EMAIL(ctx context.Context, field graphql
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_SENDER_EMAIL(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_SENDER_EMAIL(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -5444,7 +5990,7 @@ func (ec *executionContext) _Env_SENDER_NAME(ctx context.Context, field graphql.
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.SenderName, nil
})
@@ -5460,7 +6006,7 @@ func (ec *executionContext) _Env_SENDER_NAME(ctx context.Context, field graphql.
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_SENDER_NAME(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_SENDER_NAME(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -5485,7 +6031,7 @@ func (ec *executionContext) _Env_JWT_TYPE(ctx context.Context, field graphql.Col
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.JwtType, nil
})
@@ -5501,7 +6047,7 @@ func (ec *executionContext) _Env_JWT_TYPE(ctx context.Context, field graphql.Col
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_JWT_TYPE(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_JWT_TYPE(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -5526,7 +6072,7 @@ func (ec *executionContext) _Env_JWT_SECRET(ctx context.Context, field graphql.C
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.JwtSecret, nil
})
@@ -5542,7 +6088,7 @@ func (ec *executionContext) _Env_JWT_SECRET(ctx context.Context, field graphql.C
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_JWT_SECRET(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_JWT_SECRET(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -5567,7 +6113,7 @@ func (ec *executionContext) _Env_JWT_PRIVATE_KEY(ctx context.Context, field grap
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.JwtPrivateKey, nil
})
@@ -5583,7 +6129,7 @@ func (ec *executionContext) _Env_JWT_PRIVATE_KEY(ctx context.Context, field grap
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_JWT_PRIVATE_KEY(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_JWT_PRIVATE_KEY(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -5608,7 +6154,7 @@ func (ec *executionContext) _Env_JWT_PUBLIC_KEY(ctx context.Context, field graph
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.JwtPublicKey, nil
})
@@ -5624,7 +6170,7 @@ func (ec *executionContext) _Env_JWT_PUBLIC_KEY(ctx context.Context, field graph
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_JWT_PUBLIC_KEY(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_JWT_PUBLIC_KEY(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -5649,7 +6195,7 @@ func (ec *executionContext) _Env_ALLOWED_ORIGINS(ctx context.Context, field grap
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.AllowedOrigins, nil
})
@@ -5665,7 +6211,7 @@ func (ec *executionContext) _Env_ALLOWED_ORIGINS(ctx context.Context, field grap
return ec.marshalOString2ᚕstringᚄ(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_ALLOWED_ORIGINS(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_ALLOWED_ORIGINS(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -5690,7 +6236,7 @@ func (ec *executionContext) _Env_APP_URL(ctx context.Context, field graphql.Coll
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.AppURL, nil
})
@@ -5706,7 +6252,7 @@ func (ec *executionContext) _Env_APP_URL(ctx context.Context, field graphql.Coll
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_APP_URL(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_APP_URL(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -5731,7 +6277,7 @@ func (ec *executionContext) _Env_REDIS_URL(ctx context.Context, field graphql.Co
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.RedisURL, nil
})
@@ -5747,7 +6293,7 @@ func (ec *executionContext) _Env_REDIS_URL(ctx context.Context, field graphql.Co
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_REDIS_URL(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_REDIS_URL(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -5772,7 +6318,7 @@ func (ec *executionContext) _Env_RESET_PASSWORD_URL(ctx context.Context, field g
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.ResetPasswordURL, nil
})
@@ -5788,7 +6334,7 @@ func (ec *executionContext) _Env_RESET_PASSWORD_URL(ctx context.Context, field g
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_RESET_PASSWORD_URL(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_RESET_PASSWORD_URL(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -5813,7 +6359,7 @@ func (ec *executionContext) _Env_DISABLE_EMAIL_VERIFICATION(ctx context.Context,
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.DisableEmailVerification, nil
})
@@ -5832,7 +6378,7 @@ func (ec *executionContext) _Env_DISABLE_EMAIL_VERIFICATION(ctx context.Context,
return ec.marshalNBoolean2bool(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_DISABLE_EMAIL_VERIFICATION(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_DISABLE_EMAIL_VERIFICATION(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -5857,7 +6403,7 @@ func (ec *executionContext) _Env_DISABLE_BASIC_AUTHENTICATION(ctx context.Contex
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.DisableBasicAuthentication, nil
})
@@ -5876,7 +6422,7 @@ func (ec *executionContext) _Env_DISABLE_BASIC_AUTHENTICATION(ctx context.Contex
return ec.marshalNBoolean2bool(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_DISABLE_BASIC_AUTHENTICATION(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_DISABLE_BASIC_AUTHENTICATION(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -5901,7 +6447,7 @@ func (ec *executionContext) _Env_DISABLE_MOBILE_BASIC_AUTHENTICATION(ctx context
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.DisableMobileBasicAuthentication, nil
})
@@ -5920,7 +6466,7 @@ func (ec *executionContext) _Env_DISABLE_MOBILE_BASIC_AUTHENTICATION(ctx context
return ec.marshalNBoolean2bool(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_DISABLE_MOBILE_BASIC_AUTHENTICATION(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_DISABLE_MOBILE_BASIC_AUTHENTICATION(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -5945,7 +6491,7 @@ func (ec *executionContext) _Env_DISABLE_MAGIC_LINK_LOGIN(ctx context.Context, f
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.DisableMagicLinkLogin, nil
})
@@ -5964,7 +6510,7 @@ func (ec *executionContext) _Env_DISABLE_MAGIC_LINK_LOGIN(ctx context.Context, f
return ec.marshalNBoolean2bool(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_DISABLE_MAGIC_LINK_LOGIN(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_DISABLE_MAGIC_LINK_LOGIN(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -5989,7 +6535,7 @@ func (ec *executionContext) _Env_DISABLE_LOGIN_PAGE(ctx context.Context, field g
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.DisableLoginPage, nil
})
@@ -6008,7 +6554,7 @@ func (ec *executionContext) _Env_DISABLE_LOGIN_PAGE(ctx context.Context, field g
return ec.marshalNBoolean2bool(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_DISABLE_LOGIN_PAGE(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_DISABLE_LOGIN_PAGE(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -6033,7 +6579,7 @@ func (ec *executionContext) _Env_DISABLE_SIGN_UP(ctx context.Context, field grap
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.DisableSignUp, nil
})
@@ -6052,7 +6598,7 @@ func (ec *executionContext) _Env_DISABLE_SIGN_UP(ctx context.Context, field grap
return ec.marshalNBoolean2bool(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_DISABLE_SIGN_UP(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_DISABLE_SIGN_UP(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -6077,7 +6623,7 @@ func (ec *executionContext) _Env_DISABLE_REDIS_FOR_ENV(ctx context.Context, fiel
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.DisableRedisForEnv, nil
})
@@ -6096,7 +6642,7 @@ func (ec *executionContext) _Env_DISABLE_REDIS_FOR_ENV(ctx context.Context, fiel
return ec.marshalNBoolean2bool(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_DISABLE_REDIS_FOR_ENV(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_DISABLE_REDIS_FOR_ENV(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -6121,7 +6667,7 @@ func (ec *executionContext) _Env_DISABLE_STRONG_PASSWORD(ctx context.Context, fi
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.DisableStrongPassword, nil
})
@@ -6140,7 +6686,7 @@ func (ec *executionContext) _Env_DISABLE_STRONG_PASSWORD(ctx context.Context, fi
return ec.marshalNBoolean2bool(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_DISABLE_STRONG_PASSWORD(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_DISABLE_STRONG_PASSWORD(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -6165,7 +6711,7 @@ func (ec *executionContext) _Env_DISABLE_MULTI_FACTOR_AUTHENTICATION(ctx context
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.DisableMultiFactorAuthentication, nil
})
@@ -6184,7 +6730,7 @@ func (ec *executionContext) _Env_DISABLE_MULTI_FACTOR_AUTHENTICATION(ctx context
return ec.marshalNBoolean2bool(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_DISABLE_MULTI_FACTOR_AUTHENTICATION(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_DISABLE_MULTI_FACTOR_AUTHENTICATION(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -6209,7 +6755,7 @@ func (ec *executionContext) _Env_ENFORCE_MULTI_FACTOR_AUTHENTICATION(ctx context
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.EnforceMultiFactorAuthentication, nil
})
@@ -6228,7 +6774,7 @@ func (ec *executionContext) _Env_ENFORCE_MULTI_FACTOR_AUTHENTICATION(ctx context
return ec.marshalNBoolean2bool(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_ENFORCE_MULTI_FACTOR_AUTHENTICATION(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_ENFORCE_MULTI_FACTOR_AUTHENTICATION(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -6253,7 +6799,7 @@ func (ec *executionContext) _Env_ROLES(ctx context.Context, field graphql.Collec
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Roles, nil
})
@@ -6269,7 +6815,7 @@ func (ec *executionContext) _Env_ROLES(ctx context.Context, field graphql.Collec
return ec.marshalOString2ᚕstringᚄ(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_ROLES(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_ROLES(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -6294,7 +6840,7 @@ func (ec *executionContext) _Env_PROTECTED_ROLES(ctx context.Context, field grap
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.ProtectedRoles, nil
})
@@ -6310,7 +6856,7 @@ func (ec *executionContext) _Env_PROTECTED_ROLES(ctx context.Context, field grap
return ec.marshalOString2ᚕstringᚄ(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_PROTECTED_ROLES(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_PROTECTED_ROLES(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -6335,7 +6881,7 @@ func (ec *executionContext) _Env_DEFAULT_ROLES(ctx context.Context, field graphq
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.DefaultRoles, nil
})
@@ -6351,7 +6897,7 @@ func (ec *executionContext) _Env_DEFAULT_ROLES(ctx context.Context, field graphq
return ec.marshalOString2ᚕstringᚄ(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_DEFAULT_ROLES(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_DEFAULT_ROLES(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -6376,7 +6922,7 @@ func (ec *executionContext) _Env_JWT_ROLE_CLAIM(ctx context.Context, field graph
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.JwtRoleClaim, nil
})
@@ -6392,7 +6938,7 @@ func (ec *executionContext) _Env_JWT_ROLE_CLAIM(ctx context.Context, field graph
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_JWT_ROLE_CLAIM(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_JWT_ROLE_CLAIM(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -6417,7 +6963,7 @@ func (ec *executionContext) _Env_GOOGLE_CLIENT_ID(ctx context.Context, field gra
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.GoogleClientID, nil
})
@@ -6433,7 +6979,7 @@ func (ec *executionContext) _Env_GOOGLE_CLIENT_ID(ctx context.Context, field gra
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_GOOGLE_CLIENT_ID(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_GOOGLE_CLIENT_ID(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -6458,7 +7004,7 @@ func (ec *executionContext) _Env_GOOGLE_CLIENT_SECRET(ctx context.Context, field
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.GoogleClientSecret, nil
})
@@ -6474,7 +7020,7 @@ func (ec *executionContext) _Env_GOOGLE_CLIENT_SECRET(ctx context.Context, field
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_GOOGLE_CLIENT_SECRET(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_GOOGLE_CLIENT_SECRET(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -6499,7 +7045,7 @@ func (ec *executionContext) _Env_GITHUB_CLIENT_ID(ctx context.Context, field gra
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.GithubClientID, nil
})
@@ -6515,7 +7061,7 @@ func (ec *executionContext) _Env_GITHUB_CLIENT_ID(ctx context.Context, field gra
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_GITHUB_CLIENT_ID(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_GITHUB_CLIENT_ID(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -6540,7 +7086,7 @@ func (ec *executionContext) _Env_GITHUB_CLIENT_SECRET(ctx context.Context, field
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.GithubClientSecret, nil
})
@@ -6556,7 +7102,7 @@ func (ec *executionContext) _Env_GITHUB_CLIENT_SECRET(ctx context.Context, field
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_GITHUB_CLIENT_SECRET(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_GITHUB_CLIENT_SECRET(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -6581,7 +7127,7 @@ func (ec *executionContext) _Env_FACEBOOK_CLIENT_ID(ctx context.Context, field g
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.FacebookClientID, nil
})
@@ -6597,7 +7143,7 @@ func (ec *executionContext) _Env_FACEBOOK_CLIENT_ID(ctx context.Context, field g
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_FACEBOOK_CLIENT_ID(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_FACEBOOK_CLIENT_ID(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -6622,7 +7168,7 @@ func (ec *executionContext) _Env_FACEBOOK_CLIENT_SECRET(ctx context.Context, fie
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.FacebookClientSecret, nil
})
@@ -6638,7 +7184,7 @@ func (ec *executionContext) _Env_FACEBOOK_CLIENT_SECRET(ctx context.Context, fie
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_FACEBOOK_CLIENT_SECRET(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_FACEBOOK_CLIENT_SECRET(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -6663,7 +7209,7 @@ func (ec *executionContext) _Env_LINKEDIN_CLIENT_ID(ctx context.Context, field g
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.LinkedinClientID, nil
})
@@ -6679,7 +7225,7 @@ func (ec *executionContext) _Env_LINKEDIN_CLIENT_ID(ctx context.Context, field g
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_LINKEDIN_CLIENT_ID(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_LINKEDIN_CLIENT_ID(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -6704,7 +7250,7 @@ func (ec *executionContext) _Env_LINKEDIN_CLIENT_SECRET(ctx context.Context, fie
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.LinkedinClientSecret, nil
})
@@ -6720,7 +7266,7 @@ func (ec *executionContext) _Env_LINKEDIN_CLIENT_SECRET(ctx context.Context, fie
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_LINKEDIN_CLIENT_SECRET(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_LINKEDIN_CLIENT_SECRET(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -6745,7 +7291,7 @@ func (ec *executionContext) _Env_APPLE_CLIENT_ID(ctx context.Context, field grap
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.AppleClientID, nil
})
@@ -6761,7 +7307,7 @@ func (ec *executionContext) _Env_APPLE_CLIENT_ID(ctx context.Context, field grap
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_APPLE_CLIENT_ID(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_APPLE_CLIENT_ID(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -6786,7 +7332,7 @@ func (ec *executionContext) _Env_APPLE_CLIENT_SECRET(ctx context.Context, field
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.AppleClientSecret, nil
})
@@ -6802,7 +7348,7 @@ func (ec *executionContext) _Env_APPLE_CLIENT_SECRET(ctx context.Context, field
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_APPLE_CLIENT_SECRET(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_APPLE_CLIENT_SECRET(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -6827,7 +7373,7 @@ func (ec *executionContext) _Env_DISCORD_CLIENT_ID(ctx context.Context, field gr
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.DiscordClientID, nil
})
@@ -6843,7 +7389,7 @@ func (ec *executionContext) _Env_DISCORD_CLIENT_ID(ctx context.Context, field gr
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_DISCORD_CLIENT_ID(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_DISCORD_CLIENT_ID(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -6868,7 +7414,7 @@ func (ec *executionContext) _Env_DISCORD_CLIENT_SECRET(ctx context.Context, fiel
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.DiscordClientSecret, nil
})
@@ -6884,7 +7430,7 @@ func (ec *executionContext) _Env_DISCORD_CLIENT_SECRET(ctx context.Context, fiel
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_DISCORD_CLIENT_SECRET(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_DISCORD_CLIENT_SECRET(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -6909,7 +7455,7 @@ func (ec *executionContext) _Env_TWITTER_CLIENT_ID(ctx context.Context, field gr
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.TwitterClientID, nil
})
@@ -6925,7 +7471,7 @@ func (ec *executionContext) _Env_TWITTER_CLIENT_ID(ctx context.Context, field gr
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_TWITTER_CLIENT_ID(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_TWITTER_CLIENT_ID(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -6950,7 +7496,7 @@ func (ec *executionContext) _Env_TWITTER_CLIENT_SECRET(ctx context.Context, fiel
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.TwitterClientSecret, nil
})
@@ -6966,7 +7512,7 @@ func (ec *executionContext) _Env_TWITTER_CLIENT_SECRET(ctx context.Context, fiel
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_TWITTER_CLIENT_SECRET(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_TWITTER_CLIENT_SECRET(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -6991,7 +7537,7 @@ func (ec *executionContext) _Env_MICROSOFT_CLIENT_ID(ctx context.Context, field
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.MicrosoftClientID, nil
})
@@ -7007,7 +7553,7 @@ func (ec *executionContext) _Env_MICROSOFT_CLIENT_ID(ctx context.Context, field
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_MICROSOFT_CLIENT_ID(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_MICROSOFT_CLIENT_ID(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -7032,7 +7578,7 @@ func (ec *executionContext) _Env_MICROSOFT_CLIENT_SECRET(ctx context.Context, fi
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.MicrosoftClientSecret, nil
})
@@ -7048,7 +7594,7 @@ func (ec *executionContext) _Env_MICROSOFT_CLIENT_SECRET(ctx context.Context, fi
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_MICROSOFT_CLIENT_SECRET(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_MICROSOFT_CLIENT_SECRET(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -7073,7 +7619,7 @@ func (ec *executionContext) _Env_MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID(ctx contex
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.MicrosoftActiveDirectoryTenantID, nil
})
@@ -7089,7 +7635,7 @@ func (ec *executionContext) _Env_MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID(ctx contex
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -7114,7 +7660,7 @@ func (ec *executionContext) _Env_TWITCH_CLIENT_ID(ctx context.Context, field gra
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.TwitchClientID, nil
})
@@ -7130,7 +7676,7 @@ func (ec *executionContext) _Env_TWITCH_CLIENT_ID(ctx context.Context, field gra
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_TWITCH_CLIENT_ID(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_TWITCH_CLIENT_ID(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -7155,7 +7701,7 @@ func (ec *executionContext) _Env_TWITCH_CLIENT_SECRET(ctx context.Context, field
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.TwitchClientSecret, nil
})
@@ -7171,7 +7717,7 @@ func (ec *executionContext) _Env_TWITCH_CLIENT_SECRET(ctx context.Context, field
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_TWITCH_CLIENT_SECRET(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_TWITCH_CLIENT_SECRET(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -7196,7 +7742,7 @@ func (ec *executionContext) _Env_ROBLOX_CLIENT_ID(ctx context.Context, field gra
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.RobloxClientID, nil
})
@@ -7212,7 +7758,7 @@ func (ec *executionContext) _Env_ROBLOX_CLIENT_ID(ctx context.Context, field gra
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_ROBLOX_CLIENT_ID(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_ROBLOX_CLIENT_ID(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -7237,7 +7783,7 @@ func (ec *executionContext) _Env_ROBLOX_CLIENT_SECRET(ctx context.Context, field
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.RobloxClientSecret, nil
})
@@ -7253,7 +7799,7 @@ func (ec *executionContext) _Env_ROBLOX_CLIENT_SECRET(ctx context.Context, field
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_ROBLOX_CLIENT_SECRET(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_ROBLOX_CLIENT_SECRET(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -7278,7 +7824,7 @@ func (ec *executionContext) _Env_ORGANIZATION_NAME(ctx context.Context, field gr
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.OrganizationName, nil
})
@@ -7294,7 +7840,7 @@ func (ec *executionContext) _Env_ORGANIZATION_NAME(ctx context.Context, field gr
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_ORGANIZATION_NAME(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_ORGANIZATION_NAME(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -7319,7 +7865,7 @@ func (ec *executionContext) _Env_ORGANIZATION_LOGO(ctx context.Context, field gr
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.OrganizationLogo, nil
})
@@ -7335,7 +7881,7 @@ func (ec *executionContext) _Env_ORGANIZATION_LOGO(ctx context.Context, field gr
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_ORGANIZATION_LOGO(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_ORGANIZATION_LOGO(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -7360,7 +7906,7 @@ func (ec *executionContext) _Env_APP_COOKIE_SECURE(ctx context.Context, field gr
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.AppCookieSecure, nil
})
@@ -7379,7 +7925,7 @@ func (ec *executionContext) _Env_APP_COOKIE_SECURE(ctx context.Context, field gr
return ec.marshalNBoolean2bool(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_APP_COOKIE_SECURE(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_APP_COOKIE_SECURE(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -7404,7 +7950,7 @@ func (ec *executionContext) _Env_ADMIN_COOKIE_SECURE(ctx context.Context, field
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.AdminCookieSecure, nil
})
@@ -7423,7 +7969,7 @@ func (ec *executionContext) _Env_ADMIN_COOKIE_SECURE(ctx context.Context, field
return ec.marshalNBoolean2bool(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_ADMIN_COOKIE_SECURE(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_ADMIN_COOKIE_SECURE(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -7448,7 +7994,7 @@ func (ec *executionContext) _Env_DEFAULT_AUTHORIZE_RESPONSE_TYPE(ctx context.Con
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.DefaultAuthorizeResponseType, nil
})
@@ -7464,7 +8010,7 @@ func (ec *executionContext) _Env_DEFAULT_AUTHORIZE_RESPONSE_TYPE(ctx context.Con
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_DEFAULT_AUTHORIZE_RESPONSE_TYPE(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_DEFAULT_AUTHORIZE_RESPONSE_TYPE(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -7489,7 +8035,7 @@ func (ec *executionContext) _Env_DEFAULT_AUTHORIZE_RESPONSE_MODE(ctx context.Con
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.DefaultAuthorizeResponseMode, nil
})
@@ -7505,7 +8051,7 @@ func (ec *executionContext) _Env_DEFAULT_AUTHORIZE_RESPONSE_MODE(ctx context.Con
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_DEFAULT_AUTHORIZE_RESPONSE_MODE(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_DEFAULT_AUTHORIZE_RESPONSE_MODE(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -7530,7 +8076,7 @@ func (ec *executionContext) _Env_DISABLE_PLAYGROUND(ctx context.Context, field g
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.DisablePlayground, nil
})
@@ -7549,7 +8095,7 @@ func (ec *executionContext) _Env_DISABLE_PLAYGROUND(ctx context.Context, field g
return ec.marshalNBoolean2bool(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_DISABLE_PLAYGROUND(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_DISABLE_PLAYGROUND(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -7574,7 +8120,7 @@ func (ec *executionContext) _Env_DISABLE_MAIL_OTP_LOGIN(ctx context.Context, fie
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.DisableMailOtpLogin, nil
})
@@ -7593,7 +8139,7 @@ func (ec *executionContext) _Env_DISABLE_MAIL_OTP_LOGIN(ctx context.Context, fie
return ec.marshalNBoolean2bool(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_DISABLE_MAIL_OTP_LOGIN(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_DISABLE_MAIL_OTP_LOGIN(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -7618,7 +8164,7 @@ func (ec *executionContext) _Env_DISABLE_TOTP_LOGIN(ctx context.Context, field g
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.DisableTotpLogin, nil
})
@@ -7637,7 +8183,7 @@ func (ec *executionContext) _Env_DISABLE_TOTP_LOGIN(ctx context.Context, field g
return ec.marshalNBoolean2bool(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Env_DISABLE_TOTP_LOGIN(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Env_DISABLE_TOTP_LOGIN(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
@@ -7662,7 +8208,7 @@ func (ec *executionContext) _Error_message(ctx context.Context, field graphql.Co
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Message, nil
})
@@ -7681,7 +8227,7 @@ func (ec *executionContext) _Error_message(ctx context.Context, field graphql.Co
return ec.marshalNString2string(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Error_message(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Error_message(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Error",
Field: field,
@@ -7706,7 +8252,7 @@ func (ec *executionContext) _Error_reason(ctx context.Context, field graphql.Col
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Reason, nil
})
@@ -7725,7 +8271,7 @@ func (ec *executionContext) _Error_reason(ctx context.Context, field graphql.Col
return ec.marshalNString2string(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Error_reason(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Error_reason(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Error",
Field: field,
@@ -7750,7 +8296,7 @@ func (ec *executionContext) _ForgotPasswordResponse_message(ctx context.Context,
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Message, nil
})
@@ -7769,7 +8315,7 @@ func (ec *executionContext) _ForgotPasswordResponse_message(ctx context.Context,
return ec.marshalNString2string(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_ForgotPasswordResponse_message(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_ForgotPasswordResponse_message(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "ForgotPasswordResponse",
Field: field,
@@ -7794,7 +8340,7 @@ func (ec *executionContext) _ForgotPasswordResponse_should_show_mobile_otp_scree
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.ShouldShowMobileOtpScreen, nil
})
@@ -7810,7 +8356,7 @@ func (ec *executionContext) _ForgotPasswordResponse_should_show_mobile_otp_scree
return ec.marshalOBoolean2ᚖbool(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_ForgotPasswordResponse_should_show_mobile_otp_screen(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_ForgotPasswordResponse_should_show_mobile_otp_screen(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "ForgotPasswordResponse",
Field: field,
@@ -7835,7 +8381,7 @@ func (ec *executionContext) _GenerateJWTKeysResponse_secret(ctx context.Context,
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Secret, nil
})
@@ -7851,7 +8397,7 @@ func (ec *executionContext) _GenerateJWTKeysResponse_secret(ctx context.Context,
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_GenerateJWTKeysResponse_secret(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_GenerateJWTKeysResponse_secret(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "GenerateJWTKeysResponse",
Field: field,
@@ -7876,7 +8422,7 @@ func (ec *executionContext) _GenerateJWTKeysResponse_public_key(ctx context.Cont
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.PublicKey, nil
})
@@ -7892,7 +8438,7 @@ func (ec *executionContext) _GenerateJWTKeysResponse_public_key(ctx context.Cont
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_GenerateJWTKeysResponse_public_key(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_GenerateJWTKeysResponse_public_key(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "GenerateJWTKeysResponse",
Field: field,
@@ -7917,7 +8463,7 @@ func (ec *executionContext) _GenerateJWTKeysResponse_private_key(ctx context.Con
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.PrivateKey, nil
})
@@ -7933,7 +8479,7 @@ func (ec *executionContext) _GenerateJWTKeysResponse_private_key(ctx context.Con
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_GenerateJWTKeysResponse_private_key(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_GenerateJWTKeysResponse_private_key(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "GenerateJWTKeysResponse",
Field: field,
@@ -7958,7 +8504,7 @@ func (ec *executionContext) _InviteMembersResponse_message(ctx context.Context,
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Message, nil
})
@@ -7977,7 +8523,7 @@ func (ec *executionContext) _InviteMembersResponse_message(ctx context.Context,
return ec.marshalNString2string(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_InviteMembersResponse_message(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_InviteMembersResponse_message(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "InviteMembersResponse",
Field: field,
@@ -8002,7 +8548,7 @@ func (ec *executionContext) _InviteMembersResponse_Users(ctx context.Context, fi
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Users, nil
})
@@ -8018,10 +8564,10 @@ func (ec *executionContext) _InviteMembersResponse_Users(ctx context.Context, fi
}
res := resTmp.([]*model.User)
fc.Result = res
- return ec.marshalNUser2ᚕᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐUserᚄ(ctx, field.Selections, res)
+ return ec.marshalNUser2ᚕᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐUserᚄ(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_InviteMembersResponse_Users(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_InviteMembersResponse_Users(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "InviteMembersResponse",
Field: field,
@@ -8088,7 +8634,7 @@ func (ec *executionContext) _Meta_version(ctx context.Context, field graphql.Col
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Version, nil
})
@@ -8107,7 +8653,7 @@ func (ec *executionContext) _Meta_version(ctx context.Context, field graphql.Col
return ec.marshalNString2string(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Meta_version(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Meta_version(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Meta",
Field: field,
@@ -8132,7 +8678,7 @@ func (ec *executionContext) _Meta_client_id(ctx context.Context, field graphql.C
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.ClientID, nil
})
@@ -8151,7 +8697,7 @@ func (ec *executionContext) _Meta_client_id(ctx context.Context, field graphql.C
return ec.marshalNString2string(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Meta_client_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Meta_client_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Meta",
Field: field,
@@ -8176,7 +8722,7 @@ func (ec *executionContext) _Meta_is_google_login_enabled(ctx context.Context, f
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.IsGoogleLoginEnabled, nil
})
@@ -8195,7 +8741,7 @@ func (ec *executionContext) _Meta_is_google_login_enabled(ctx context.Context, f
return ec.marshalNBoolean2bool(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Meta_is_google_login_enabled(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Meta_is_google_login_enabled(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Meta",
Field: field,
@@ -8220,7 +8766,7 @@ func (ec *executionContext) _Meta_is_facebook_login_enabled(ctx context.Context,
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.IsFacebookLoginEnabled, nil
})
@@ -8239,7 +8785,7 @@ func (ec *executionContext) _Meta_is_facebook_login_enabled(ctx context.Context,
return ec.marshalNBoolean2bool(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Meta_is_facebook_login_enabled(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Meta_is_facebook_login_enabled(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Meta",
Field: field,
@@ -8264,7 +8810,7 @@ func (ec *executionContext) _Meta_is_github_login_enabled(ctx context.Context, f
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.IsGithubLoginEnabled, nil
})
@@ -8283,7 +8829,7 @@ func (ec *executionContext) _Meta_is_github_login_enabled(ctx context.Context, f
return ec.marshalNBoolean2bool(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Meta_is_github_login_enabled(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Meta_is_github_login_enabled(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Meta",
Field: field,
@@ -8308,7 +8854,7 @@ func (ec *executionContext) _Meta_is_linkedin_login_enabled(ctx context.Context,
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.IsLinkedinLoginEnabled, nil
})
@@ -8327,7 +8873,7 @@ func (ec *executionContext) _Meta_is_linkedin_login_enabled(ctx context.Context,
return ec.marshalNBoolean2bool(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Meta_is_linkedin_login_enabled(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Meta_is_linkedin_login_enabled(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Meta",
Field: field,
@@ -8352,7 +8898,7 @@ func (ec *executionContext) _Meta_is_apple_login_enabled(ctx context.Context, fi
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.IsAppleLoginEnabled, nil
})
@@ -8371,7 +8917,7 @@ func (ec *executionContext) _Meta_is_apple_login_enabled(ctx context.Context, fi
return ec.marshalNBoolean2bool(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Meta_is_apple_login_enabled(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Meta_is_apple_login_enabled(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Meta",
Field: field,
@@ -8396,7 +8942,7 @@ func (ec *executionContext) _Meta_is_discord_login_enabled(ctx context.Context,
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.IsDiscordLoginEnabled, nil
})
@@ -8415,7 +8961,7 @@ func (ec *executionContext) _Meta_is_discord_login_enabled(ctx context.Context,
return ec.marshalNBoolean2bool(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Meta_is_discord_login_enabled(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Meta_is_discord_login_enabled(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Meta",
Field: field,
@@ -8440,7 +8986,7 @@ func (ec *executionContext) _Meta_is_twitter_login_enabled(ctx context.Context,
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.IsTwitterLoginEnabled, nil
})
@@ -8459,7 +9005,7 @@ func (ec *executionContext) _Meta_is_twitter_login_enabled(ctx context.Context,
return ec.marshalNBoolean2bool(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Meta_is_twitter_login_enabled(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Meta_is_twitter_login_enabled(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Meta",
Field: field,
@@ -8484,7 +9030,7 @@ func (ec *executionContext) _Meta_is_microsoft_login_enabled(ctx context.Context
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.IsMicrosoftLoginEnabled, nil
})
@@ -8503,7 +9049,7 @@ func (ec *executionContext) _Meta_is_microsoft_login_enabled(ctx context.Context
return ec.marshalNBoolean2bool(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Meta_is_microsoft_login_enabled(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Meta_is_microsoft_login_enabled(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Meta",
Field: field,
@@ -8528,7 +9074,7 @@ func (ec *executionContext) _Meta_is_twitch_login_enabled(ctx context.Context, f
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.IsTwitchLoginEnabled, nil
})
@@ -8547,7 +9093,7 @@ func (ec *executionContext) _Meta_is_twitch_login_enabled(ctx context.Context, f
return ec.marshalNBoolean2bool(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Meta_is_twitch_login_enabled(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Meta_is_twitch_login_enabled(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Meta",
Field: field,
@@ -8572,7 +9118,7 @@ func (ec *executionContext) _Meta_is_roblox_login_enabled(ctx context.Context, f
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.IsRobloxLoginEnabled, nil
})
@@ -8591,7 +9137,7 @@ func (ec *executionContext) _Meta_is_roblox_login_enabled(ctx context.Context, f
return ec.marshalNBoolean2bool(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Meta_is_roblox_login_enabled(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Meta_is_roblox_login_enabled(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Meta",
Field: field,
@@ -8616,7 +9162,7 @@ func (ec *executionContext) _Meta_is_email_verification_enabled(ctx context.Cont
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.IsEmailVerificationEnabled, nil
})
@@ -8635,7 +9181,7 @@ func (ec *executionContext) _Meta_is_email_verification_enabled(ctx context.Cont
return ec.marshalNBoolean2bool(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Meta_is_email_verification_enabled(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Meta_is_email_verification_enabled(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Meta",
Field: field,
@@ -8660,7 +9206,7 @@ func (ec *executionContext) _Meta_is_basic_authentication_enabled(ctx context.Co
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.IsBasicAuthenticationEnabled, nil
})
@@ -8679,7 +9225,7 @@ func (ec *executionContext) _Meta_is_basic_authentication_enabled(ctx context.Co
return ec.marshalNBoolean2bool(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Meta_is_basic_authentication_enabled(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Meta_is_basic_authentication_enabled(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Meta",
Field: field,
@@ -8704,7 +9250,7 @@ func (ec *executionContext) _Meta_is_magic_link_login_enabled(ctx context.Contex
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.IsMagicLinkLoginEnabled, nil
})
@@ -8723,7 +9269,7 @@ func (ec *executionContext) _Meta_is_magic_link_login_enabled(ctx context.Contex
return ec.marshalNBoolean2bool(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Meta_is_magic_link_login_enabled(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Meta_is_magic_link_login_enabled(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Meta",
Field: field,
@@ -8748,7 +9294,7 @@ func (ec *executionContext) _Meta_is_sign_up_enabled(ctx context.Context, field
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.IsSignUpEnabled, nil
})
@@ -8767,7 +9313,7 @@ func (ec *executionContext) _Meta_is_sign_up_enabled(ctx context.Context, field
return ec.marshalNBoolean2bool(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Meta_is_sign_up_enabled(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Meta_is_sign_up_enabled(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Meta",
Field: field,
@@ -8792,7 +9338,7 @@ func (ec *executionContext) _Meta_is_strong_password_enabled(ctx context.Context
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.IsStrongPasswordEnabled, nil
})
@@ -8811,7 +9357,7 @@ func (ec *executionContext) _Meta_is_strong_password_enabled(ctx context.Context
return ec.marshalNBoolean2bool(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Meta_is_strong_password_enabled(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Meta_is_strong_password_enabled(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Meta",
Field: field,
@@ -8836,7 +9382,7 @@ func (ec *executionContext) _Meta_is_multi_factor_auth_enabled(ctx context.Conte
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.IsMultiFactorAuthEnabled, nil
})
@@ -8855,7 +9401,7 @@ func (ec *executionContext) _Meta_is_multi_factor_auth_enabled(ctx context.Conte
return ec.marshalNBoolean2bool(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Meta_is_multi_factor_auth_enabled(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Meta_is_multi_factor_auth_enabled(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Meta",
Field: field,
@@ -8880,7 +9426,7 @@ func (ec *executionContext) _Meta_is_mobile_basic_authentication_enabled(ctx con
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.IsMobileBasicAuthenticationEnabled, nil
})
@@ -8899,7 +9445,7 @@ func (ec *executionContext) _Meta_is_mobile_basic_authentication_enabled(ctx con
return ec.marshalNBoolean2bool(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Meta_is_mobile_basic_authentication_enabled(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Meta_is_mobile_basic_authentication_enabled(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Meta",
Field: field,
@@ -8924,7 +9470,7 @@ func (ec *executionContext) _Meta_is_phone_verification_enabled(ctx context.Cont
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.IsPhoneVerificationEnabled, nil
})
@@ -8943,7 +9489,7 @@ func (ec *executionContext) _Meta_is_phone_verification_enabled(ctx context.Cont
return ec.marshalNBoolean2bool(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Meta_is_phone_verification_enabled(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Meta_is_phone_verification_enabled(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Meta",
Field: field,
@@ -8968,9 +9514,9 @@ func (ec *executionContext) _Mutation_signup(ctx context.Context, field graphql.
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
- return ec.resolvers.Mutation().Signup(rctx, fc.Args["params"].(model.SignUpInput))
+ return ec.resolvers.Mutation().Signup(rctx, fc.Args["params"].(model.SignUpRequest))
})
if err != nil {
ec.Error(ctx, err)
@@ -8984,7 +9530,7 @@ func (ec *executionContext) _Mutation_signup(ctx context.Context, field graphql.
}
res := resTmp.(*model.AuthResponse)
fc.Result = res
- return ec.marshalNAuthResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐAuthResponse(ctx, field.Selections, res)
+ return ec.marshalNAuthResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐAuthResponse(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Mutation_signup(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
@@ -9049,9 +9595,9 @@ func (ec *executionContext) _Mutation_mobile_signup(ctx context.Context, field g
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
- return ec.resolvers.Mutation().MobileSignup(rctx, fc.Args["params"].(*model.MobileSignUpInput))
+ return ec.resolvers.Mutation().MobileSignup(rctx, fc.Args["params"].(*model.MobileSignUpRequest))
})
if err != nil {
ec.Error(ctx, err)
@@ -9065,7 +9611,7 @@ func (ec *executionContext) _Mutation_mobile_signup(ctx context.Context, field g
}
res := resTmp.(*model.AuthResponse)
fc.Result = res
- return ec.marshalNAuthResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐAuthResponse(ctx, field.Selections, res)
+ return ec.marshalNAuthResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐAuthResponse(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Mutation_mobile_signup(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
@@ -9130,9 +9676,9 @@ func (ec *executionContext) _Mutation_login(ctx context.Context, field graphql.C
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
- return ec.resolvers.Mutation().Login(rctx, fc.Args["params"].(model.LoginInput))
+ return ec.resolvers.Mutation().Login(rctx, fc.Args["params"].(model.LoginRequest))
})
if err != nil {
ec.Error(ctx, err)
@@ -9146,7 +9692,7 @@ func (ec *executionContext) _Mutation_login(ctx context.Context, field graphql.C
}
res := resTmp.(*model.AuthResponse)
fc.Result = res
- return ec.marshalNAuthResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐAuthResponse(ctx, field.Selections, res)
+ return ec.marshalNAuthResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐAuthResponse(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Mutation_login(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
@@ -9211,9 +9757,9 @@ func (ec *executionContext) _Mutation_mobile_login(ctx context.Context, field gr
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
- return ec.resolvers.Mutation().MobileLogin(rctx, fc.Args["params"].(model.MobileLoginInput))
+ return ec.resolvers.Mutation().MobileLogin(rctx, fc.Args["params"].(model.MobileLoginRequest))
})
if err != nil {
ec.Error(ctx, err)
@@ -9227,7 +9773,7 @@ func (ec *executionContext) _Mutation_mobile_login(ctx context.Context, field gr
}
res := resTmp.(*model.AuthResponse)
fc.Result = res
- return ec.marshalNAuthResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐAuthResponse(ctx, field.Selections, res)
+ return ec.marshalNAuthResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐAuthResponse(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Mutation_mobile_login(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
@@ -9292,9 +9838,9 @@ func (ec *executionContext) _Mutation_magic_link_login(ctx context.Context, fiel
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
- return ec.resolvers.Mutation().MagicLinkLogin(rctx, fc.Args["params"].(model.MagicLinkLoginInput))
+ return ec.resolvers.Mutation().MagicLinkLogin(rctx, fc.Args["params"].(model.MagicLinkLoginRequest))
})
if err != nil {
ec.Error(ctx, err)
@@ -9308,7 +9854,7 @@ func (ec *executionContext) _Mutation_magic_link_login(ctx context.Context, fiel
}
res := resTmp.(*model.Response)
fc.Result = res
- return ec.marshalNResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐResponse(ctx, field.Selections, res)
+ return ec.marshalNResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐResponse(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Mutation_magic_link_login(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
@@ -9351,7 +9897,7 @@ func (ec *executionContext) _Mutation_logout(ctx context.Context, field graphql.
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.Mutation().Logout(rctx)
})
@@ -9367,10 +9913,10 @@ func (ec *executionContext) _Mutation_logout(ctx context.Context, field graphql.
}
res := resTmp.(*model.Response)
fc.Result = res
- return ec.marshalNResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐResponse(ctx, field.Selections, res)
+ return ec.marshalNResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐResponse(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Mutation_logout(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Mutation_logout(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Mutation",
Field: field,
@@ -9399,9 +9945,9 @@ func (ec *executionContext) _Mutation_update_profile(ctx context.Context, field
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
- return ec.resolvers.Mutation().UpdateProfile(rctx, fc.Args["params"].(model.UpdateProfileInput))
+ return ec.resolvers.Mutation().UpdateProfile(rctx, fc.Args["params"].(model.UpdateProfileRequest))
})
if err != nil {
ec.Error(ctx, err)
@@ -9415,7 +9961,7 @@ func (ec *executionContext) _Mutation_update_profile(ctx context.Context, field
}
res := resTmp.(*model.Response)
fc.Result = res
- return ec.marshalNResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐResponse(ctx, field.Selections, res)
+ return ec.marshalNResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐResponse(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Mutation_update_profile(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
@@ -9458,9 +10004,9 @@ func (ec *executionContext) _Mutation_verify_email(ctx context.Context, field gr
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
- return ec.resolvers.Mutation().VerifyEmail(rctx, fc.Args["params"].(model.VerifyEmailInput))
+ return ec.resolvers.Mutation().VerifyEmail(rctx, fc.Args["params"].(model.VerifyEmailRequest))
})
if err != nil {
ec.Error(ctx, err)
@@ -9474,7 +10020,7 @@ func (ec *executionContext) _Mutation_verify_email(ctx context.Context, field gr
}
res := resTmp.(*model.AuthResponse)
fc.Result = res
- return ec.marshalNAuthResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐAuthResponse(ctx, field.Selections, res)
+ return ec.marshalNAuthResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐAuthResponse(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Mutation_verify_email(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
@@ -9539,9 +10085,9 @@ func (ec *executionContext) _Mutation_resend_verify_email(ctx context.Context, f
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
- return ec.resolvers.Mutation().ResendVerifyEmail(rctx, fc.Args["params"].(model.ResendVerifyEmailInput))
+ return ec.resolvers.Mutation().ResendVerifyEmail(rctx, fc.Args["params"].(model.ResendVerifyEmailRequest))
})
if err != nil {
ec.Error(ctx, err)
@@ -9555,7 +10101,7 @@ func (ec *executionContext) _Mutation_resend_verify_email(ctx context.Context, f
}
res := resTmp.(*model.Response)
fc.Result = res
- return ec.marshalNResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐResponse(ctx, field.Selections, res)
+ return ec.marshalNResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐResponse(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Mutation_resend_verify_email(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
@@ -9598,9 +10144,9 @@ func (ec *executionContext) _Mutation_forgot_password(ctx context.Context, field
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
- return ec.resolvers.Mutation().ForgotPassword(rctx, fc.Args["params"].(model.ForgotPasswordInput))
+ return ec.resolvers.Mutation().ForgotPassword(rctx, fc.Args["params"].(model.ForgotPasswordRequest))
})
if err != nil {
ec.Error(ctx, err)
@@ -9614,7 +10160,7 @@ func (ec *executionContext) _Mutation_forgot_password(ctx context.Context, field
}
res := resTmp.(*model.ForgotPasswordResponse)
fc.Result = res
- return ec.marshalNForgotPasswordResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐForgotPasswordResponse(ctx, field.Selections, res)
+ return ec.marshalNForgotPasswordResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐForgotPasswordResponse(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Mutation_forgot_password(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
@@ -9659,9 +10205,9 @@ func (ec *executionContext) _Mutation_reset_password(ctx context.Context, field
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
- return ec.resolvers.Mutation().ResetPassword(rctx, fc.Args["params"].(model.ResetPasswordInput))
+ return ec.resolvers.Mutation().ResetPassword(rctx, fc.Args["params"].(model.ResetPasswordRequest))
})
if err != nil {
ec.Error(ctx, err)
@@ -9675,7 +10221,7 @@ func (ec *executionContext) _Mutation_reset_password(ctx context.Context, field
}
res := resTmp.(*model.Response)
fc.Result = res
- return ec.marshalNResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐResponse(ctx, field.Selections, res)
+ return ec.marshalNResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐResponse(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Mutation_reset_password(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
@@ -9718,9 +10264,9 @@ func (ec *executionContext) _Mutation_revoke(ctx context.Context, field graphql.
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
- return ec.resolvers.Mutation().Revoke(rctx, fc.Args["params"].(model.OAuthRevokeInput))
+ return ec.resolvers.Mutation().Revoke(rctx, fc.Args["params"].(model.OAuthRevokeRequest))
})
if err != nil {
ec.Error(ctx, err)
@@ -9734,7 +10280,7 @@ func (ec *executionContext) _Mutation_revoke(ctx context.Context, field graphql.
}
res := resTmp.(*model.Response)
fc.Result = res
- return ec.marshalNResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐResponse(ctx, field.Selections, res)
+ return ec.marshalNResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐResponse(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Mutation_revoke(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
@@ -9777,7 +10323,7 @@ func (ec *executionContext) _Mutation_verify_otp(ctx context.Context, field grap
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.Mutation().VerifyOtp(rctx, fc.Args["params"].(model.VerifyOTPRequest))
})
@@ -9793,7 +10339,7 @@ func (ec *executionContext) _Mutation_verify_otp(ctx context.Context, field grap
}
res := resTmp.(*model.AuthResponse)
fc.Result = res
- return ec.marshalNAuthResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐAuthResponse(ctx, field.Selections, res)
+ return ec.marshalNAuthResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐAuthResponse(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Mutation_verify_otp(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
@@ -9858,7 +10404,7 @@ func (ec *executionContext) _Mutation_resend_otp(ctx context.Context, field grap
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.Mutation().ResendOtp(rctx, fc.Args["params"].(model.ResendOTPRequest))
})
@@ -9874,7 +10420,7 @@ func (ec *executionContext) _Mutation_resend_otp(ctx context.Context, field grap
}
res := resTmp.(*model.Response)
fc.Result = res
- return ec.marshalNResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐResponse(ctx, field.Selections, res)
+ return ec.marshalNResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐResponse(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Mutation_resend_otp(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
@@ -9917,7 +10463,7 @@ func (ec *executionContext) _Mutation_deactivate_account(ctx context.Context, fi
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.Mutation().DeactivateAccount(rctx)
})
@@ -9933,10 +10479,10 @@ func (ec *executionContext) _Mutation_deactivate_account(ctx context.Context, fi
}
res := resTmp.(*model.Response)
fc.Result = res
- return ec.marshalNResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐResponse(ctx, field.Selections, res)
+ return ec.marshalNResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐResponse(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Mutation_deactivate_account(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Mutation_deactivate_account(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Mutation",
Field: field,
@@ -9965,9 +10511,9 @@ func (ec *executionContext) _Mutation__delete_user(ctx context.Context, field gr
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
- return ec.resolvers.Mutation().DeleteUser(rctx, fc.Args["params"].(model.DeleteUserInput))
+ return ec.resolvers.Mutation().DeleteUser(rctx, fc.Args["params"].(model.DeleteUserRequest))
})
if err != nil {
ec.Error(ctx, err)
@@ -9981,7 +10527,7 @@ func (ec *executionContext) _Mutation__delete_user(ctx context.Context, field gr
}
res := resTmp.(*model.Response)
fc.Result = res
- return ec.marshalNResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐResponse(ctx, field.Selections, res)
+ return ec.marshalNResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐResponse(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Mutation__delete_user(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
@@ -10024,9 +10570,9 @@ func (ec *executionContext) _Mutation__update_user(ctx context.Context, field gr
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
- return ec.resolvers.Mutation().UpdateUser(rctx, fc.Args["params"].(model.UpdateUserInput))
+ return ec.resolvers.Mutation().UpdateUser(rctx, fc.Args["params"].(model.UpdateUserRequest))
})
if err != nil {
ec.Error(ctx, err)
@@ -10040,7 +10586,7 @@ func (ec *executionContext) _Mutation__update_user(ctx context.Context, field gr
}
res := resTmp.(*model.User)
fc.Result = res
- return ec.marshalNUser2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐUser(ctx, field.Selections, res)
+ return ec.marshalNUser2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐUser(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Mutation__update_user(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
@@ -10121,9 +10667,9 @@ func (ec *executionContext) _Mutation__admin_signup(ctx context.Context, field g
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
- return ec.resolvers.Mutation().AdminSignup(rctx, fc.Args["params"].(model.AdminSignupInput))
+ return ec.resolvers.Mutation().AdminSignup(rctx, fc.Args["params"].(model.AdminSignupRequest))
})
if err != nil {
ec.Error(ctx, err)
@@ -10137,7 +10683,7 @@ func (ec *executionContext) _Mutation__admin_signup(ctx context.Context, field g
}
res := resTmp.(*model.Response)
fc.Result = res
- return ec.marshalNResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐResponse(ctx, field.Selections, res)
+ return ec.marshalNResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐResponse(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Mutation__admin_signup(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
@@ -10180,9 +10726,9 @@ func (ec *executionContext) _Mutation__admin_login(ctx context.Context, field gr
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
- return ec.resolvers.Mutation().AdminLogin(rctx, fc.Args["params"].(model.AdminLoginInput))
+ return ec.resolvers.Mutation().AdminLogin(rctx, fc.Args["params"].(model.AdminLoginRequest))
})
if err != nil {
ec.Error(ctx, err)
@@ -10196,7 +10742,7 @@ func (ec *executionContext) _Mutation__admin_login(ctx context.Context, field gr
}
res := resTmp.(*model.Response)
fc.Result = res
- return ec.marshalNResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐResponse(ctx, field.Selections, res)
+ return ec.marshalNResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐResponse(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Mutation__admin_login(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
@@ -10239,7 +10785,7 @@ func (ec *executionContext) _Mutation__admin_logout(ctx context.Context, field g
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.Mutation().AdminLogout(rctx)
})
@@ -10255,10 +10801,10 @@ func (ec *executionContext) _Mutation__admin_logout(ctx context.Context, field g
}
res := resTmp.(*model.Response)
fc.Result = res
- return ec.marshalNResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐResponse(ctx, field.Selections, res)
+ return ec.marshalNResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐResponse(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Mutation__admin_logout(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Mutation__admin_logout(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Mutation",
Field: field,
@@ -10287,9 +10833,9 @@ func (ec *executionContext) _Mutation__update_env(ctx context.Context, field gra
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
- return ec.resolvers.Mutation().UpdateEnv(rctx, fc.Args["params"].(model.UpdateEnvInput))
+ return ec.resolvers.Mutation().UpdateEnv(rctx, fc.Args["params"].(model.UpdateEnvRequest))
})
if err != nil {
ec.Error(ctx, err)
@@ -10303,7 +10849,7 @@ func (ec *executionContext) _Mutation__update_env(ctx context.Context, field gra
}
res := resTmp.(*model.Response)
fc.Result = res
- return ec.marshalNResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐResponse(ctx, field.Selections, res)
+ return ec.marshalNResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐResponse(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Mutation__update_env(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
@@ -10346,9 +10892,9 @@ func (ec *executionContext) _Mutation__invite_members(ctx context.Context, field
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
- return ec.resolvers.Mutation().InviteMembers(rctx, fc.Args["params"].(model.InviteMemberInput))
+ return ec.resolvers.Mutation().InviteMembers(rctx, fc.Args["params"].(model.InviteMemberRequest))
})
if err != nil {
ec.Error(ctx, err)
@@ -10362,7 +10908,7 @@ func (ec *executionContext) _Mutation__invite_members(ctx context.Context, field
}
res := resTmp.(*model.InviteMembersResponse)
fc.Result = res
- return ec.marshalNInviteMembersResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐInviteMembersResponse(ctx, field.Selections, res)
+ return ec.marshalNInviteMembersResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐInviteMembersResponse(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Mutation__invite_members(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
@@ -10407,9 +10953,9 @@ func (ec *executionContext) _Mutation__revoke_access(ctx context.Context, field
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
- return ec.resolvers.Mutation().RevokeAccess(rctx, fc.Args["param"].(model.UpdateAccessInput))
+ return ec.resolvers.Mutation().RevokeAccess(rctx, fc.Args["param"].(model.UpdateAccessRequest))
})
if err != nil {
ec.Error(ctx, err)
@@ -10423,7 +10969,7 @@ func (ec *executionContext) _Mutation__revoke_access(ctx context.Context, field
}
res := resTmp.(*model.Response)
fc.Result = res
- return ec.marshalNResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐResponse(ctx, field.Selections, res)
+ return ec.marshalNResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐResponse(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Mutation__revoke_access(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
@@ -10466,9 +11012,9 @@ func (ec *executionContext) _Mutation__enable_access(ctx context.Context, field
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
- return ec.resolvers.Mutation().EnableAccess(rctx, fc.Args["param"].(model.UpdateAccessInput))
+ return ec.resolvers.Mutation().EnableAccess(rctx, fc.Args["param"].(model.UpdateAccessRequest))
})
if err != nil {
ec.Error(ctx, err)
@@ -10482,7 +11028,7 @@ func (ec *executionContext) _Mutation__enable_access(ctx context.Context, field
}
res := resTmp.(*model.Response)
fc.Result = res
- return ec.marshalNResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐResponse(ctx, field.Selections, res)
+ return ec.marshalNResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐResponse(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Mutation__enable_access(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
@@ -10525,9 +11071,9 @@ func (ec *executionContext) _Mutation__generate_jwt_keys(ctx context.Context, fi
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
- return ec.resolvers.Mutation().GenerateJwtKeys(rctx, fc.Args["params"].(model.GenerateJWTKeysInput))
+ return ec.resolvers.Mutation().GenerateJwtKeys(rctx, fc.Args["params"].(model.GenerateJWTKeysRequest))
})
if err != nil {
ec.Error(ctx, err)
@@ -10541,7 +11087,7 @@ func (ec *executionContext) _Mutation__generate_jwt_keys(ctx context.Context, fi
}
res := resTmp.(*model.GenerateJWTKeysResponse)
fc.Result = res
- return ec.marshalNGenerateJWTKeysResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐGenerateJWTKeysResponse(ctx, field.Selections, res)
+ return ec.marshalNGenerateJWTKeysResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐGenerateJWTKeysResponse(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Mutation__generate_jwt_keys(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
@@ -10588,7 +11134,7 @@ func (ec *executionContext) _Mutation__add_webhook(ctx context.Context, field gr
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.Mutation().AddWebhook(rctx, fc.Args["params"].(model.AddWebhookRequest))
})
@@ -10604,7 +11150,7 @@ func (ec *executionContext) _Mutation__add_webhook(ctx context.Context, field gr
}
res := resTmp.(*model.Response)
fc.Result = res
- return ec.marshalNResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐResponse(ctx, field.Selections, res)
+ return ec.marshalNResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐResponse(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Mutation__add_webhook(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
@@ -10647,7 +11193,7 @@ func (ec *executionContext) _Mutation__update_webhook(ctx context.Context, field
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.Mutation().UpdateWebhook(rctx, fc.Args["params"].(model.UpdateWebhookRequest))
})
@@ -10663,7 +11209,7 @@ func (ec *executionContext) _Mutation__update_webhook(ctx context.Context, field
}
res := resTmp.(*model.Response)
fc.Result = res
- return ec.marshalNResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐResponse(ctx, field.Selections, res)
+ return ec.marshalNResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐResponse(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Mutation__update_webhook(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
@@ -10706,7 +11252,7 @@ func (ec *executionContext) _Mutation__delete_webhook(ctx context.Context, field
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.Mutation().DeleteWebhook(rctx, fc.Args["params"].(model.WebhookRequest))
})
@@ -10722,7 +11268,7 @@ func (ec *executionContext) _Mutation__delete_webhook(ctx context.Context, field
}
res := resTmp.(*model.Response)
fc.Result = res
- return ec.marshalNResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐResponse(ctx, field.Selections, res)
+ return ec.marshalNResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐResponse(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Mutation__delete_webhook(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
@@ -10765,7 +11311,7 @@ func (ec *executionContext) _Mutation__test_endpoint(ctx context.Context, field
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.Mutation().TestEndpoint(rctx, fc.Args["params"].(model.TestEndpointRequest))
})
@@ -10781,7 +11327,7 @@ func (ec *executionContext) _Mutation__test_endpoint(ctx context.Context, field
}
res := resTmp.(*model.TestEndpointResponse)
fc.Result = res
- return ec.marshalNTestEndpointResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐTestEndpointResponse(ctx, field.Selections, res)
+ return ec.marshalNTestEndpointResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐTestEndpointResponse(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Mutation__test_endpoint(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
@@ -10826,7 +11372,7 @@ func (ec *executionContext) _Mutation__add_email_template(ctx context.Context, f
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.Mutation().AddEmailTemplate(rctx, fc.Args["params"].(model.AddEmailTemplateRequest))
})
@@ -10842,7 +11388,7 @@ func (ec *executionContext) _Mutation__add_email_template(ctx context.Context, f
}
res := resTmp.(*model.Response)
fc.Result = res
- return ec.marshalNResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐResponse(ctx, field.Selections, res)
+ return ec.marshalNResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐResponse(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Mutation__add_email_template(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
@@ -10885,7 +11431,7 @@ func (ec *executionContext) _Mutation__update_email_template(ctx context.Context
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.Mutation().UpdateEmailTemplate(rctx, fc.Args["params"].(model.UpdateEmailTemplateRequest))
})
@@ -10901,7 +11447,7 @@ func (ec *executionContext) _Mutation__update_email_template(ctx context.Context
}
res := resTmp.(*model.Response)
fc.Result = res
- return ec.marshalNResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐResponse(ctx, field.Selections, res)
+ return ec.marshalNResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐResponse(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Mutation__update_email_template(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
@@ -10944,7 +11490,7 @@ func (ec *executionContext) _Mutation__delete_email_template(ctx context.Context
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.Mutation().DeleteEmailTemplate(rctx, fc.Args["params"].(model.DeleteEmailTemplateRequest))
})
@@ -10960,7 +11506,7 @@ func (ec *executionContext) _Mutation__delete_email_template(ctx context.Context
}
res := resTmp.(*model.Response)
fc.Result = res
- return ec.marshalNResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐResponse(ctx, field.Selections, res)
+ return ec.marshalNResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐResponse(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Mutation__delete_email_template(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
@@ -11003,7 +11549,7 @@ func (ec *executionContext) _Pagination_limit(ctx context.Context, field graphql
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Limit, nil
})
@@ -11022,7 +11568,7 @@ func (ec *executionContext) _Pagination_limit(ctx context.Context, field graphql
return ec.marshalNInt642int64(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Pagination_limit(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Pagination_limit(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Pagination",
Field: field,
@@ -11047,7 +11593,7 @@ func (ec *executionContext) _Pagination_page(ctx context.Context, field graphql.
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Page, nil
})
@@ -11066,7 +11612,7 @@ func (ec *executionContext) _Pagination_page(ctx context.Context, field graphql.
return ec.marshalNInt642int64(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Pagination_page(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Pagination_page(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Pagination",
Field: field,
@@ -11091,7 +11637,7 @@ func (ec *executionContext) _Pagination_offset(ctx context.Context, field graphq
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Offset, nil
})
@@ -11110,7 +11656,7 @@ func (ec *executionContext) _Pagination_offset(ctx context.Context, field graphq
return ec.marshalNInt642int64(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Pagination_offset(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Pagination_offset(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Pagination",
Field: field,
@@ -11135,7 +11681,7 @@ func (ec *executionContext) _Pagination_total(ctx context.Context, field graphql
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Total, nil
})
@@ -11154,7 +11700,7 @@ func (ec *executionContext) _Pagination_total(ctx context.Context, field graphql
return ec.marshalNInt642int64(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Pagination_total(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Pagination_total(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Pagination",
Field: field,
@@ -11179,7 +11725,7 @@ func (ec *executionContext) _Query_meta(ctx context.Context, field graphql.Colle
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.Query().Meta(rctx)
})
@@ -11195,10 +11741,10 @@ func (ec *executionContext) _Query_meta(ctx context.Context, field graphql.Colle
}
res := resTmp.(*model.Meta)
fc.Result = res
- return ec.marshalNMeta2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐMeta(ctx, field.Selections, res)
+ return ec.marshalNMeta2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐMeta(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Query_meta(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Query_meta(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Query",
Field: field,
@@ -11265,9 +11811,9 @@ func (ec *executionContext) _Query_session(ctx context.Context, field graphql.Co
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
- return ec.resolvers.Query().Session(rctx, fc.Args["params"].(*model.SessionQueryInput))
+ return ec.resolvers.Query().Session(rctx, fc.Args["params"].(*model.SessionQueryRequest))
})
if err != nil {
ec.Error(ctx, err)
@@ -11281,7 +11827,7 @@ func (ec *executionContext) _Query_session(ctx context.Context, field graphql.Co
}
res := resTmp.(*model.AuthResponse)
fc.Result = res
- return ec.marshalNAuthResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐAuthResponse(ctx, field.Selections, res)
+ return ec.marshalNAuthResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐAuthResponse(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Query_session(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
@@ -11346,659 +11892,82 @@ func (ec *executionContext) _Query_profile(ctx context.Context, field graphql.Co
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
- ctx = rctx // use context from middleware stack in children
- return ec.resolvers.Query().Profile(rctx)
- })
- if err != nil {
- ec.Error(ctx, err)
- return graphql.Null
- }
- if resTmp == nil {
- if !graphql.HasFieldError(ctx, fc) {
- ec.Errorf(ctx, "must not be null")
- }
- return graphql.Null
- }
- res := resTmp.(*model.User)
- fc.Result = res
- return ec.marshalNUser2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐUser(ctx, field.Selections, res)
-}
-
-func (ec *executionContext) fieldContext_Query_profile(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
- fc = &graphql.FieldContext{
- Object: "Query",
- Field: field,
- IsMethod: true,
- IsResolver: true,
- Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
- switch field.Name {
- case "id":
- return ec.fieldContext_User_id(ctx, field)
- case "email":
- return ec.fieldContext_User_email(ctx, field)
- case "email_verified":
- return ec.fieldContext_User_email_verified(ctx, field)
- case "signup_methods":
- return ec.fieldContext_User_signup_methods(ctx, field)
- case "given_name":
- return ec.fieldContext_User_given_name(ctx, field)
- case "family_name":
- return ec.fieldContext_User_family_name(ctx, field)
- case "middle_name":
- return ec.fieldContext_User_middle_name(ctx, field)
- case "nickname":
- return ec.fieldContext_User_nickname(ctx, field)
- case "preferred_username":
- return ec.fieldContext_User_preferred_username(ctx, field)
- case "gender":
- return ec.fieldContext_User_gender(ctx, field)
- case "birthdate":
- return ec.fieldContext_User_birthdate(ctx, field)
- case "phone_number":
- return ec.fieldContext_User_phone_number(ctx, field)
- case "phone_number_verified":
- return ec.fieldContext_User_phone_number_verified(ctx, field)
- case "picture":
- return ec.fieldContext_User_picture(ctx, field)
- case "roles":
- return ec.fieldContext_User_roles(ctx, field)
- case "created_at":
- return ec.fieldContext_User_created_at(ctx, field)
- case "updated_at":
- return ec.fieldContext_User_updated_at(ctx, field)
- case "revoked_timestamp":
- return ec.fieldContext_User_revoked_timestamp(ctx, field)
- case "is_multi_factor_auth_enabled":
- return ec.fieldContext_User_is_multi_factor_auth_enabled(ctx, field)
- case "app_data":
- return ec.fieldContext_User_app_data(ctx, field)
- }
- return nil, fmt.Errorf("no field named %q was found under type User", field.Name)
- },
- }
- return fc, nil
-}
-
-func (ec *executionContext) _Query_validate_jwt_token(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
- fc, err := ec.fieldContext_Query_validate_jwt_token(ctx, field)
- if err != nil {
- return graphql.Null
- }
- ctx = graphql.WithFieldContext(ctx, fc)
- defer func() {
- if r := recover(); r != nil {
- ec.Error(ctx, ec.Recover(ctx, r))
- ret = graphql.Null
- }
- }()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
- ctx = rctx // use context from middleware stack in children
- return ec.resolvers.Query().ValidateJwtToken(rctx, fc.Args["params"].(model.ValidateJWTTokenInput))
- })
- if err != nil {
- ec.Error(ctx, err)
- return graphql.Null
- }
- if resTmp == nil {
- if !graphql.HasFieldError(ctx, fc) {
- ec.Errorf(ctx, "must not be null")
- }
- return graphql.Null
- }
- res := resTmp.(*model.ValidateJWTTokenResponse)
- fc.Result = res
- return ec.marshalNValidateJWTTokenResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐValidateJWTTokenResponse(ctx, field.Selections, res)
-}
-
-func (ec *executionContext) fieldContext_Query_validate_jwt_token(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
- fc = &graphql.FieldContext{
- Object: "Query",
- Field: field,
- IsMethod: true,
- IsResolver: true,
- Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
- switch field.Name {
- case "is_valid":
- return ec.fieldContext_ValidateJWTTokenResponse_is_valid(ctx, field)
- case "claims":
- return ec.fieldContext_ValidateJWTTokenResponse_claims(ctx, field)
- }
- return nil, fmt.Errorf("no field named %q was found under type ValidateJWTTokenResponse", field.Name)
- },
- }
- defer func() {
- if r := recover(); r != nil {
- err = ec.Recover(ctx, r)
- ec.Error(ctx, err)
- }
- }()
- ctx = graphql.WithFieldContext(ctx, fc)
- if fc.Args, err = ec.field_Query_validate_jwt_token_args(ctx, field.ArgumentMap(ec.Variables)); err != nil {
- ec.Error(ctx, err)
- return fc, err
- }
- return fc, nil
-}
-
-func (ec *executionContext) _Query_validate_session(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
- fc, err := ec.fieldContext_Query_validate_session(ctx, field)
- if err != nil {
- return graphql.Null
- }
- ctx = graphql.WithFieldContext(ctx, fc)
- defer func() {
- if r := recover(); r != nil {
- ec.Error(ctx, ec.Recover(ctx, r))
- ret = graphql.Null
- }
- }()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
- ctx = rctx // use context from middleware stack in children
- return ec.resolvers.Query().ValidateSession(rctx, fc.Args["params"].(*model.ValidateSessionInput))
- })
- if err != nil {
- ec.Error(ctx, err)
- return graphql.Null
- }
- if resTmp == nil {
- if !graphql.HasFieldError(ctx, fc) {
- ec.Errorf(ctx, "must not be null")
- }
- return graphql.Null
- }
- res := resTmp.(*model.ValidateSessionResponse)
- fc.Result = res
- return ec.marshalNValidateSessionResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐValidateSessionResponse(ctx, field.Selections, res)
-}
-
-func (ec *executionContext) fieldContext_Query_validate_session(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
- fc = &graphql.FieldContext{
- Object: "Query",
- Field: field,
- IsMethod: true,
- IsResolver: true,
- Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
- switch field.Name {
- case "is_valid":
- return ec.fieldContext_ValidateSessionResponse_is_valid(ctx, field)
- case "user":
- return ec.fieldContext_ValidateSessionResponse_user(ctx, field)
- }
- return nil, fmt.Errorf("no field named %q was found under type ValidateSessionResponse", field.Name)
- },
- }
- defer func() {
- if r := recover(); r != nil {
- err = ec.Recover(ctx, r)
- ec.Error(ctx, err)
- }
- }()
- ctx = graphql.WithFieldContext(ctx, fc)
- if fc.Args, err = ec.field_Query_validate_session_args(ctx, field.ArgumentMap(ec.Variables)); err != nil {
- ec.Error(ctx, err)
- return fc, err
- }
- return fc, nil
-}
-
-func (ec *executionContext) _Query__users(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
- fc, err := ec.fieldContext_Query__users(ctx, field)
- if err != nil {
- return graphql.Null
- }
- ctx = graphql.WithFieldContext(ctx, fc)
- defer func() {
- if r := recover(); r != nil {
- ec.Error(ctx, ec.Recover(ctx, r))
- ret = graphql.Null
- }
- }()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
- ctx = rctx // use context from middleware stack in children
- return ec.resolvers.Query().Users(rctx, fc.Args["params"].(*model.PaginatedInput))
- })
- if err != nil {
- ec.Error(ctx, err)
- return graphql.Null
- }
- if resTmp == nil {
- if !graphql.HasFieldError(ctx, fc) {
- ec.Errorf(ctx, "must not be null")
- }
- return graphql.Null
- }
- res := resTmp.(*model.Users)
- fc.Result = res
- return ec.marshalNUsers2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐUsers(ctx, field.Selections, res)
-}
-
-func (ec *executionContext) fieldContext_Query__users(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
- fc = &graphql.FieldContext{
- Object: "Query",
- Field: field,
- IsMethod: true,
- IsResolver: true,
- Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
- switch field.Name {
- case "pagination":
- return ec.fieldContext_Users_pagination(ctx, field)
- case "users":
- return ec.fieldContext_Users_users(ctx, field)
- }
- return nil, fmt.Errorf("no field named %q was found under type Users", field.Name)
- },
- }
- defer func() {
- if r := recover(); r != nil {
- err = ec.Recover(ctx, r)
- ec.Error(ctx, err)
- }
- }()
- ctx = graphql.WithFieldContext(ctx, fc)
- if fc.Args, err = ec.field_Query__users_args(ctx, field.ArgumentMap(ec.Variables)); err != nil {
- ec.Error(ctx, err)
- return fc, err
- }
- return fc, nil
-}
-
-func (ec *executionContext) _Query__user(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
- fc, err := ec.fieldContext_Query__user(ctx, field)
- if err != nil {
- return graphql.Null
- }
- ctx = graphql.WithFieldContext(ctx, fc)
- defer func() {
- if r := recover(); r != nil {
- ec.Error(ctx, ec.Recover(ctx, r))
- ret = graphql.Null
- }
- }()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
- ctx = rctx // use context from middleware stack in children
- return ec.resolvers.Query().User(rctx, fc.Args["params"].(model.GetUserRequest))
- })
- if err != nil {
- ec.Error(ctx, err)
- return graphql.Null
- }
- if resTmp == nil {
- if !graphql.HasFieldError(ctx, fc) {
- ec.Errorf(ctx, "must not be null")
- }
- return graphql.Null
- }
- res := resTmp.(*model.User)
- fc.Result = res
- return ec.marshalNUser2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐUser(ctx, field.Selections, res)
-}
-
-func (ec *executionContext) fieldContext_Query__user(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
- fc = &graphql.FieldContext{
- Object: "Query",
- Field: field,
- IsMethod: true,
- IsResolver: true,
- Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
- switch field.Name {
- case "id":
- return ec.fieldContext_User_id(ctx, field)
- case "email":
- return ec.fieldContext_User_email(ctx, field)
- case "email_verified":
- return ec.fieldContext_User_email_verified(ctx, field)
- case "signup_methods":
- return ec.fieldContext_User_signup_methods(ctx, field)
- case "given_name":
- return ec.fieldContext_User_given_name(ctx, field)
- case "family_name":
- return ec.fieldContext_User_family_name(ctx, field)
- case "middle_name":
- return ec.fieldContext_User_middle_name(ctx, field)
- case "nickname":
- return ec.fieldContext_User_nickname(ctx, field)
- case "preferred_username":
- return ec.fieldContext_User_preferred_username(ctx, field)
- case "gender":
- return ec.fieldContext_User_gender(ctx, field)
- case "birthdate":
- return ec.fieldContext_User_birthdate(ctx, field)
- case "phone_number":
- return ec.fieldContext_User_phone_number(ctx, field)
- case "phone_number_verified":
- return ec.fieldContext_User_phone_number_verified(ctx, field)
- case "picture":
- return ec.fieldContext_User_picture(ctx, field)
- case "roles":
- return ec.fieldContext_User_roles(ctx, field)
- case "created_at":
- return ec.fieldContext_User_created_at(ctx, field)
- case "updated_at":
- return ec.fieldContext_User_updated_at(ctx, field)
- case "revoked_timestamp":
- return ec.fieldContext_User_revoked_timestamp(ctx, field)
- case "is_multi_factor_auth_enabled":
- return ec.fieldContext_User_is_multi_factor_auth_enabled(ctx, field)
- case "app_data":
- return ec.fieldContext_User_app_data(ctx, field)
- }
- return nil, fmt.Errorf("no field named %q was found under type User", field.Name)
- },
- }
- defer func() {
- if r := recover(); r != nil {
- err = ec.Recover(ctx, r)
- ec.Error(ctx, err)
- }
- }()
- ctx = graphql.WithFieldContext(ctx, fc)
- if fc.Args, err = ec.field_Query__user_args(ctx, field.ArgumentMap(ec.Variables)); err != nil {
- ec.Error(ctx, err)
- return fc, err
- }
- return fc, nil
-}
-
-func (ec *executionContext) _Query__verification_requests(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
- fc, err := ec.fieldContext_Query__verification_requests(ctx, field)
- if err != nil {
- return graphql.Null
- }
- ctx = graphql.WithFieldContext(ctx, fc)
- defer func() {
- if r := recover(); r != nil {
- ec.Error(ctx, ec.Recover(ctx, r))
- ret = graphql.Null
- }
- }()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
- ctx = rctx // use context from middleware stack in children
- return ec.resolvers.Query().VerificationRequests(rctx, fc.Args["params"].(*model.PaginatedInput))
- })
- if err != nil {
- ec.Error(ctx, err)
- return graphql.Null
- }
- if resTmp == nil {
- if !graphql.HasFieldError(ctx, fc) {
- ec.Errorf(ctx, "must not be null")
- }
- return graphql.Null
- }
- res := resTmp.(*model.VerificationRequests)
- fc.Result = res
- return ec.marshalNVerificationRequests2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐVerificationRequests(ctx, field.Selections, res)
-}
-
-func (ec *executionContext) fieldContext_Query__verification_requests(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
- fc = &graphql.FieldContext{
- Object: "Query",
- Field: field,
- IsMethod: true,
- IsResolver: true,
- Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
- switch field.Name {
- case "pagination":
- return ec.fieldContext_VerificationRequests_pagination(ctx, field)
- case "verification_requests":
- return ec.fieldContext_VerificationRequests_verification_requests(ctx, field)
- }
- return nil, fmt.Errorf("no field named %q was found under type VerificationRequests", field.Name)
- },
- }
- defer func() {
- if r := recover(); r != nil {
- err = ec.Recover(ctx, r)
- ec.Error(ctx, err)
- }
- }()
- ctx = graphql.WithFieldContext(ctx, fc)
- if fc.Args, err = ec.field_Query__verification_requests_args(ctx, field.ArgumentMap(ec.Variables)); err != nil {
- ec.Error(ctx, err)
- return fc, err
- }
- return fc, nil
-}
-
-func (ec *executionContext) _Query__admin_session(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
- fc, err := ec.fieldContext_Query__admin_session(ctx, field)
- if err != nil {
- return graphql.Null
- }
- ctx = graphql.WithFieldContext(ctx, fc)
- defer func() {
- if r := recover(); r != nil {
- ec.Error(ctx, ec.Recover(ctx, r))
- ret = graphql.Null
- }
- }()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
- ctx = rctx // use context from middleware stack in children
- return ec.resolvers.Query().AdminSession(rctx)
- })
- if err != nil {
- ec.Error(ctx, err)
- return graphql.Null
- }
- if resTmp == nil {
- if !graphql.HasFieldError(ctx, fc) {
- ec.Errorf(ctx, "must not be null")
- }
- return graphql.Null
- }
- res := resTmp.(*model.Response)
- fc.Result = res
- return ec.marshalNResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐResponse(ctx, field.Selections, res)
-}
-
-func (ec *executionContext) fieldContext_Query__admin_session(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
- fc = &graphql.FieldContext{
- Object: "Query",
- Field: field,
- IsMethod: true,
- IsResolver: true,
- Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
- switch field.Name {
- case "message":
- return ec.fieldContext_Response_message(ctx, field)
- }
- return nil, fmt.Errorf("no field named %q was found under type Response", field.Name)
- },
- }
- return fc, nil
-}
-
-func (ec *executionContext) _Query__env(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
- fc, err := ec.fieldContext_Query__env(ctx, field)
- if err != nil {
- return graphql.Null
- }
- ctx = graphql.WithFieldContext(ctx, fc)
- defer func() {
- if r := recover(); r != nil {
- ec.Error(ctx, ec.Recover(ctx, r))
- ret = graphql.Null
- }
- }()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
- ctx = rctx // use context from middleware stack in children
- return ec.resolvers.Query().Env(rctx)
- })
- if err != nil {
- ec.Error(ctx, err)
- return graphql.Null
- }
- if resTmp == nil {
- if !graphql.HasFieldError(ctx, fc) {
- ec.Errorf(ctx, "must not be null")
- }
- return graphql.Null
- }
- res := resTmp.(*model.Env)
- fc.Result = res
- return ec.marshalNEnv2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐEnv(ctx, field.Selections, res)
-}
-
-func (ec *executionContext) fieldContext_Query__env(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
- fc = &graphql.FieldContext{
- Object: "Query",
- Field: field,
- IsMethod: true,
- IsResolver: true,
- Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
- switch field.Name {
- case "ACCESS_TOKEN_EXPIRY_TIME":
- return ec.fieldContext_Env_ACCESS_TOKEN_EXPIRY_TIME(ctx, field)
- case "ADMIN_SECRET":
- return ec.fieldContext_Env_ADMIN_SECRET(ctx, field)
- case "DATABASE_NAME":
- return ec.fieldContext_Env_DATABASE_NAME(ctx, field)
- case "DATABASE_URL":
- return ec.fieldContext_Env_DATABASE_URL(ctx, field)
- case "DATABASE_TYPE":
- return ec.fieldContext_Env_DATABASE_TYPE(ctx, field)
- case "DATABASE_USERNAME":
- return ec.fieldContext_Env_DATABASE_USERNAME(ctx, field)
- case "DATABASE_PASSWORD":
- return ec.fieldContext_Env_DATABASE_PASSWORD(ctx, field)
- case "DATABASE_HOST":
- return ec.fieldContext_Env_DATABASE_HOST(ctx, field)
- case "DATABASE_PORT":
- return ec.fieldContext_Env_DATABASE_PORT(ctx, field)
- case "CLIENT_ID":
- return ec.fieldContext_Env_CLIENT_ID(ctx, field)
- case "CLIENT_SECRET":
- return ec.fieldContext_Env_CLIENT_SECRET(ctx, field)
- case "CUSTOM_ACCESS_TOKEN_SCRIPT":
- return ec.fieldContext_Env_CUSTOM_ACCESS_TOKEN_SCRIPT(ctx, field)
- case "SMTP_HOST":
- return ec.fieldContext_Env_SMTP_HOST(ctx, field)
- case "SMTP_PORT":
- return ec.fieldContext_Env_SMTP_PORT(ctx, field)
- case "SMTP_USERNAME":
- return ec.fieldContext_Env_SMTP_USERNAME(ctx, field)
- case "SMTP_PASSWORD":
- return ec.fieldContext_Env_SMTP_PASSWORD(ctx, field)
- case "SMTP_LOCAL_NAME":
- return ec.fieldContext_Env_SMTP_LOCAL_NAME(ctx, field)
- case "SENDER_EMAIL":
- return ec.fieldContext_Env_SENDER_EMAIL(ctx, field)
- case "SENDER_NAME":
- return ec.fieldContext_Env_SENDER_NAME(ctx, field)
- case "JWT_TYPE":
- return ec.fieldContext_Env_JWT_TYPE(ctx, field)
- case "JWT_SECRET":
- return ec.fieldContext_Env_JWT_SECRET(ctx, field)
- case "JWT_PRIVATE_KEY":
- return ec.fieldContext_Env_JWT_PRIVATE_KEY(ctx, field)
- case "JWT_PUBLIC_KEY":
- return ec.fieldContext_Env_JWT_PUBLIC_KEY(ctx, field)
- case "ALLOWED_ORIGINS":
- return ec.fieldContext_Env_ALLOWED_ORIGINS(ctx, field)
- case "APP_URL":
- return ec.fieldContext_Env_APP_URL(ctx, field)
- case "REDIS_URL":
- return ec.fieldContext_Env_REDIS_URL(ctx, field)
- case "RESET_PASSWORD_URL":
- return ec.fieldContext_Env_RESET_PASSWORD_URL(ctx, field)
- case "DISABLE_EMAIL_VERIFICATION":
- return ec.fieldContext_Env_DISABLE_EMAIL_VERIFICATION(ctx, field)
- case "DISABLE_BASIC_AUTHENTICATION":
- return ec.fieldContext_Env_DISABLE_BASIC_AUTHENTICATION(ctx, field)
- case "DISABLE_MOBILE_BASIC_AUTHENTICATION":
- return ec.fieldContext_Env_DISABLE_MOBILE_BASIC_AUTHENTICATION(ctx, field)
- case "DISABLE_MAGIC_LINK_LOGIN":
- return ec.fieldContext_Env_DISABLE_MAGIC_LINK_LOGIN(ctx, field)
- case "DISABLE_LOGIN_PAGE":
- return ec.fieldContext_Env_DISABLE_LOGIN_PAGE(ctx, field)
- case "DISABLE_SIGN_UP":
- return ec.fieldContext_Env_DISABLE_SIGN_UP(ctx, field)
- case "DISABLE_REDIS_FOR_ENV":
- return ec.fieldContext_Env_DISABLE_REDIS_FOR_ENV(ctx, field)
- case "DISABLE_STRONG_PASSWORD":
- return ec.fieldContext_Env_DISABLE_STRONG_PASSWORD(ctx, field)
- case "DISABLE_MULTI_FACTOR_AUTHENTICATION":
- return ec.fieldContext_Env_DISABLE_MULTI_FACTOR_AUTHENTICATION(ctx, field)
- case "ENFORCE_MULTI_FACTOR_AUTHENTICATION":
- return ec.fieldContext_Env_ENFORCE_MULTI_FACTOR_AUTHENTICATION(ctx, field)
- case "ROLES":
- return ec.fieldContext_Env_ROLES(ctx, field)
- case "PROTECTED_ROLES":
- return ec.fieldContext_Env_PROTECTED_ROLES(ctx, field)
- case "DEFAULT_ROLES":
- return ec.fieldContext_Env_DEFAULT_ROLES(ctx, field)
- case "JWT_ROLE_CLAIM":
- return ec.fieldContext_Env_JWT_ROLE_CLAIM(ctx, field)
- case "GOOGLE_CLIENT_ID":
- return ec.fieldContext_Env_GOOGLE_CLIENT_ID(ctx, field)
- case "GOOGLE_CLIENT_SECRET":
- return ec.fieldContext_Env_GOOGLE_CLIENT_SECRET(ctx, field)
- case "GITHUB_CLIENT_ID":
- return ec.fieldContext_Env_GITHUB_CLIENT_ID(ctx, field)
- case "GITHUB_CLIENT_SECRET":
- return ec.fieldContext_Env_GITHUB_CLIENT_SECRET(ctx, field)
- case "FACEBOOK_CLIENT_ID":
- return ec.fieldContext_Env_FACEBOOK_CLIENT_ID(ctx, field)
- case "FACEBOOK_CLIENT_SECRET":
- return ec.fieldContext_Env_FACEBOOK_CLIENT_SECRET(ctx, field)
- case "LINKEDIN_CLIENT_ID":
- return ec.fieldContext_Env_LINKEDIN_CLIENT_ID(ctx, field)
- case "LINKEDIN_CLIENT_SECRET":
- return ec.fieldContext_Env_LINKEDIN_CLIENT_SECRET(ctx, field)
- case "APPLE_CLIENT_ID":
- return ec.fieldContext_Env_APPLE_CLIENT_ID(ctx, field)
- case "APPLE_CLIENT_SECRET":
- return ec.fieldContext_Env_APPLE_CLIENT_SECRET(ctx, field)
- case "DISCORD_CLIENT_ID":
- return ec.fieldContext_Env_DISCORD_CLIENT_ID(ctx, field)
- case "DISCORD_CLIENT_SECRET":
- return ec.fieldContext_Env_DISCORD_CLIENT_SECRET(ctx, field)
- case "TWITTER_CLIENT_ID":
- return ec.fieldContext_Env_TWITTER_CLIENT_ID(ctx, field)
- case "TWITTER_CLIENT_SECRET":
- return ec.fieldContext_Env_TWITTER_CLIENT_SECRET(ctx, field)
- case "MICROSOFT_CLIENT_ID":
- return ec.fieldContext_Env_MICROSOFT_CLIENT_ID(ctx, field)
- case "MICROSOFT_CLIENT_SECRET":
- return ec.fieldContext_Env_MICROSOFT_CLIENT_SECRET(ctx, field)
- case "MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID":
- return ec.fieldContext_Env_MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID(ctx, field)
- case "TWITCH_CLIENT_ID":
- return ec.fieldContext_Env_TWITCH_CLIENT_ID(ctx, field)
- case "TWITCH_CLIENT_SECRET":
- return ec.fieldContext_Env_TWITCH_CLIENT_SECRET(ctx, field)
- case "ROBLOX_CLIENT_ID":
- return ec.fieldContext_Env_ROBLOX_CLIENT_ID(ctx, field)
- case "ROBLOX_CLIENT_SECRET":
- return ec.fieldContext_Env_ROBLOX_CLIENT_SECRET(ctx, field)
- case "ORGANIZATION_NAME":
- return ec.fieldContext_Env_ORGANIZATION_NAME(ctx, field)
- case "ORGANIZATION_LOGO":
- return ec.fieldContext_Env_ORGANIZATION_LOGO(ctx, field)
- case "APP_COOKIE_SECURE":
- return ec.fieldContext_Env_APP_COOKIE_SECURE(ctx, field)
- case "ADMIN_COOKIE_SECURE":
- return ec.fieldContext_Env_ADMIN_COOKIE_SECURE(ctx, field)
- case "DEFAULT_AUTHORIZE_RESPONSE_TYPE":
- return ec.fieldContext_Env_DEFAULT_AUTHORIZE_RESPONSE_TYPE(ctx, field)
- case "DEFAULT_AUTHORIZE_RESPONSE_MODE":
- return ec.fieldContext_Env_DEFAULT_AUTHORIZE_RESPONSE_MODE(ctx, field)
- case "DISABLE_PLAYGROUND":
- return ec.fieldContext_Env_DISABLE_PLAYGROUND(ctx, field)
- case "DISABLE_MAIL_OTP_LOGIN":
- return ec.fieldContext_Env_DISABLE_MAIL_OTP_LOGIN(ctx, field)
- case "DISABLE_TOTP_LOGIN":
- return ec.fieldContext_Env_DISABLE_TOTP_LOGIN(ctx, field)
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
+ ctx = rctx // use context from middleware stack in children
+ return ec.resolvers.Query().Profile(rctx)
+ })
+ if err != nil {
+ ec.Error(ctx, err)
+ return graphql.Null
+ }
+ if resTmp == nil {
+ if !graphql.HasFieldError(ctx, fc) {
+ ec.Errorf(ctx, "must not be null")
+ }
+ return graphql.Null
+ }
+ res := resTmp.(*model.User)
+ fc.Result = res
+ return ec.marshalNUser2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐUser(ctx, field.Selections, res)
+}
+
+func (ec *executionContext) fieldContext_Query_profile(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+ fc = &graphql.FieldContext{
+ Object: "Query",
+ Field: field,
+ IsMethod: true,
+ IsResolver: true,
+ Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
+ switch field.Name {
+ case "id":
+ return ec.fieldContext_User_id(ctx, field)
+ case "email":
+ return ec.fieldContext_User_email(ctx, field)
+ case "email_verified":
+ return ec.fieldContext_User_email_verified(ctx, field)
+ case "signup_methods":
+ return ec.fieldContext_User_signup_methods(ctx, field)
+ case "given_name":
+ return ec.fieldContext_User_given_name(ctx, field)
+ case "family_name":
+ return ec.fieldContext_User_family_name(ctx, field)
+ case "middle_name":
+ return ec.fieldContext_User_middle_name(ctx, field)
+ case "nickname":
+ return ec.fieldContext_User_nickname(ctx, field)
+ case "preferred_username":
+ return ec.fieldContext_User_preferred_username(ctx, field)
+ case "gender":
+ return ec.fieldContext_User_gender(ctx, field)
+ case "birthdate":
+ return ec.fieldContext_User_birthdate(ctx, field)
+ case "phone_number":
+ return ec.fieldContext_User_phone_number(ctx, field)
+ case "phone_number_verified":
+ return ec.fieldContext_User_phone_number_verified(ctx, field)
+ case "picture":
+ return ec.fieldContext_User_picture(ctx, field)
+ case "roles":
+ return ec.fieldContext_User_roles(ctx, field)
+ case "created_at":
+ return ec.fieldContext_User_created_at(ctx, field)
+ case "updated_at":
+ return ec.fieldContext_User_updated_at(ctx, field)
+ case "revoked_timestamp":
+ return ec.fieldContext_User_revoked_timestamp(ctx, field)
+ case "is_multi_factor_auth_enabled":
+ return ec.fieldContext_User_is_multi_factor_auth_enabled(ctx, field)
+ case "app_data":
+ return ec.fieldContext_User_app_data(ctx, field)
}
- return nil, fmt.Errorf("no field named %q was found under type Env", field.Name)
+ return nil, fmt.Errorf("no field named %q was found under type User", field.Name)
},
}
return fc, nil
}
-func (ec *executionContext) _Query__webhook(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
- fc, err := ec.fieldContext_Query__webhook(ctx, field)
+func (ec *executionContext) _Query_validate_jwt_token(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
+ fc, err := ec.fieldContext_Query_validate_jwt_token(ctx, field)
if err != nil {
return graphql.Null
}
@@ -12009,9 +11978,9 @@ func (ec *executionContext) _Query__webhook(ctx context.Context, field graphql.C
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
- return ec.resolvers.Query().Webhook(rctx, fc.Args["params"].(model.WebhookRequest))
+ return ec.resolvers.Query().ValidateJwtToken(rctx, fc.Args["params"].(model.ValidateJWTTokenRequest))
})
if err != nil {
ec.Error(ctx, err)
@@ -12023,12 +11992,12 @@ func (ec *executionContext) _Query__webhook(ctx context.Context, field graphql.C
}
return graphql.Null
}
- res := resTmp.(*model.Webhook)
+ res := resTmp.(*model.ValidateJWTTokenResponse)
fc.Result = res
- return ec.marshalNWebhook2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐWebhook(ctx, field.Selections, res)
+ return ec.marshalNValidateJWTTokenResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐValidateJWTTokenResponse(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Query__webhook(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Query_validate_jwt_token(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Query",
Field: field,
@@ -12036,24 +12005,12 @@ func (ec *executionContext) fieldContext_Query__webhook(ctx context.Context, fie
IsResolver: true,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
switch field.Name {
- case "id":
- return ec.fieldContext_Webhook_id(ctx, field)
- case "event_name":
- return ec.fieldContext_Webhook_event_name(ctx, field)
- case "event_description":
- return ec.fieldContext_Webhook_event_description(ctx, field)
- case "endpoint":
- return ec.fieldContext_Webhook_endpoint(ctx, field)
- case "enabled":
- return ec.fieldContext_Webhook_enabled(ctx, field)
- case "headers":
- return ec.fieldContext_Webhook_headers(ctx, field)
- case "created_at":
- return ec.fieldContext_Webhook_created_at(ctx, field)
- case "updated_at":
- return ec.fieldContext_Webhook_updated_at(ctx, field)
+ case "is_valid":
+ return ec.fieldContext_ValidateJWTTokenResponse_is_valid(ctx, field)
+ case "claims":
+ return ec.fieldContext_ValidateJWTTokenResponse_claims(ctx, field)
}
- return nil, fmt.Errorf("no field named %q was found under type Webhook", field.Name)
+ return nil, fmt.Errorf("no field named %q was found under type ValidateJWTTokenResponse", field.Name)
},
}
defer func() {
@@ -12063,15 +12020,15 @@ func (ec *executionContext) fieldContext_Query__webhook(ctx context.Context, fie
}
}()
ctx = graphql.WithFieldContext(ctx, fc)
- if fc.Args, err = ec.field_Query__webhook_args(ctx, field.ArgumentMap(ec.Variables)); err != nil {
+ if fc.Args, err = ec.field_Query_validate_jwt_token_args(ctx, field.ArgumentMap(ec.Variables)); err != nil {
ec.Error(ctx, err)
return fc, err
}
return fc, nil
}
-func (ec *executionContext) _Query__webhooks(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
- fc, err := ec.fieldContext_Query__webhooks(ctx, field)
+func (ec *executionContext) _Query_validate_session(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
+ fc, err := ec.fieldContext_Query_validate_session(ctx, field)
if err != nil {
return graphql.Null
}
@@ -12082,9 +12039,9 @@ func (ec *executionContext) _Query__webhooks(ctx context.Context, field graphql.
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
- return ec.resolvers.Query().Webhooks(rctx, fc.Args["params"].(*model.PaginatedInput))
+ return ec.resolvers.Query().ValidateSession(rctx, fc.Args["params"].(*model.ValidateSessionRequest))
})
if err != nil {
ec.Error(ctx, err)
@@ -12096,12 +12053,12 @@ func (ec *executionContext) _Query__webhooks(ctx context.Context, field graphql.
}
return graphql.Null
}
- res := resTmp.(*model.Webhooks)
+ res := resTmp.(*model.ValidateSessionResponse)
fc.Result = res
- return ec.marshalNWebhooks2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐWebhooks(ctx, field.Selections, res)
+ return ec.marshalNValidateSessionResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐValidateSessionResponse(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Query__webhooks(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Query_validate_session(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Query",
Field: field,
@@ -12109,12 +12066,12 @@ func (ec *executionContext) fieldContext_Query__webhooks(ctx context.Context, fi
IsResolver: true,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
switch field.Name {
- case "pagination":
- return ec.fieldContext_Webhooks_pagination(ctx, field)
- case "webhooks":
- return ec.fieldContext_Webhooks_webhooks(ctx, field)
+ case "is_valid":
+ return ec.fieldContext_ValidateSessionResponse_is_valid(ctx, field)
+ case "user":
+ return ec.fieldContext_ValidateSessionResponse_user(ctx, field)
}
- return nil, fmt.Errorf("no field named %q was found under type Webhooks", field.Name)
+ return nil, fmt.Errorf("no field named %q was found under type ValidateSessionResponse", field.Name)
},
}
defer func() {
@@ -12124,15 +12081,15 @@ func (ec *executionContext) fieldContext_Query__webhooks(ctx context.Context, fi
}
}()
ctx = graphql.WithFieldContext(ctx, fc)
- if fc.Args, err = ec.field_Query__webhooks_args(ctx, field.ArgumentMap(ec.Variables)); err != nil {
+ if fc.Args, err = ec.field_Query_validate_session_args(ctx, field.ArgumentMap(ec.Variables)); err != nil {
ec.Error(ctx, err)
return fc, err
}
return fc, nil
}
-func (ec *executionContext) _Query__webhook_logs(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
- fc, err := ec.fieldContext_Query__webhook_logs(ctx, field)
+func (ec *executionContext) _Query__users(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
+ fc, err := ec.fieldContext_Query__users(ctx, field)
if err != nil {
return graphql.Null
}
@@ -12143,9 +12100,9 @@ func (ec *executionContext) _Query__webhook_logs(ctx context.Context, field grap
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
- return ec.resolvers.Query().WebhookLogs(rctx, fc.Args["params"].(*model.ListWebhookLogRequest))
+ return ec.resolvers.Query().Users(rctx, fc.Args["params"].(*model.PaginatedRequest))
})
if err != nil {
ec.Error(ctx, err)
@@ -12157,12 +12114,12 @@ func (ec *executionContext) _Query__webhook_logs(ctx context.Context, field grap
}
return graphql.Null
}
- res := resTmp.(*model.WebhookLogs)
+ res := resTmp.(*model.Users)
fc.Result = res
- return ec.marshalNWebhookLogs2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐWebhookLogs(ctx, field.Selections, res)
+ return ec.marshalNUsers2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐUsers(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Query__webhook_logs(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Query__users(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Query",
Field: field,
@@ -12171,11 +12128,11 @@ func (ec *executionContext) fieldContext_Query__webhook_logs(ctx context.Context
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
switch field.Name {
case "pagination":
- return ec.fieldContext_WebhookLogs_pagination(ctx, field)
- case "webhook_logs":
- return ec.fieldContext_WebhookLogs_webhook_logs(ctx, field)
+ return ec.fieldContext_Users_pagination(ctx, field)
+ case "users":
+ return ec.fieldContext_Users_users(ctx, field)
}
- return nil, fmt.Errorf("no field named %q was found under type WebhookLogs", field.Name)
+ return nil, fmt.Errorf("no field named %q was found under type Users", field.Name)
},
}
defer func() {
@@ -12185,15 +12142,15 @@ func (ec *executionContext) fieldContext_Query__webhook_logs(ctx context.Context
}
}()
ctx = graphql.WithFieldContext(ctx, fc)
- if fc.Args, err = ec.field_Query__webhook_logs_args(ctx, field.ArgumentMap(ec.Variables)); err != nil {
+ if fc.Args, err = ec.field_Query__users_args(ctx, field.ArgumentMap(ec.Variables)); err != nil {
ec.Error(ctx, err)
return fc, err
}
return fc, nil
}
-func (ec *executionContext) _Query__email_templates(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
- fc, err := ec.fieldContext_Query__email_templates(ctx, field)
+func (ec *executionContext) _Query__user(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
+ fc, err := ec.fieldContext_Query__user(ctx, field)
if err != nil {
return graphql.Null
}
@@ -12204,9 +12161,9 @@ func (ec *executionContext) _Query__email_templates(ctx context.Context, field g
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
- return ec.resolvers.Query().EmailTemplates(rctx, fc.Args["params"].(*model.PaginatedInput))
+ return ec.resolvers.Query().User(rctx, fc.Args["params"].(model.GetUserRequest))
})
if err != nil {
ec.Error(ctx, err)
@@ -12218,12 +12175,12 @@ func (ec *executionContext) _Query__email_templates(ctx context.Context, field g
}
return graphql.Null
}
- res := resTmp.(*model.EmailTemplates)
+ res := resTmp.(*model.User)
fc.Result = res
- return ec.marshalNEmailTemplates2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐEmailTemplates(ctx, field.Selections, res)
+ return ec.marshalNUser2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐUser(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Query__email_templates(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Query__user(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Query",
Field: field,
@@ -12231,12 +12188,48 @@ func (ec *executionContext) fieldContext_Query__email_templates(ctx context.Cont
IsResolver: true,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
switch field.Name {
- case "pagination":
- return ec.fieldContext_EmailTemplates_pagination(ctx, field)
- case "email_templates":
- return ec.fieldContext_EmailTemplates_email_templates(ctx, field)
+ case "id":
+ return ec.fieldContext_User_id(ctx, field)
+ case "email":
+ return ec.fieldContext_User_email(ctx, field)
+ case "email_verified":
+ return ec.fieldContext_User_email_verified(ctx, field)
+ case "signup_methods":
+ return ec.fieldContext_User_signup_methods(ctx, field)
+ case "given_name":
+ return ec.fieldContext_User_given_name(ctx, field)
+ case "family_name":
+ return ec.fieldContext_User_family_name(ctx, field)
+ case "middle_name":
+ return ec.fieldContext_User_middle_name(ctx, field)
+ case "nickname":
+ return ec.fieldContext_User_nickname(ctx, field)
+ case "preferred_username":
+ return ec.fieldContext_User_preferred_username(ctx, field)
+ case "gender":
+ return ec.fieldContext_User_gender(ctx, field)
+ case "birthdate":
+ return ec.fieldContext_User_birthdate(ctx, field)
+ case "phone_number":
+ return ec.fieldContext_User_phone_number(ctx, field)
+ case "phone_number_verified":
+ return ec.fieldContext_User_phone_number_verified(ctx, field)
+ case "picture":
+ return ec.fieldContext_User_picture(ctx, field)
+ case "roles":
+ return ec.fieldContext_User_roles(ctx, field)
+ case "created_at":
+ return ec.fieldContext_User_created_at(ctx, field)
+ case "updated_at":
+ return ec.fieldContext_User_updated_at(ctx, field)
+ case "revoked_timestamp":
+ return ec.fieldContext_User_revoked_timestamp(ctx, field)
+ case "is_multi_factor_auth_enabled":
+ return ec.fieldContext_User_is_multi_factor_auth_enabled(ctx, field)
+ case "app_data":
+ return ec.fieldContext_User_app_data(ctx, field)
}
- return nil, fmt.Errorf("no field named %q was found under type EmailTemplates", field.Name)
+ return nil, fmt.Errorf("no field named %q was found under type User", field.Name)
},
}
defer func() {
@@ -12246,15 +12239,15 @@ func (ec *executionContext) fieldContext_Query__email_templates(ctx context.Cont
}
}()
ctx = graphql.WithFieldContext(ctx, fc)
- if fc.Args, err = ec.field_Query__email_templates_args(ctx, field.ArgumentMap(ec.Variables)); err != nil {
+ if fc.Args, err = ec.field_Query__user_args(ctx, field.ArgumentMap(ec.Variables)); err != nil {
ec.Error(ctx, err)
return fc, err
}
return fc, nil
}
-func (ec *executionContext) _Query___type(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
- fc, err := ec.fieldContext_Query___type(ctx, field)
+func (ec *executionContext) _Query__verification_requests(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
+ fc, err := ec.fieldContext_Query__verification_requests(ctx, field)
if err != nil {
return graphql.Null
}
@@ -12265,70 +12258,105 @@ func (ec *executionContext) _Query___type(ctx context.Context, field graphql.Col
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
- return ec.introspectType(fc.Args["name"].(string))
+ return ec.resolvers.Query().VerificationRequests(rctx, fc.Args["params"].(*model.PaginatedRequest))
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
+ if !graphql.HasFieldError(ctx, fc) {
+ ec.Errorf(ctx, "must not be null")
+ }
return graphql.Null
}
- res := resTmp.(*introspection.Type)
+ res := resTmp.(*model.VerificationRequests)
fc.Result = res
- return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res)
+ return ec.marshalNVerificationRequests2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐVerificationRequests(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Query___type(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Query__verification_requests(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Query",
Field: field,
IsMethod: true,
- IsResolver: false,
+ IsResolver: true,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
switch field.Name {
- case "kind":
- return ec.fieldContext___Type_kind(ctx, field)
- case "name":
- return ec.fieldContext___Type_name(ctx, field)
- case "description":
- return ec.fieldContext___Type_description(ctx, field)
- case "fields":
- return ec.fieldContext___Type_fields(ctx, field)
- case "interfaces":
- return ec.fieldContext___Type_interfaces(ctx, field)
- case "possibleTypes":
- return ec.fieldContext___Type_possibleTypes(ctx, field)
- case "enumValues":
- return ec.fieldContext___Type_enumValues(ctx, field)
- case "inputFields":
- return ec.fieldContext___Type_inputFields(ctx, field)
- case "ofType":
- return ec.fieldContext___Type_ofType(ctx, field)
- case "specifiedByURL":
- return ec.fieldContext___Type_specifiedByURL(ctx, field)
+ case "pagination":
+ return ec.fieldContext_VerificationRequests_pagination(ctx, field)
+ case "verification_requests":
+ return ec.fieldContext_VerificationRequests_verification_requests(ctx, field)
}
- return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name)
+ return nil, fmt.Errorf("no field named %q was found under type VerificationRequests", field.Name)
},
}
defer func() {
if r := recover(); r != nil {
- err = ec.Recover(ctx, r)
- ec.Error(ctx, err)
+ err = ec.Recover(ctx, r)
+ ec.Error(ctx, err)
+ }
+ }()
+ ctx = graphql.WithFieldContext(ctx, fc)
+ if fc.Args, err = ec.field_Query__verification_requests_args(ctx, field.ArgumentMap(ec.Variables)); err != nil {
+ ec.Error(ctx, err)
+ return fc, err
+ }
+ return fc, nil
+}
+
+func (ec *executionContext) _Query__admin_session(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
+ fc, err := ec.fieldContext_Query__admin_session(ctx, field)
+ if err != nil {
+ return graphql.Null
+ }
+ ctx = graphql.WithFieldContext(ctx, fc)
+ defer func() {
+ if r := recover(); r != nil {
+ ec.Error(ctx, ec.Recover(ctx, r))
+ ret = graphql.Null
}
}()
- ctx = graphql.WithFieldContext(ctx, fc)
- if fc.Args, err = ec.field_Query___type_args(ctx, field.ArgumentMap(ec.Variables)); err != nil {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
+ ctx = rctx // use context from middleware stack in children
+ return ec.resolvers.Query().AdminSession(rctx)
+ })
+ if err != nil {
ec.Error(ctx, err)
- return fc, err
+ return graphql.Null
+ }
+ if resTmp == nil {
+ if !graphql.HasFieldError(ctx, fc) {
+ ec.Errorf(ctx, "must not be null")
+ }
+ return graphql.Null
+ }
+ res := resTmp.(*model.Response)
+ fc.Result = res
+ return ec.marshalNResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐResponse(ctx, field.Selections, res)
+}
+
+func (ec *executionContext) fieldContext_Query__admin_session(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+ fc = &graphql.FieldContext{
+ Object: "Query",
+ Field: field,
+ IsMethod: true,
+ IsResolver: true,
+ Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
+ switch field.Name {
+ case "message":
+ return ec.fieldContext_Response_message(ctx, field)
+ }
+ return nil, fmt.Errorf("no field named %q was found under type Response", field.Name)
+ },
}
return fc, nil
}
-func (ec *executionContext) _Query___schema(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
- fc, err := ec.fieldContext_Query___schema(ctx, field)
+func (ec *executionContext) _Query__env(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
+ fc, err := ec.fieldContext_Query__env(ctx, field)
if err != nil {
return graphql.Null
}
@@ -12339,51 +12367,184 @@ func (ec *executionContext) _Query___schema(ctx context.Context, field graphql.C
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
- return ec.introspectSchema()
+ return ec.resolvers.Query().Env(rctx)
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
+ if !graphql.HasFieldError(ctx, fc) {
+ ec.Errorf(ctx, "must not be null")
+ }
return graphql.Null
}
- res := resTmp.(*introspection.Schema)
+ res := resTmp.(*model.Env)
fc.Result = res
- return ec.marshalO__Schema2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐSchema(ctx, field.Selections, res)
+ return ec.marshalNEnv2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐEnv(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Query___schema(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Query__env(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Query",
Field: field,
IsMethod: true,
- IsResolver: false,
+ IsResolver: true,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
switch field.Name {
- case "description":
- return ec.fieldContext___Schema_description(ctx, field)
- case "types":
- return ec.fieldContext___Schema_types(ctx, field)
- case "queryType":
- return ec.fieldContext___Schema_queryType(ctx, field)
- case "mutationType":
- return ec.fieldContext___Schema_mutationType(ctx, field)
- case "subscriptionType":
- return ec.fieldContext___Schema_subscriptionType(ctx, field)
- case "directives":
- return ec.fieldContext___Schema_directives(ctx, field)
+ case "ACCESS_TOKEN_EXPIRY_TIME":
+ return ec.fieldContext_Env_ACCESS_TOKEN_EXPIRY_TIME(ctx, field)
+ case "ADMIN_SECRET":
+ return ec.fieldContext_Env_ADMIN_SECRET(ctx, field)
+ case "DATABASE_NAME":
+ return ec.fieldContext_Env_DATABASE_NAME(ctx, field)
+ case "DATABASE_URL":
+ return ec.fieldContext_Env_DATABASE_URL(ctx, field)
+ case "DATABASE_TYPE":
+ return ec.fieldContext_Env_DATABASE_TYPE(ctx, field)
+ case "DATABASE_USERNAME":
+ return ec.fieldContext_Env_DATABASE_USERNAME(ctx, field)
+ case "DATABASE_PASSWORD":
+ return ec.fieldContext_Env_DATABASE_PASSWORD(ctx, field)
+ case "DATABASE_HOST":
+ return ec.fieldContext_Env_DATABASE_HOST(ctx, field)
+ case "DATABASE_PORT":
+ return ec.fieldContext_Env_DATABASE_PORT(ctx, field)
+ case "CLIENT_ID":
+ return ec.fieldContext_Env_CLIENT_ID(ctx, field)
+ case "CLIENT_SECRET":
+ return ec.fieldContext_Env_CLIENT_SECRET(ctx, field)
+ case "CUSTOM_ACCESS_TOKEN_SCRIPT":
+ return ec.fieldContext_Env_CUSTOM_ACCESS_TOKEN_SCRIPT(ctx, field)
+ case "SMTP_HOST":
+ return ec.fieldContext_Env_SMTP_HOST(ctx, field)
+ case "SMTP_PORT":
+ return ec.fieldContext_Env_SMTP_PORT(ctx, field)
+ case "SMTP_USERNAME":
+ return ec.fieldContext_Env_SMTP_USERNAME(ctx, field)
+ case "SMTP_PASSWORD":
+ return ec.fieldContext_Env_SMTP_PASSWORD(ctx, field)
+ case "SMTP_LOCAL_NAME":
+ return ec.fieldContext_Env_SMTP_LOCAL_NAME(ctx, field)
+ case "SENDER_EMAIL":
+ return ec.fieldContext_Env_SENDER_EMAIL(ctx, field)
+ case "SENDER_NAME":
+ return ec.fieldContext_Env_SENDER_NAME(ctx, field)
+ case "JWT_TYPE":
+ return ec.fieldContext_Env_JWT_TYPE(ctx, field)
+ case "JWT_SECRET":
+ return ec.fieldContext_Env_JWT_SECRET(ctx, field)
+ case "JWT_PRIVATE_KEY":
+ return ec.fieldContext_Env_JWT_PRIVATE_KEY(ctx, field)
+ case "JWT_PUBLIC_KEY":
+ return ec.fieldContext_Env_JWT_PUBLIC_KEY(ctx, field)
+ case "ALLOWED_ORIGINS":
+ return ec.fieldContext_Env_ALLOWED_ORIGINS(ctx, field)
+ case "APP_URL":
+ return ec.fieldContext_Env_APP_URL(ctx, field)
+ case "REDIS_URL":
+ return ec.fieldContext_Env_REDIS_URL(ctx, field)
+ case "RESET_PASSWORD_URL":
+ return ec.fieldContext_Env_RESET_PASSWORD_URL(ctx, field)
+ case "DISABLE_EMAIL_VERIFICATION":
+ return ec.fieldContext_Env_DISABLE_EMAIL_VERIFICATION(ctx, field)
+ case "DISABLE_BASIC_AUTHENTICATION":
+ return ec.fieldContext_Env_DISABLE_BASIC_AUTHENTICATION(ctx, field)
+ case "DISABLE_MOBILE_BASIC_AUTHENTICATION":
+ return ec.fieldContext_Env_DISABLE_MOBILE_BASIC_AUTHENTICATION(ctx, field)
+ case "DISABLE_MAGIC_LINK_LOGIN":
+ return ec.fieldContext_Env_DISABLE_MAGIC_LINK_LOGIN(ctx, field)
+ case "DISABLE_LOGIN_PAGE":
+ return ec.fieldContext_Env_DISABLE_LOGIN_PAGE(ctx, field)
+ case "DISABLE_SIGN_UP":
+ return ec.fieldContext_Env_DISABLE_SIGN_UP(ctx, field)
+ case "DISABLE_REDIS_FOR_ENV":
+ return ec.fieldContext_Env_DISABLE_REDIS_FOR_ENV(ctx, field)
+ case "DISABLE_STRONG_PASSWORD":
+ return ec.fieldContext_Env_DISABLE_STRONG_PASSWORD(ctx, field)
+ case "DISABLE_MULTI_FACTOR_AUTHENTICATION":
+ return ec.fieldContext_Env_DISABLE_MULTI_FACTOR_AUTHENTICATION(ctx, field)
+ case "ENFORCE_MULTI_FACTOR_AUTHENTICATION":
+ return ec.fieldContext_Env_ENFORCE_MULTI_FACTOR_AUTHENTICATION(ctx, field)
+ case "ROLES":
+ return ec.fieldContext_Env_ROLES(ctx, field)
+ case "PROTECTED_ROLES":
+ return ec.fieldContext_Env_PROTECTED_ROLES(ctx, field)
+ case "DEFAULT_ROLES":
+ return ec.fieldContext_Env_DEFAULT_ROLES(ctx, field)
+ case "JWT_ROLE_CLAIM":
+ return ec.fieldContext_Env_JWT_ROLE_CLAIM(ctx, field)
+ case "GOOGLE_CLIENT_ID":
+ return ec.fieldContext_Env_GOOGLE_CLIENT_ID(ctx, field)
+ case "GOOGLE_CLIENT_SECRET":
+ return ec.fieldContext_Env_GOOGLE_CLIENT_SECRET(ctx, field)
+ case "GITHUB_CLIENT_ID":
+ return ec.fieldContext_Env_GITHUB_CLIENT_ID(ctx, field)
+ case "GITHUB_CLIENT_SECRET":
+ return ec.fieldContext_Env_GITHUB_CLIENT_SECRET(ctx, field)
+ case "FACEBOOK_CLIENT_ID":
+ return ec.fieldContext_Env_FACEBOOK_CLIENT_ID(ctx, field)
+ case "FACEBOOK_CLIENT_SECRET":
+ return ec.fieldContext_Env_FACEBOOK_CLIENT_SECRET(ctx, field)
+ case "LINKEDIN_CLIENT_ID":
+ return ec.fieldContext_Env_LINKEDIN_CLIENT_ID(ctx, field)
+ case "LINKEDIN_CLIENT_SECRET":
+ return ec.fieldContext_Env_LINKEDIN_CLIENT_SECRET(ctx, field)
+ case "APPLE_CLIENT_ID":
+ return ec.fieldContext_Env_APPLE_CLIENT_ID(ctx, field)
+ case "APPLE_CLIENT_SECRET":
+ return ec.fieldContext_Env_APPLE_CLIENT_SECRET(ctx, field)
+ case "DISCORD_CLIENT_ID":
+ return ec.fieldContext_Env_DISCORD_CLIENT_ID(ctx, field)
+ case "DISCORD_CLIENT_SECRET":
+ return ec.fieldContext_Env_DISCORD_CLIENT_SECRET(ctx, field)
+ case "TWITTER_CLIENT_ID":
+ return ec.fieldContext_Env_TWITTER_CLIENT_ID(ctx, field)
+ case "TWITTER_CLIENT_SECRET":
+ return ec.fieldContext_Env_TWITTER_CLIENT_SECRET(ctx, field)
+ case "MICROSOFT_CLIENT_ID":
+ return ec.fieldContext_Env_MICROSOFT_CLIENT_ID(ctx, field)
+ case "MICROSOFT_CLIENT_SECRET":
+ return ec.fieldContext_Env_MICROSOFT_CLIENT_SECRET(ctx, field)
+ case "MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID":
+ return ec.fieldContext_Env_MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID(ctx, field)
+ case "TWITCH_CLIENT_ID":
+ return ec.fieldContext_Env_TWITCH_CLIENT_ID(ctx, field)
+ case "TWITCH_CLIENT_SECRET":
+ return ec.fieldContext_Env_TWITCH_CLIENT_SECRET(ctx, field)
+ case "ROBLOX_CLIENT_ID":
+ return ec.fieldContext_Env_ROBLOX_CLIENT_ID(ctx, field)
+ case "ROBLOX_CLIENT_SECRET":
+ return ec.fieldContext_Env_ROBLOX_CLIENT_SECRET(ctx, field)
+ case "ORGANIZATION_NAME":
+ return ec.fieldContext_Env_ORGANIZATION_NAME(ctx, field)
+ case "ORGANIZATION_LOGO":
+ return ec.fieldContext_Env_ORGANIZATION_LOGO(ctx, field)
+ case "APP_COOKIE_SECURE":
+ return ec.fieldContext_Env_APP_COOKIE_SECURE(ctx, field)
+ case "ADMIN_COOKIE_SECURE":
+ return ec.fieldContext_Env_ADMIN_COOKIE_SECURE(ctx, field)
+ case "DEFAULT_AUTHORIZE_RESPONSE_TYPE":
+ return ec.fieldContext_Env_DEFAULT_AUTHORIZE_RESPONSE_TYPE(ctx, field)
+ case "DEFAULT_AUTHORIZE_RESPONSE_MODE":
+ return ec.fieldContext_Env_DEFAULT_AUTHORIZE_RESPONSE_MODE(ctx, field)
+ case "DISABLE_PLAYGROUND":
+ return ec.fieldContext_Env_DISABLE_PLAYGROUND(ctx, field)
+ case "DISABLE_MAIL_OTP_LOGIN":
+ return ec.fieldContext_Env_DISABLE_MAIL_OTP_LOGIN(ctx, field)
+ case "DISABLE_TOTP_LOGIN":
+ return ec.fieldContext_Env_DISABLE_TOTP_LOGIN(ctx, field)
}
- return nil, fmt.Errorf("no field named %q was found under type __Schema", field.Name)
+ return nil, fmt.Errorf("no field named %q was found under type Env", field.Name)
},
}
return fc, nil
}
-func (ec *executionContext) _Response_message(ctx context.Context, field graphql.CollectedField, obj *model.Response) (ret graphql.Marshaler) {
- fc, err := ec.fieldContext_Response_message(ctx, field)
+func (ec *executionContext) _Query__webhook(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
+ fc, err := ec.fieldContext_Query__webhook(ctx, field)
if err != nil {
return graphql.Null
}
@@ -12394,9 +12555,9 @@ func (ec *executionContext) _Response_message(ctx context.Context, field graphql
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
- return obj.Message, nil
+ return ec.resolvers.Query().Webhook(rctx, fc.Args["params"].(model.WebhookRequest))
})
if err != nil {
ec.Error(ctx, err)
@@ -12408,26 +12569,55 @@ func (ec *executionContext) _Response_message(ctx context.Context, field graphql
}
return graphql.Null
}
- res := resTmp.(string)
+ res := resTmp.(*model.Webhook)
fc.Result = res
- return ec.marshalNString2string(ctx, field.Selections, res)
+ return ec.marshalNWebhook2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐWebhook(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Response_message(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Query__webhook(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
- Object: "Response",
+ Object: "Query",
Field: field,
- IsMethod: false,
- IsResolver: false,
+ IsMethod: true,
+ IsResolver: true,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
- return nil, errors.New("field of type String does not have child fields")
+ switch field.Name {
+ case "id":
+ return ec.fieldContext_Webhook_id(ctx, field)
+ case "event_name":
+ return ec.fieldContext_Webhook_event_name(ctx, field)
+ case "event_description":
+ return ec.fieldContext_Webhook_event_description(ctx, field)
+ case "endpoint":
+ return ec.fieldContext_Webhook_endpoint(ctx, field)
+ case "enabled":
+ return ec.fieldContext_Webhook_enabled(ctx, field)
+ case "headers":
+ return ec.fieldContext_Webhook_headers(ctx, field)
+ case "created_at":
+ return ec.fieldContext_Webhook_created_at(ctx, field)
+ case "updated_at":
+ return ec.fieldContext_Webhook_updated_at(ctx, field)
+ }
+ return nil, fmt.Errorf("no field named %q was found under type Webhook", field.Name)
},
}
+ defer func() {
+ if r := recover(); r != nil {
+ err = ec.Recover(ctx, r)
+ ec.Error(ctx, err)
+ }
+ }()
+ ctx = graphql.WithFieldContext(ctx, fc)
+ if fc.Args, err = ec.field_Query__webhook_args(ctx, field.ArgumentMap(ec.Variables)); err != nil {
+ ec.Error(ctx, err)
+ return fc, err
+ }
return fc, nil
}
-func (ec *executionContext) _SMSVerificationRequests_id(ctx context.Context, field graphql.CollectedField, obj *model.SMSVerificationRequests) (ret graphql.Marshaler) {
- fc, err := ec.fieldContext_SMSVerificationRequests_id(ctx, field)
+func (ec *executionContext) _Query__webhooks(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
+ fc, err := ec.fieldContext_Query__webhooks(ctx, field)
if err != nil {
return graphql.Null
}
@@ -12438,9 +12628,9 @@ func (ec *executionContext) _SMSVerificationRequests_id(ctx context.Context, fie
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
- return obj.ID, nil
+ return ec.resolvers.Query().Webhooks(rctx, fc.Args["params"].(*model.PaginatedRequest))
})
if err != nil {
ec.Error(ctx, err)
@@ -12452,26 +12642,43 @@ func (ec *executionContext) _SMSVerificationRequests_id(ctx context.Context, fie
}
return graphql.Null
}
- res := resTmp.(string)
+ res := resTmp.(*model.Webhooks)
fc.Result = res
- return ec.marshalNID2string(ctx, field.Selections, res)
+ return ec.marshalNWebhooks2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐWebhooks(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_SMSVerificationRequests_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Query__webhooks(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
- Object: "SMSVerificationRequests",
+ Object: "Query",
Field: field,
- IsMethod: false,
- IsResolver: false,
+ IsMethod: true,
+ IsResolver: true,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
- return nil, errors.New("field of type ID does not have child fields")
+ switch field.Name {
+ case "pagination":
+ return ec.fieldContext_Webhooks_pagination(ctx, field)
+ case "webhooks":
+ return ec.fieldContext_Webhooks_webhooks(ctx, field)
+ }
+ return nil, fmt.Errorf("no field named %q was found under type Webhooks", field.Name)
},
}
+ defer func() {
+ if r := recover(); r != nil {
+ err = ec.Recover(ctx, r)
+ ec.Error(ctx, err)
+ }
+ }()
+ ctx = graphql.WithFieldContext(ctx, fc)
+ if fc.Args, err = ec.field_Query__webhooks_args(ctx, field.ArgumentMap(ec.Variables)); err != nil {
+ ec.Error(ctx, err)
+ return fc, err
+ }
return fc, nil
}
-func (ec *executionContext) _SMSVerificationRequests_code(ctx context.Context, field graphql.CollectedField, obj *model.SMSVerificationRequests) (ret graphql.Marshaler) {
- fc, err := ec.fieldContext_SMSVerificationRequests_code(ctx, field)
+func (ec *executionContext) _Query__webhook_logs(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
+ fc, err := ec.fieldContext_Query__webhook_logs(ctx, field)
if err != nil {
return graphql.Null
}
@@ -12482,9 +12689,9 @@ func (ec *executionContext) _SMSVerificationRequests_code(ctx context.Context, f
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
- return obj.Code, nil
+ return ec.resolvers.Query().WebhookLogs(rctx, fc.Args["params"].(*model.ListWebhookLogRequest))
})
if err != nil {
ec.Error(ctx, err)
@@ -12496,26 +12703,43 @@ func (ec *executionContext) _SMSVerificationRequests_code(ctx context.Context, f
}
return graphql.Null
}
- res := resTmp.(string)
+ res := resTmp.(*model.WebhookLogs)
fc.Result = res
- return ec.marshalNString2string(ctx, field.Selections, res)
+ return ec.marshalNWebhookLogs2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐWebhookLogs(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_SMSVerificationRequests_code(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Query__webhook_logs(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
- Object: "SMSVerificationRequests",
+ Object: "Query",
Field: field,
- IsMethod: false,
- IsResolver: false,
+ IsMethod: true,
+ IsResolver: true,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
- return nil, errors.New("field of type String does not have child fields")
+ switch field.Name {
+ case "pagination":
+ return ec.fieldContext_WebhookLogs_pagination(ctx, field)
+ case "webhook_logs":
+ return ec.fieldContext_WebhookLogs_webhook_logs(ctx, field)
+ }
+ return nil, fmt.Errorf("no field named %q was found under type WebhookLogs", field.Name)
},
}
+ defer func() {
+ if r := recover(); r != nil {
+ err = ec.Recover(ctx, r)
+ ec.Error(ctx, err)
+ }
+ }()
+ ctx = graphql.WithFieldContext(ctx, fc)
+ if fc.Args, err = ec.field_Query__webhook_logs_args(ctx, field.ArgumentMap(ec.Variables)); err != nil {
+ ec.Error(ctx, err)
+ return fc, err
+ }
return fc, nil
}
-func (ec *executionContext) _SMSVerificationRequests_code_expires_at(ctx context.Context, field graphql.CollectedField, obj *model.SMSVerificationRequests) (ret graphql.Marshaler) {
- fc, err := ec.fieldContext_SMSVerificationRequests_code_expires_at(ctx, field)
+func (ec *executionContext) _Query__email_templates(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
+ fc, err := ec.fieldContext_Query__email_templates(ctx, field)
if err != nil {
return graphql.Null
}
@@ -12526,9 +12750,9 @@ func (ec *executionContext) _SMSVerificationRequests_code_expires_at(ctx context
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
- return obj.CodeExpiresAt, nil
+ return ec.resolvers.Query().EmailTemplates(rctx, fc.Args["params"].(*model.PaginatedRequest))
})
if err != nil {
ec.Error(ctx, err)
@@ -12540,26 +12764,43 @@ func (ec *executionContext) _SMSVerificationRequests_code_expires_at(ctx context
}
return graphql.Null
}
- res := resTmp.(int64)
+ res := resTmp.(*model.EmailTemplates)
fc.Result = res
- return ec.marshalNInt642int64(ctx, field.Selections, res)
+ return ec.marshalNEmailTemplates2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐEmailTemplates(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_SMSVerificationRequests_code_expires_at(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Query__email_templates(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
- Object: "SMSVerificationRequests",
+ Object: "Query",
Field: field,
- IsMethod: false,
- IsResolver: false,
+ IsMethod: true,
+ IsResolver: true,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
- return nil, errors.New("field of type Int64 does not have child fields")
+ switch field.Name {
+ case "pagination":
+ return ec.fieldContext_EmailTemplates_pagination(ctx, field)
+ case "email_templates":
+ return ec.fieldContext_EmailTemplates_email_templates(ctx, field)
+ }
+ return nil, fmt.Errorf("no field named %q was found under type EmailTemplates", field.Name)
},
}
+ defer func() {
+ if r := recover(); r != nil {
+ err = ec.Recover(ctx, r)
+ ec.Error(ctx, err)
+ }
+ }()
+ ctx = graphql.WithFieldContext(ctx, fc)
+ if fc.Args, err = ec.field_Query__email_templates_args(ctx, field.ArgumentMap(ec.Variables)); err != nil {
+ ec.Error(ctx, err)
+ return fc, err
+ }
return fc, nil
}
-func (ec *executionContext) _SMSVerificationRequests_phone_number(ctx context.Context, field graphql.CollectedField, obj *model.SMSVerificationRequests) (ret graphql.Marshaler) {
- fc, err := ec.fieldContext_SMSVerificationRequests_phone_number(ctx, field)
+func (ec *executionContext) _Query___type(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
+ fc, err := ec.fieldContext_Query___type(ctx, field)
if err != nil {
return graphql.Null
}
@@ -12570,40 +12811,72 @@ func (ec *executionContext) _SMSVerificationRequests_phone_number(ctx context.Co
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
- return obj.PhoneNumber, nil
+ return ec.introspectType(fc.Args["name"].(string))
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
- if !graphql.HasFieldError(ctx, fc) {
- ec.Errorf(ctx, "must not be null")
- }
return graphql.Null
}
- res := resTmp.(string)
+ res := resTmp.(*introspection.Type)
fc.Result = res
- return ec.marshalNString2string(ctx, field.Selections, res)
+ return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_SMSVerificationRequests_phone_number(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Query___type(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
- Object: "SMSVerificationRequests",
+ Object: "Query",
Field: field,
- IsMethod: false,
+ IsMethod: true,
IsResolver: false,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
- return nil, errors.New("field of type String does not have child fields")
+ switch field.Name {
+ case "kind":
+ return ec.fieldContext___Type_kind(ctx, field)
+ case "name":
+ return ec.fieldContext___Type_name(ctx, field)
+ case "description":
+ return ec.fieldContext___Type_description(ctx, field)
+ case "specifiedByURL":
+ return ec.fieldContext___Type_specifiedByURL(ctx, field)
+ case "fields":
+ return ec.fieldContext___Type_fields(ctx, field)
+ case "interfaces":
+ return ec.fieldContext___Type_interfaces(ctx, field)
+ case "possibleTypes":
+ return ec.fieldContext___Type_possibleTypes(ctx, field)
+ case "enumValues":
+ return ec.fieldContext___Type_enumValues(ctx, field)
+ case "inputFields":
+ return ec.fieldContext___Type_inputFields(ctx, field)
+ case "ofType":
+ return ec.fieldContext___Type_ofType(ctx, field)
+ case "isOneOf":
+ return ec.fieldContext___Type_isOneOf(ctx, field)
+ }
+ return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name)
},
}
+ defer func() {
+ if r := recover(); r != nil {
+ err = ec.Recover(ctx, r)
+ ec.Error(ctx, err)
+ }
+ }()
+ ctx = graphql.WithFieldContext(ctx, fc)
+ if fc.Args, err = ec.field_Query___type_args(ctx, field.ArgumentMap(ec.Variables)); err != nil {
+ ec.Error(ctx, err)
+ return fc, err
+ }
return fc, nil
}
-func (ec *executionContext) _SMSVerificationRequests_created_at(ctx context.Context, field graphql.CollectedField, obj *model.SMSVerificationRequests) (ret graphql.Marshaler) {
- fc, err := ec.fieldContext_SMSVerificationRequests_created_at(ctx, field)
+func (ec *executionContext) _Query___schema(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
+ fc, err := ec.fieldContext_Query___schema(ctx, field)
if err != nil {
return graphql.Null
}
@@ -12614,40 +12887,51 @@ func (ec *executionContext) _SMSVerificationRequests_created_at(ctx context.Cont
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
- return obj.CreatedAt, nil
+ return ec.introspectSchema()
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
- if !graphql.HasFieldError(ctx, fc) {
- ec.Errorf(ctx, "must not be null")
- }
return graphql.Null
}
- res := resTmp.(int64)
+ res := resTmp.(*introspection.Schema)
fc.Result = res
- return ec.marshalNInt642int64(ctx, field.Selections, res)
+ return ec.marshalO__Schema2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐSchema(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_SMSVerificationRequests_created_at(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Query___schema(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
- Object: "SMSVerificationRequests",
+ Object: "Query",
Field: field,
- IsMethod: false,
+ IsMethod: true,
IsResolver: false,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
- return nil, errors.New("field of type Int64 does not have child fields")
+ switch field.Name {
+ case "description":
+ return ec.fieldContext___Schema_description(ctx, field)
+ case "types":
+ return ec.fieldContext___Schema_types(ctx, field)
+ case "queryType":
+ return ec.fieldContext___Schema_queryType(ctx, field)
+ case "mutationType":
+ return ec.fieldContext___Schema_mutationType(ctx, field)
+ case "subscriptionType":
+ return ec.fieldContext___Schema_subscriptionType(ctx, field)
+ case "directives":
+ return ec.fieldContext___Schema_directives(ctx, field)
+ }
+ return nil, fmt.Errorf("no field named %q was found under type __Schema", field.Name)
},
}
return fc, nil
}
-func (ec *executionContext) _SMSVerificationRequests_updated_at(ctx context.Context, field graphql.CollectedField, obj *model.SMSVerificationRequests) (ret graphql.Marshaler) {
- fc, err := ec.fieldContext_SMSVerificationRequests_updated_at(ctx, field)
+func (ec *executionContext) _Response_message(ctx context.Context, field graphql.CollectedField, obj *model.Response) (ret graphql.Marshaler) {
+ fc, err := ec.fieldContext_Response_message(ctx, field)
if err != nil {
return graphql.Null
}
@@ -12658,30 +12942,33 @@ func (ec *executionContext) _SMSVerificationRequests_updated_at(ctx context.Cont
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
- return obj.UpdatedAt, nil
+ return obj.Message, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
+ if !graphql.HasFieldError(ctx, fc) {
+ ec.Errorf(ctx, "must not be null")
+ }
return graphql.Null
}
- res := resTmp.(*int64)
+ res := resTmp.(string)
fc.Result = res
- return ec.marshalOInt642ᚖint64(ctx, field.Selections, res)
+ return ec.marshalNString2string(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_SMSVerificationRequests_updated_at(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Response_message(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
- Object: "SMSVerificationRequests",
+ Object: "Response",
Field: field,
IsMethod: false,
IsResolver: false,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
- return nil, errors.New("field of type Int64 does not have child fields")
+ return nil, errors.New("field of type String does not have child fields")
},
}
return fc, nil
@@ -12699,7 +12986,7 @@ func (ec *executionContext) _TestEndpointResponse_http_status(ctx context.Contex
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.HTTPStatus, nil
})
@@ -12715,7 +13002,7 @@ func (ec *executionContext) _TestEndpointResponse_http_status(ctx context.Contex
return ec.marshalOInt642ᚖint64(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_TestEndpointResponse_http_status(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_TestEndpointResponse_http_status(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "TestEndpointResponse",
Field: field,
@@ -12740,7 +13027,7 @@ func (ec *executionContext) _TestEndpointResponse_response(ctx context.Context,
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Response, nil
})
@@ -12756,7 +13043,7 @@ func (ec *executionContext) _TestEndpointResponse_response(ctx context.Context,
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_TestEndpointResponse_response(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_TestEndpointResponse_response(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "TestEndpointResponse",
Field: field,
@@ -12781,7 +13068,7 @@ func (ec *executionContext) _User_id(ctx context.Context, field graphql.Collecte
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.ID, nil
})
@@ -12800,7 +13087,7 @@ func (ec *executionContext) _User_id(ctx context.Context, field graphql.Collecte
return ec.marshalNID2string(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_User_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_User_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "User",
Field: field,
@@ -12825,7 +13112,7 @@ func (ec *executionContext) _User_email(ctx context.Context, field graphql.Colle
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Email, nil
})
@@ -12841,7 +13128,7 @@ func (ec *executionContext) _User_email(ctx context.Context, field graphql.Colle
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_User_email(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_User_email(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "User",
Field: field,
@@ -12866,7 +13153,7 @@ func (ec *executionContext) _User_email_verified(ctx context.Context, field grap
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.EmailVerified, nil
})
@@ -12885,7 +13172,7 @@ func (ec *executionContext) _User_email_verified(ctx context.Context, field grap
return ec.marshalNBoolean2bool(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_User_email_verified(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_User_email_verified(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "User",
Field: field,
@@ -12910,7 +13197,7 @@ func (ec *executionContext) _User_signup_methods(ctx context.Context, field grap
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.SignupMethods, nil
})
@@ -12929,7 +13216,7 @@ func (ec *executionContext) _User_signup_methods(ctx context.Context, field grap
return ec.marshalNString2string(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_User_signup_methods(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_User_signup_methods(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "User",
Field: field,
@@ -12954,7 +13241,7 @@ func (ec *executionContext) _User_given_name(ctx context.Context, field graphql.
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.GivenName, nil
})
@@ -12970,7 +13257,7 @@ func (ec *executionContext) _User_given_name(ctx context.Context, field graphql.
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_User_given_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_User_given_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "User",
Field: field,
@@ -12995,7 +13282,7 @@ func (ec *executionContext) _User_family_name(ctx context.Context, field graphql
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.FamilyName, nil
})
@@ -13011,7 +13298,7 @@ func (ec *executionContext) _User_family_name(ctx context.Context, field graphql
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_User_family_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_User_family_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "User",
Field: field,
@@ -13036,7 +13323,7 @@ func (ec *executionContext) _User_middle_name(ctx context.Context, field graphql
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.MiddleName, nil
})
@@ -13052,7 +13339,7 @@ func (ec *executionContext) _User_middle_name(ctx context.Context, field graphql
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_User_middle_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_User_middle_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "User",
Field: field,
@@ -13077,7 +13364,7 @@ func (ec *executionContext) _User_nickname(ctx context.Context, field graphql.Co
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Nickname, nil
})
@@ -13093,7 +13380,7 @@ func (ec *executionContext) _User_nickname(ctx context.Context, field graphql.Co
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_User_nickname(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_User_nickname(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "User",
Field: field,
@@ -13118,7 +13405,7 @@ func (ec *executionContext) _User_preferred_username(ctx context.Context, field
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.PreferredUsername, nil
})
@@ -13134,7 +13421,7 @@ func (ec *executionContext) _User_preferred_username(ctx context.Context, field
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_User_preferred_username(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_User_preferred_username(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "User",
Field: field,
@@ -13159,7 +13446,7 @@ func (ec *executionContext) _User_gender(ctx context.Context, field graphql.Coll
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Gender, nil
})
@@ -13175,7 +13462,7 @@ func (ec *executionContext) _User_gender(ctx context.Context, field graphql.Coll
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_User_gender(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_User_gender(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "User",
Field: field,
@@ -13200,7 +13487,7 @@ func (ec *executionContext) _User_birthdate(ctx context.Context, field graphql.C
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Birthdate, nil
})
@@ -13216,7 +13503,7 @@ func (ec *executionContext) _User_birthdate(ctx context.Context, field graphql.C
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_User_birthdate(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_User_birthdate(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "User",
Field: field,
@@ -13241,7 +13528,7 @@ func (ec *executionContext) _User_phone_number(ctx context.Context, field graphq
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.PhoneNumber, nil
})
@@ -13257,7 +13544,7 @@ func (ec *executionContext) _User_phone_number(ctx context.Context, field graphq
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_User_phone_number(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_User_phone_number(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "User",
Field: field,
@@ -13282,7 +13569,7 @@ func (ec *executionContext) _User_phone_number_verified(ctx context.Context, fie
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.PhoneNumberVerified, nil
})
@@ -13291,14 +13578,17 @@ func (ec *executionContext) _User_phone_number_verified(ctx context.Context, fie
return graphql.Null
}
if resTmp == nil {
+ if !graphql.HasFieldError(ctx, fc) {
+ ec.Errorf(ctx, "must not be null")
+ }
return graphql.Null
}
- res := resTmp.(*bool)
+ res := resTmp.(bool)
fc.Result = res
- return ec.marshalOBoolean2ᚖbool(ctx, field.Selections, res)
+ return ec.marshalNBoolean2bool(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_User_phone_number_verified(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_User_phone_number_verified(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "User",
Field: field,
@@ -13323,7 +13613,7 @@ func (ec *executionContext) _User_picture(ctx context.Context, field graphql.Col
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Picture, nil
})
@@ -13339,7 +13629,7 @@ func (ec *executionContext) _User_picture(ctx context.Context, field graphql.Col
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_User_picture(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_User_picture(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "User",
Field: field,
@@ -13364,7 +13654,7 @@ func (ec *executionContext) _User_roles(ctx context.Context, field graphql.Colle
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Roles, nil
})
@@ -13383,7 +13673,7 @@ func (ec *executionContext) _User_roles(ctx context.Context, field graphql.Colle
return ec.marshalNString2ᚕstringᚄ(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_User_roles(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_User_roles(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "User",
Field: field,
@@ -13408,7 +13698,7 @@ func (ec *executionContext) _User_created_at(ctx context.Context, field graphql.
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.CreatedAt, nil
})
@@ -13424,7 +13714,7 @@ func (ec *executionContext) _User_created_at(ctx context.Context, field graphql.
return ec.marshalOInt642ᚖint64(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_User_created_at(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_User_created_at(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "User",
Field: field,
@@ -13449,7 +13739,7 @@ func (ec *executionContext) _User_updated_at(ctx context.Context, field graphql.
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.UpdatedAt, nil
})
@@ -13465,7 +13755,7 @@ func (ec *executionContext) _User_updated_at(ctx context.Context, field graphql.
return ec.marshalOInt642ᚖint64(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_User_updated_at(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_User_updated_at(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "User",
Field: field,
@@ -13490,7 +13780,7 @@ func (ec *executionContext) _User_revoked_timestamp(ctx context.Context, field g
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.RevokedTimestamp, nil
})
@@ -13506,7 +13796,7 @@ func (ec *executionContext) _User_revoked_timestamp(ctx context.Context, field g
return ec.marshalOInt642ᚖint64(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_User_revoked_timestamp(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_User_revoked_timestamp(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "User",
Field: field,
@@ -13531,7 +13821,7 @@ func (ec *executionContext) _User_is_multi_factor_auth_enabled(ctx context.Conte
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.IsMultiFactorAuthEnabled, nil
})
@@ -13547,7 +13837,7 @@ func (ec *executionContext) _User_is_multi_factor_auth_enabled(ctx context.Conte
return ec.marshalOBoolean2ᚖbool(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_User_is_multi_factor_auth_enabled(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_User_is_multi_factor_auth_enabled(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "User",
Field: field,
@@ -13572,7 +13862,7 @@ func (ec *executionContext) _User_app_data(ctx context.Context, field graphql.Co
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.AppData, nil
})
@@ -13583,12 +13873,12 @@ func (ec *executionContext) _User_app_data(ctx context.Context, field graphql.Co
if resTmp == nil {
return graphql.Null
}
- res := resTmp.(map[string]interface{})
+ res := resTmp.(map[string]any)
fc.Result = res
return ec.marshalOMap2map(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_User_app_data(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_User_app_data(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "User",
Field: field,
@@ -13613,7 +13903,7 @@ func (ec *executionContext) _Users_pagination(ctx context.Context, field graphql
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Pagination, nil
})
@@ -13629,10 +13919,10 @@ func (ec *executionContext) _Users_pagination(ctx context.Context, field graphql
}
res := resTmp.(*model.Pagination)
fc.Result = res
- return ec.marshalNPagination2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐPagination(ctx, field.Selections, res)
+ return ec.marshalNPagination2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐPagination(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Users_pagination(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Users_pagination(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Users",
Field: field,
@@ -13667,7 +13957,7 @@ func (ec *executionContext) _Users_users(ctx context.Context, field graphql.Coll
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Users, nil
})
@@ -13683,10 +13973,10 @@ func (ec *executionContext) _Users_users(ctx context.Context, field graphql.Coll
}
res := resTmp.([]*model.User)
fc.Result = res
- return ec.marshalNUser2ᚕᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐUserᚄ(ctx, field.Selections, res)
+ return ec.marshalNUser2ᚕᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐUserᚄ(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Users_users(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Users_users(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Users",
Field: field,
@@ -13753,7 +14043,7 @@ func (ec *executionContext) _ValidateJWTTokenResponse_is_valid(ctx context.Conte
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.IsValid, nil
})
@@ -13772,7 +14062,7 @@ func (ec *executionContext) _ValidateJWTTokenResponse_is_valid(ctx context.Conte
return ec.marshalNBoolean2bool(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_ValidateJWTTokenResponse_is_valid(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_ValidateJWTTokenResponse_is_valid(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "ValidateJWTTokenResponse",
Field: field,
@@ -13797,7 +14087,7 @@ func (ec *executionContext) _ValidateJWTTokenResponse_claims(ctx context.Context
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Claims, nil
})
@@ -13808,12 +14098,12 @@ func (ec *executionContext) _ValidateJWTTokenResponse_claims(ctx context.Context
if resTmp == nil {
return graphql.Null
}
- res := resTmp.(map[string]interface{})
+ res := resTmp.(map[string]any)
fc.Result = res
return ec.marshalOMap2map(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_ValidateJWTTokenResponse_claims(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_ValidateJWTTokenResponse_claims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "ValidateJWTTokenResponse",
Field: field,
@@ -13838,7 +14128,7 @@ func (ec *executionContext) _ValidateSessionResponse_is_valid(ctx context.Contex
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.IsValid, nil
})
@@ -13857,7 +14147,7 @@ func (ec *executionContext) _ValidateSessionResponse_is_valid(ctx context.Contex
return ec.marshalNBoolean2bool(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_ValidateSessionResponse_is_valid(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_ValidateSessionResponse_is_valid(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "ValidateSessionResponse",
Field: field,
@@ -13882,7 +14172,7 @@ func (ec *executionContext) _ValidateSessionResponse_user(ctx context.Context, f
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.User, nil
})
@@ -13898,10 +14188,10 @@ func (ec *executionContext) _ValidateSessionResponse_user(ctx context.Context, f
}
res := resTmp.(*model.User)
fc.Result = res
- return ec.marshalNUser2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐUser(ctx, field.Selections, res)
+ return ec.marshalNUser2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐUser(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_ValidateSessionResponse_user(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_ValidateSessionResponse_user(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "ValidateSessionResponse",
Field: field,
@@ -13968,7 +14258,7 @@ func (ec *executionContext) _VerificationRequest_id(ctx context.Context, field g
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.ID, nil
})
@@ -13987,7 +14277,7 @@ func (ec *executionContext) _VerificationRequest_id(ctx context.Context, field g
return ec.marshalNID2string(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_VerificationRequest_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_VerificationRequest_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "VerificationRequest",
Field: field,
@@ -14012,7 +14302,7 @@ func (ec *executionContext) _VerificationRequest_identifier(ctx context.Context,
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Identifier, nil
})
@@ -14028,7 +14318,7 @@ func (ec *executionContext) _VerificationRequest_identifier(ctx context.Context,
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_VerificationRequest_identifier(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_VerificationRequest_identifier(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "VerificationRequest",
Field: field,
@@ -14053,7 +14343,7 @@ func (ec *executionContext) _VerificationRequest_token(ctx context.Context, fiel
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Token, nil
})
@@ -14069,7 +14359,7 @@ func (ec *executionContext) _VerificationRequest_token(ctx context.Context, fiel
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_VerificationRequest_token(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_VerificationRequest_token(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "VerificationRequest",
Field: field,
@@ -14094,7 +14384,7 @@ func (ec *executionContext) _VerificationRequest_email(ctx context.Context, fiel
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Email, nil
})
@@ -14110,7 +14400,7 @@ func (ec *executionContext) _VerificationRequest_email(ctx context.Context, fiel
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_VerificationRequest_email(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_VerificationRequest_email(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "VerificationRequest",
Field: field,
@@ -14135,7 +14425,7 @@ func (ec *executionContext) _VerificationRequest_expires(ctx context.Context, fi
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Expires, nil
})
@@ -14151,7 +14441,7 @@ func (ec *executionContext) _VerificationRequest_expires(ctx context.Context, fi
return ec.marshalOInt642ᚖint64(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_VerificationRequest_expires(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_VerificationRequest_expires(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "VerificationRequest",
Field: field,
@@ -14176,7 +14466,7 @@ func (ec *executionContext) _VerificationRequest_created_at(ctx context.Context,
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.CreatedAt, nil
})
@@ -14192,7 +14482,7 @@ func (ec *executionContext) _VerificationRequest_created_at(ctx context.Context,
return ec.marshalOInt642ᚖint64(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_VerificationRequest_created_at(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_VerificationRequest_created_at(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "VerificationRequest",
Field: field,
@@ -14217,7 +14507,7 @@ func (ec *executionContext) _VerificationRequest_updated_at(ctx context.Context,
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.UpdatedAt, nil
})
@@ -14233,7 +14523,7 @@ func (ec *executionContext) _VerificationRequest_updated_at(ctx context.Context,
return ec.marshalOInt642ᚖint64(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_VerificationRequest_updated_at(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_VerificationRequest_updated_at(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "VerificationRequest",
Field: field,
@@ -14258,7 +14548,7 @@ func (ec *executionContext) _VerificationRequest_nonce(ctx context.Context, fiel
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Nonce, nil
})
@@ -14274,7 +14564,7 @@ func (ec *executionContext) _VerificationRequest_nonce(ctx context.Context, fiel
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_VerificationRequest_nonce(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_VerificationRequest_nonce(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "VerificationRequest",
Field: field,
@@ -14299,7 +14589,7 @@ func (ec *executionContext) _VerificationRequest_redirect_uri(ctx context.Contex
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.RedirectURI, nil
})
@@ -14315,7 +14605,7 @@ func (ec *executionContext) _VerificationRequest_redirect_uri(ctx context.Contex
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_VerificationRequest_redirect_uri(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_VerificationRequest_redirect_uri(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "VerificationRequest",
Field: field,
@@ -14340,7 +14630,7 @@ func (ec *executionContext) _VerificationRequests_pagination(ctx context.Context
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Pagination, nil
})
@@ -14356,10 +14646,10 @@ func (ec *executionContext) _VerificationRequests_pagination(ctx context.Context
}
res := resTmp.(*model.Pagination)
fc.Result = res
- return ec.marshalNPagination2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐPagination(ctx, field.Selections, res)
+ return ec.marshalNPagination2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐPagination(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_VerificationRequests_pagination(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_VerificationRequests_pagination(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "VerificationRequests",
Field: field,
@@ -14394,7 +14684,7 @@ func (ec *executionContext) _VerificationRequests_verification_requests(ctx cont
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.VerificationRequests, nil
})
@@ -14410,10 +14700,10 @@ func (ec *executionContext) _VerificationRequests_verification_requests(ctx cont
}
res := resTmp.([]*model.VerificationRequest)
fc.Result = res
- return ec.marshalNVerificationRequest2ᚕᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐVerificationRequestᚄ(ctx, field.Selections, res)
+ return ec.marshalNVerificationRequest2ᚕᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐVerificationRequestᚄ(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_VerificationRequests_verification_requests(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_VerificationRequests_verification_requests(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "VerificationRequests",
Field: field,
@@ -14458,7 +14748,7 @@ func (ec *executionContext) _Webhook_id(ctx context.Context, field graphql.Colle
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.ID, nil
})
@@ -14477,7 +14767,7 @@ func (ec *executionContext) _Webhook_id(ctx context.Context, field graphql.Colle
return ec.marshalNID2string(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Webhook_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Webhook_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Webhook",
Field: field,
@@ -14502,7 +14792,7 @@ func (ec *executionContext) _Webhook_event_name(ctx context.Context, field graph
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.EventName, nil
})
@@ -14518,7 +14808,7 @@ func (ec *executionContext) _Webhook_event_name(ctx context.Context, field graph
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Webhook_event_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Webhook_event_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Webhook",
Field: field,
@@ -14543,7 +14833,7 @@ func (ec *executionContext) _Webhook_event_description(ctx context.Context, fiel
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.EventDescription, nil
})
@@ -14559,7 +14849,7 @@ func (ec *executionContext) _Webhook_event_description(ctx context.Context, fiel
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Webhook_event_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Webhook_event_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Webhook",
Field: field,
@@ -14584,7 +14874,7 @@ func (ec *executionContext) _Webhook_endpoint(ctx context.Context, field graphql
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Endpoint, nil
})
@@ -14600,7 +14890,7 @@ func (ec *executionContext) _Webhook_endpoint(ctx context.Context, field graphql
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Webhook_endpoint(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Webhook_endpoint(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Webhook",
Field: field,
@@ -14625,7 +14915,7 @@ func (ec *executionContext) _Webhook_enabled(ctx context.Context, field graphql.
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Enabled, nil
})
@@ -14641,7 +14931,7 @@ func (ec *executionContext) _Webhook_enabled(ctx context.Context, field graphql.
return ec.marshalOBoolean2ᚖbool(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Webhook_enabled(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Webhook_enabled(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Webhook",
Field: field,
@@ -14666,7 +14956,7 @@ func (ec *executionContext) _Webhook_headers(ctx context.Context, field graphql.
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Headers, nil
})
@@ -14677,12 +14967,12 @@ func (ec *executionContext) _Webhook_headers(ctx context.Context, field graphql.
if resTmp == nil {
return graphql.Null
}
- res := resTmp.(map[string]interface{})
+ res := resTmp.(map[string]any)
fc.Result = res
return ec.marshalOMap2map(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Webhook_headers(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Webhook_headers(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Webhook",
Field: field,
@@ -14707,7 +14997,7 @@ func (ec *executionContext) _Webhook_created_at(ctx context.Context, field graph
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.CreatedAt, nil
})
@@ -14723,7 +15013,7 @@ func (ec *executionContext) _Webhook_created_at(ctx context.Context, field graph
return ec.marshalOInt642ᚖint64(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Webhook_created_at(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Webhook_created_at(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Webhook",
Field: field,
@@ -14748,7 +15038,7 @@ func (ec *executionContext) _Webhook_updated_at(ctx context.Context, field graph
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.UpdatedAt, nil
})
@@ -14764,7 +15054,7 @@ func (ec *executionContext) _Webhook_updated_at(ctx context.Context, field graph
return ec.marshalOInt642ᚖint64(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Webhook_updated_at(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Webhook_updated_at(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Webhook",
Field: field,
@@ -14789,7 +15079,7 @@ func (ec *executionContext) _WebhookLog_id(ctx context.Context, field graphql.Co
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.ID, nil
})
@@ -14808,7 +15098,7 @@ func (ec *executionContext) _WebhookLog_id(ctx context.Context, field graphql.Co
return ec.marshalNID2string(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_WebhookLog_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_WebhookLog_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "WebhookLog",
Field: field,
@@ -14833,7 +15123,7 @@ func (ec *executionContext) _WebhookLog_http_status(ctx context.Context, field g
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.HTTPStatus, nil
})
@@ -14849,7 +15139,7 @@ func (ec *executionContext) _WebhookLog_http_status(ctx context.Context, field g
return ec.marshalOInt642ᚖint64(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_WebhookLog_http_status(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_WebhookLog_http_status(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "WebhookLog",
Field: field,
@@ -14874,7 +15164,7 @@ func (ec *executionContext) _WebhookLog_response(ctx context.Context, field grap
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Response, nil
})
@@ -14890,7 +15180,7 @@ func (ec *executionContext) _WebhookLog_response(ctx context.Context, field grap
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_WebhookLog_response(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_WebhookLog_response(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "WebhookLog",
Field: field,
@@ -14915,7 +15205,7 @@ func (ec *executionContext) _WebhookLog_request(ctx context.Context, field graph
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Request, nil
})
@@ -14931,7 +15221,7 @@ func (ec *executionContext) _WebhookLog_request(ctx context.Context, field graph
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_WebhookLog_request(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_WebhookLog_request(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "WebhookLog",
Field: field,
@@ -14956,7 +15246,7 @@ func (ec *executionContext) _WebhookLog_webhook_id(ctx context.Context, field gr
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.WebhookID, nil
})
@@ -14972,7 +15262,7 @@ func (ec *executionContext) _WebhookLog_webhook_id(ctx context.Context, field gr
return ec.marshalOID2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_WebhookLog_webhook_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_WebhookLog_webhook_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "WebhookLog",
Field: field,
@@ -14997,7 +15287,7 @@ func (ec *executionContext) _WebhookLog_created_at(ctx context.Context, field gr
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.CreatedAt, nil
})
@@ -15013,7 +15303,7 @@ func (ec *executionContext) _WebhookLog_created_at(ctx context.Context, field gr
return ec.marshalOInt642ᚖint64(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_WebhookLog_created_at(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_WebhookLog_created_at(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "WebhookLog",
Field: field,
@@ -15038,7 +15328,7 @@ func (ec *executionContext) _WebhookLog_updated_at(ctx context.Context, field gr
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.UpdatedAt, nil
})
@@ -15054,7 +15344,7 @@ func (ec *executionContext) _WebhookLog_updated_at(ctx context.Context, field gr
return ec.marshalOInt642ᚖint64(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_WebhookLog_updated_at(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_WebhookLog_updated_at(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "WebhookLog",
Field: field,
@@ -15079,7 +15369,7 @@ func (ec *executionContext) _WebhookLogs_pagination(ctx context.Context, field g
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Pagination, nil
})
@@ -15095,10 +15385,10 @@ func (ec *executionContext) _WebhookLogs_pagination(ctx context.Context, field g
}
res := resTmp.(*model.Pagination)
fc.Result = res
- return ec.marshalNPagination2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐPagination(ctx, field.Selections, res)
+ return ec.marshalNPagination2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐPagination(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_WebhookLogs_pagination(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_WebhookLogs_pagination(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "WebhookLogs",
Field: field,
@@ -15133,7 +15423,7 @@ func (ec *executionContext) _WebhookLogs_webhook_logs(ctx context.Context, field
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.WebhookLogs, nil
})
@@ -15149,10 +15439,10 @@ func (ec *executionContext) _WebhookLogs_webhook_logs(ctx context.Context, field
}
res := resTmp.([]*model.WebhookLog)
fc.Result = res
- return ec.marshalNWebhookLog2ᚕᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐWebhookLogᚄ(ctx, field.Selections, res)
+ return ec.marshalNWebhookLog2ᚕᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐWebhookLogᚄ(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_WebhookLogs_webhook_logs(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_WebhookLogs_webhook_logs(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "WebhookLogs",
Field: field,
@@ -15193,7 +15483,7 @@ func (ec *executionContext) _Webhooks_pagination(ctx context.Context, field grap
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Pagination, nil
})
@@ -15209,10 +15499,10 @@ func (ec *executionContext) _Webhooks_pagination(ctx context.Context, field grap
}
res := resTmp.(*model.Pagination)
fc.Result = res
- return ec.marshalNPagination2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐPagination(ctx, field.Selections, res)
+ return ec.marshalNPagination2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐPagination(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Webhooks_pagination(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Webhooks_pagination(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Webhooks",
Field: field,
@@ -15247,7 +15537,7 @@ func (ec *executionContext) _Webhooks_webhooks(ctx context.Context, field graphq
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Webhooks, nil
})
@@ -15263,10 +15553,10 @@ func (ec *executionContext) _Webhooks_webhooks(ctx context.Context, field graphq
}
res := resTmp.([]*model.Webhook)
fc.Result = res
- return ec.marshalNWebhook2ᚕᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐWebhookᚄ(ctx, field.Selections, res)
+ return ec.marshalNWebhook2ᚕᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐWebhookᚄ(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext_Webhooks_webhooks(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext_Webhooks_webhooks(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Webhooks",
Field: field,
@@ -15309,7 +15599,7 @@ func (ec *executionContext) ___Directive_name(ctx context.Context, field graphql
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Name, nil
})
@@ -15328,7 +15618,7 @@ func (ec *executionContext) ___Directive_name(ctx context.Context, field graphql
return ec.marshalNString2string(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext___Directive_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext___Directive_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "__Directive",
Field: field,
@@ -15353,7 +15643,7 @@ func (ec *executionContext) ___Directive_description(ctx context.Context, field
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Description(), nil
})
@@ -15369,7 +15659,7 @@ func (ec *executionContext) ___Directive_description(ctx context.Context, field
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext___Directive_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext___Directive_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "__Directive",
Field: field,
@@ -15382,8 +15672,8 @@ func (ec *executionContext) fieldContext___Directive_description(ctx context.Con
return fc, nil
}
-func (ec *executionContext) ___Directive_locations(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) {
- fc, err := ec.fieldContext___Directive_locations(ctx, field)
+func (ec *executionContext) ___Directive_isRepeatable(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) {
+ fc, err := ec.fieldContext___Directive_isRepeatable(ctx, field)
if err != nil {
return graphql.Null
}
@@ -15394,9 +15684,9 @@ func (ec *executionContext) ___Directive_locations(ctx context.Context, field gr
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
- return obj.Locations, nil
+ return obj.IsRepeatable, nil
})
if err != nil {
ec.Error(ctx, err)
@@ -15408,26 +15698,26 @@ func (ec *executionContext) ___Directive_locations(ctx context.Context, field gr
}
return graphql.Null
}
- res := resTmp.([]string)
+ res := resTmp.(bool)
fc.Result = res
- return ec.marshalN__DirectiveLocation2ᚕstringᚄ(ctx, field.Selections, res)
+ return ec.marshalNBoolean2bool(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext___Directive_locations(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext___Directive_isRepeatable(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "__Directive",
Field: field,
IsMethod: false,
IsResolver: false,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
- return nil, errors.New("field of type __DirectiveLocation does not have child fields")
+ return nil, errors.New("field of type Boolean does not have child fields")
},
}
return fc, nil
}
-func (ec *executionContext) ___Directive_args(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) {
- fc, err := ec.fieldContext___Directive_args(ctx, field)
+func (ec *executionContext) ___Directive_locations(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) {
+ fc, err := ec.fieldContext___Directive_locations(ctx, field)
if err != nil {
return graphql.Null
}
@@ -15438,9 +15728,9 @@ func (ec *executionContext) ___Directive_args(ctx context.Context, field graphql
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
- return obj.Args, nil
+ return obj.Locations, nil
})
if err != nil {
ec.Error(ctx, err)
@@ -15452,36 +15742,26 @@ func (ec *executionContext) ___Directive_args(ctx context.Context, field graphql
}
return graphql.Null
}
- res := resTmp.([]introspection.InputValue)
+ res := resTmp.([]string)
fc.Result = res
- return ec.marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res)
+ return ec.marshalN__DirectiveLocation2ᚕstringᚄ(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext___Directive_args(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext___Directive_locations(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "__Directive",
Field: field,
IsMethod: false,
IsResolver: false,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
- switch field.Name {
- case "name":
- return ec.fieldContext___InputValue_name(ctx, field)
- case "description":
- return ec.fieldContext___InputValue_description(ctx, field)
- case "type":
- return ec.fieldContext___InputValue_type(ctx, field)
- case "defaultValue":
- return ec.fieldContext___InputValue_defaultValue(ctx, field)
- }
- return nil, fmt.Errorf("no field named %q was found under type __InputValue", field.Name)
+ return nil, errors.New("field of type __DirectiveLocation does not have child fields")
},
}
return fc, nil
}
-func (ec *executionContext) ___Directive_isRepeatable(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) {
- fc, err := ec.fieldContext___Directive_isRepeatable(ctx, field)
+func (ec *executionContext) ___Directive_args(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) {
+ fc, err := ec.fieldContext___Directive_args(ctx, field)
if err != nil {
return graphql.Null
}
@@ -15492,9 +15772,9 @@ func (ec *executionContext) ___Directive_isRepeatable(ctx context.Context, field
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
- return obj.IsRepeatable, nil
+ return obj.Args, nil
})
if err != nil {
ec.Error(ctx, err)
@@ -15506,21 +15786,46 @@ func (ec *executionContext) ___Directive_isRepeatable(ctx context.Context, field
}
return graphql.Null
}
- res := resTmp.(bool)
+ res := resTmp.([]introspection.InputValue)
fc.Result = res
- return ec.marshalNBoolean2bool(ctx, field.Selections, res)
+ return ec.marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext___Directive_isRepeatable(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext___Directive_args(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "__Directive",
Field: field,
IsMethod: false,
IsResolver: false,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
- return nil, errors.New("field of type Boolean does not have child fields")
+ switch field.Name {
+ case "name":
+ return ec.fieldContext___InputValue_name(ctx, field)
+ case "description":
+ return ec.fieldContext___InputValue_description(ctx, field)
+ case "type":
+ return ec.fieldContext___InputValue_type(ctx, field)
+ case "defaultValue":
+ return ec.fieldContext___InputValue_defaultValue(ctx, field)
+ case "isDeprecated":
+ return ec.fieldContext___InputValue_isDeprecated(ctx, field)
+ case "deprecationReason":
+ return ec.fieldContext___InputValue_deprecationReason(ctx, field)
+ }
+ return nil, fmt.Errorf("no field named %q was found under type __InputValue", field.Name)
},
}
+ defer func() {
+ if r := recover(); r != nil {
+ err = ec.Recover(ctx, r)
+ ec.Error(ctx, err)
+ }
+ }()
+ ctx = graphql.WithFieldContext(ctx, fc)
+ if fc.Args, err = ec.field___Directive_args_args(ctx, field.ArgumentMap(ec.Variables)); err != nil {
+ ec.Error(ctx, err)
+ return fc, err
+ }
return fc, nil
}
@@ -15536,7 +15841,7 @@ func (ec *executionContext) ___EnumValue_name(ctx context.Context, field graphql
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Name, nil
})
@@ -15555,7 +15860,7 @@ func (ec *executionContext) ___EnumValue_name(ctx context.Context, field graphql
return ec.marshalNString2string(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext___EnumValue_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext___EnumValue_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "__EnumValue",
Field: field,
@@ -15580,7 +15885,7 @@ func (ec *executionContext) ___EnumValue_description(ctx context.Context, field
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Description(), nil
})
@@ -15596,7 +15901,7 @@ func (ec *executionContext) ___EnumValue_description(ctx context.Context, field
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext___EnumValue_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext___EnumValue_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "__EnumValue",
Field: field,
@@ -15621,7 +15926,7 @@ func (ec *executionContext) ___EnumValue_isDeprecated(ctx context.Context, field
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.IsDeprecated(), nil
})
@@ -15640,7 +15945,7 @@ func (ec *executionContext) ___EnumValue_isDeprecated(ctx context.Context, field
return ec.marshalNBoolean2bool(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext___EnumValue_isDeprecated(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext___EnumValue_isDeprecated(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "__EnumValue",
Field: field,
@@ -15665,7 +15970,7 @@ func (ec *executionContext) ___EnumValue_deprecationReason(ctx context.Context,
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.DeprecationReason(), nil
})
@@ -15681,7 +15986,7 @@ func (ec *executionContext) ___EnumValue_deprecationReason(ctx context.Context,
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext___EnumValue_deprecationReason(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext___EnumValue_deprecationReason(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "__EnumValue",
Field: field,
@@ -15706,7 +16011,7 @@ func (ec *executionContext) ___Field_name(ctx context.Context, field graphql.Col
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Name, nil
})
@@ -15725,7 +16030,7 @@ func (ec *executionContext) ___Field_name(ctx context.Context, field graphql.Col
return ec.marshalNString2string(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext___Field_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext___Field_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "__Field",
Field: field,
@@ -15750,7 +16055,7 @@ func (ec *executionContext) ___Field_description(ctx context.Context, field grap
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Description(), nil
})
@@ -15766,7 +16071,7 @@ func (ec *executionContext) ___Field_description(ctx context.Context, field grap
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext___Field_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext___Field_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "__Field",
Field: field,
@@ -15791,7 +16096,7 @@ func (ec *executionContext) ___Field_args(ctx context.Context, field graphql.Col
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Args, nil
})
@@ -15826,10 +16131,25 @@ func (ec *executionContext) fieldContext___Field_args(ctx context.Context, field
return ec.fieldContext___InputValue_type(ctx, field)
case "defaultValue":
return ec.fieldContext___InputValue_defaultValue(ctx, field)
+ case "isDeprecated":
+ return ec.fieldContext___InputValue_isDeprecated(ctx, field)
+ case "deprecationReason":
+ return ec.fieldContext___InputValue_deprecationReason(ctx, field)
}
return nil, fmt.Errorf("no field named %q was found under type __InputValue", field.Name)
},
}
+ defer func() {
+ if r := recover(); r != nil {
+ err = ec.Recover(ctx, r)
+ ec.Error(ctx, err)
+ }
+ }()
+ ctx = graphql.WithFieldContext(ctx, fc)
+ if fc.Args, err = ec.field___Field_args_args(ctx, field.ArgumentMap(ec.Variables)); err != nil {
+ ec.Error(ctx, err)
+ return fc, err
+ }
return fc, nil
}
@@ -15845,7 +16165,7 @@ func (ec *executionContext) ___Field_type(ctx context.Context, field graphql.Col
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Type, nil
})
@@ -15864,7 +16184,7 @@ func (ec *executionContext) ___Field_type(ctx context.Context, field graphql.Col
return ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext___Field_type(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext___Field_type(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "__Field",
Field: field,
@@ -15878,6 +16198,8 @@ func (ec *executionContext) fieldContext___Field_type(ctx context.Context, field
return ec.fieldContext___Type_name(ctx, field)
case "description":
return ec.fieldContext___Type_description(ctx, field)
+ case "specifiedByURL":
+ return ec.fieldContext___Type_specifiedByURL(ctx, field)
case "fields":
return ec.fieldContext___Type_fields(ctx, field)
case "interfaces":
@@ -15890,8 +16212,8 @@ func (ec *executionContext) fieldContext___Field_type(ctx context.Context, field
return ec.fieldContext___Type_inputFields(ctx, field)
case "ofType":
return ec.fieldContext___Type_ofType(ctx, field)
- case "specifiedByURL":
- return ec.fieldContext___Type_specifiedByURL(ctx, field)
+ case "isOneOf":
+ return ec.fieldContext___Type_isOneOf(ctx, field)
}
return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name)
},
@@ -15911,7 +16233,7 @@ func (ec *executionContext) ___Field_isDeprecated(ctx context.Context, field gra
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.IsDeprecated(), nil
})
@@ -15930,7 +16252,7 @@ func (ec *executionContext) ___Field_isDeprecated(ctx context.Context, field gra
return ec.marshalNBoolean2bool(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext___Field_isDeprecated(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext___Field_isDeprecated(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "__Field",
Field: field,
@@ -15955,7 +16277,7 @@ func (ec *executionContext) ___Field_deprecationReason(ctx context.Context, fiel
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.DeprecationReason(), nil
})
@@ -15971,7 +16293,7 @@ func (ec *executionContext) ___Field_deprecationReason(ctx context.Context, fiel
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext___Field_deprecationReason(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext___Field_deprecationReason(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "__Field",
Field: field,
@@ -15996,7 +16318,7 @@ func (ec *executionContext) ___InputValue_name(ctx context.Context, field graphq
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Name, nil
})
@@ -16015,7 +16337,7 @@ func (ec *executionContext) ___InputValue_name(ctx context.Context, field graphq
return ec.marshalNString2string(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext___InputValue_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext___InputValue_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "__InputValue",
Field: field,
@@ -16040,7 +16362,7 @@ func (ec *executionContext) ___InputValue_description(ctx context.Context, field
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Description(), nil
})
@@ -16056,7 +16378,7 @@ func (ec *executionContext) ___InputValue_description(ctx context.Context, field
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext___InputValue_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext___InputValue_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "__InputValue",
Field: field,
@@ -16081,7 +16403,7 @@ func (ec *executionContext) ___InputValue_type(ctx context.Context, field graphq
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Type, nil
})
@@ -16100,7 +16422,7 @@ func (ec *executionContext) ___InputValue_type(ctx context.Context, field graphq
return ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext___InputValue_type(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext___InputValue_type(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "__InputValue",
Field: field,
@@ -16114,6 +16436,8 @@ func (ec *executionContext) fieldContext___InputValue_type(ctx context.Context,
return ec.fieldContext___Type_name(ctx, field)
case "description":
return ec.fieldContext___Type_description(ctx, field)
+ case "specifiedByURL":
+ return ec.fieldContext___Type_specifiedByURL(ctx, field)
case "fields":
return ec.fieldContext___Type_fields(ctx, field)
case "interfaces":
@@ -16126,8 +16450,8 @@ func (ec *executionContext) fieldContext___InputValue_type(ctx context.Context,
return ec.fieldContext___Type_inputFields(ctx, field)
case "ofType":
return ec.fieldContext___Type_ofType(ctx, field)
- case "specifiedByURL":
- return ec.fieldContext___Type_specifiedByURL(ctx, field)
+ case "isOneOf":
+ return ec.fieldContext___Type_isOneOf(ctx, field)
}
return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name)
},
@@ -16147,7 +16471,7 @@ func (ec *executionContext) ___InputValue_defaultValue(ctx context.Context, fiel
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.DefaultValue, nil
})
@@ -16163,7 +16487,7 @@ func (ec *executionContext) ___InputValue_defaultValue(ctx context.Context, fiel
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext___InputValue_defaultValue(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext___InputValue_defaultValue(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "__InputValue",
Field: field,
@@ -16176,6 +16500,91 @@ func (ec *executionContext) fieldContext___InputValue_defaultValue(ctx context.C
return fc, nil
}
+func (ec *executionContext) ___InputValue_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) {
+ fc, err := ec.fieldContext___InputValue_isDeprecated(ctx, field)
+ if err != nil {
+ return graphql.Null
+ }
+ ctx = graphql.WithFieldContext(ctx, fc)
+ defer func() {
+ if r := recover(); r != nil {
+ ec.Error(ctx, ec.Recover(ctx, r))
+ ret = graphql.Null
+ }
+ }()
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
+ ctx = rctx // use context from middleware stack in children
+ return obj.IsDeprecated(), nil
+ })
+ if err != nil {
+ ec.Error(ctx, err)
+ return graphql.Null
+ }
+ if resTmp == nil {
+ if !graphql.HasFieldError(ctx, fc) {
+ ec.Errorf(ctx, "must not be null")
+ }
+ return graphql.Null
+ }
+ res := resTmp.(bool)
+ fc.Result = res
+ return ec.marshalNBoolean2bool(ctx, field.Selections, res)
+}
+
+func (ec *executionContext) fieldContext___InputValue_isDeprecated(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+ fc = &graphql.FieldContext{
+ Object: "__InputValue",
+ Field: field,
+ IsMethod: true,
+ IsResolver: false,
+ Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
+ return nil, errors.New("field of type Boolean does not have child fields")
+ },
+ }
+ return fc, nil
+}
+
+func (ec *executionContext) ___InputValue_deprecationReason(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) {
+ fc, err := ec.fieldContext___InputValue_deprecationReason(ctx, field)
+ if err != nil {
+ return graphql.Null
+ }
+ ctx = graphql.WithFieldContext(ctx, fc)
+ defer func() {
+ if r := recover(); r != nil {
+ ec.Error(ctx, ec.Recover(ctx, r))
+ ret = graphql.Null
+ }
+ }()
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
+ ctx = rctx // use context from middleware stack in children
+ return obj.DeprecationReason(), nil
+ })
+ if err != nil {
+ ec.Error(ctx, err)
+ return graphql.Null
+ }
+ if resTmp == nil {
+ return graphql.Null
+ }
+ res := resTmp.(*string)
+ fc.Result = res
+ return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
+}
+
+func (ec *executionContext) fieldContext___InputValue_deprecationReason(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+ fc = &graphql.FieldContext{
+ Object: "__InputValue",
+ Field: field,
+ IsMethod: true,
+ IsResolver: false,
+ Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
+ return nil, errors.New("field of type String does not have child fields")
+ },
+ }
+ return fc, nil
+}
+
func (ec *executionContext) ___Schema_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) {
fc, err := ec.fieldContext___Schema_description(ctx, field)
if err != nil {
@@ -16188,7 +16597,7 @@ func (ec *executionContext) ___Schema_description(ctx context.Context, field gra
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Description(), nil
})
@@ -16204,7 +16613,7 @@ func (ec *executionContext) ___Schema_description(ctx context.Context, field gra
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext___Schema_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext___Schema_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "__Schema",
Field: field,
@@ -16229,7 +16638,7 @@ func (ec *executionContext) ___Schema_types(ctx context.Context, field graphql.C
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Types(), nil
})
@@ -16248,7 +16657,7 @@ func (ec *executionContext) ___Schema_types(ctx context.Context, field graphql.C
return ec.marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext___Schema_types(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext___Schema_types(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "__Schema",
Field: field,
@@ -16262,6 +16671,8 @@ func (ec *executionContext) fieldContext___Schema_types(ctx context.Context, fie
return ec.fieldContext___Type_name(ctx, field)
case "description":
return ec.fieldContext___Type_description(ctx, field)
+ case "specifiedByURL":
+ return ec.fieldContext___Type_specifiedByURL(ctx, field)
case "fields":
return ec.fieldContext___Type_fields(ctx, field)
case "interfaces":
@@ -16274,8 +16685,8 @@ func (ec *executionContext) fieldContext___Schema_types(ctx context.Context, fie
return ec.fieldContext___Type_inputFields(ctx, field)
case "ofType":
return ec.fieldContext___Type_ofType(ctx, field)
- case "specifiedByURL":
- return ec.fieldContext___Type_specifiedByURL(ctx, field)
+ case "isOneOf":
+ return ec.fieldContext___Type_isOneOf(ctx, field)
}
return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name)
},
@@ -16295,7 +16706,7 @@ func (ec *executionContext) ___Schema_queryType(ctx context.Context, field graph
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.QueryType(), nil
})
@@ -16314,7 +16725,7 @@ func (ec *executionContext) ___Schema_queryType(ctx context.Context, field graph
return ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext___Schema_queryType(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext___Schema_queryType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "__Schema",
Field: field,
@@ -16328,6 +16739,8 @@ func (ec *executionContext) fieldContext___Schema_queryType(ctx context.Context,
return ec.fieldContext___Type_name(ctx, field)
case "description":
return ec.fieldContext___Type_description(ctx, field)
+ case "specifiedByURL":
+ return ec.fieldContext___Type_specifiedByURL(ctx, field)
case "fields":
return ec.fieldContext___Type_fields(ctx, field)
case "interfaces":
@@ -16340,8 +16753,8 @@ func (ec *executionContext) fieldContext___Schema_queryType(ctx context.Context,
return ec.fieldContext___Type_inputFields(ctx, field)
case "ofType":
return ec.fieldContext___Type_ofType(ctx, field)
- case "specifiedByURL":
- return ec.fieldContext___Type_specifiedByURL(ctx, field)
+ case "isOneOf":
+ return ec.fieldContext___Type_isOneOf(ctx, field)
}
return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name)
},
@@ -16361,7 +16774,7 @@ func (ec *executionContext) ___Schema_mutationType(ctx context.Context, field gr
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.MutationType(), nil
})
@@ -16377,7 +16790,7 @@ func (ec *executionContext) ___Schema_mutationType(ctx context.Context, field gr
return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext___Schema_mutationType(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext___Schema_mutationType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "__Schema",
Field: field,
@@ -16391,6 +16804,8 @@ func (ec *executionContext) fieldContext___Schema_mutationType(ctx context.Conte
return ec.fieldContext___Type_name(ctx, field)
case "description":
return ec.fieldContext___Type_description(ctx, field)
+ case "specifiedByURL":
+ return ec.fieldContext___Type_specifiedByURL(ctx, field)
case "fields":
return ec.fieldContext___Type_fields(ctx, field)
case "interfaces":
@@ -16403,8 +16818,8 @@ func (ec *executionContext) fieldContext___Schema_mutationType(ctx context.Conte
return ec.fieldContext___Type_inputFields(ctx, field)
case "ofType":
return ec.fieldContext___Type_ofType(ctx, field)
- case "specifiedByURL":
- return ec.fieldContext___Type_specifiedByURL(ctx, field)
+ case "isOneOf":
+ return ec.fieldContext___Type_isOneOf(ctx, field)
}
return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name)
},
@@ -16424,7 +16839,7 @@ func (ec *executionContext) ___Schema_subscriptionType(ctx context.Context, fiel
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.SubscriptionType(), nil
})
@@ -16440,7 +16855,7 @@ func (ec *executionContext) ___Schema_subscriptionType(ctx context.Context, fiel
return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext___Schema_subscriptionType(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext___Schema_subscriptionType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "__Schema",
Field: field,
@@ -16454,6 +16869,8 @@ func (ec *executionContext) fieldContext___Schema_subscriptionType(ctx context.C
return ec.fieldContext___Type_name(ctx, field)
case "description":
return ec.fieldContext___Type_description(ctx, field)
+ case "specifiedByURL":
+ return ec.fieldContext___Type_specifiedByURL(ctx, field)
case "fields":
return ec.fieldContext___Type_fields(ctx, field)
case "interfaces":
@@ -16466,8 +16883,8 @@ func (ec *executionContext) fieldContext___Schema_subscriptionType(ctx context.C
return ec.fieldContext___Type_inputFields(ctx, field)
case "ofType":
return ec.fieldContext___Type_ofType(ctx, field)
- case "specifiedByURL":
- return ec.fieldContext___Type_specifiedByURL(ctx, field)
+ case "isOneOf":
+ return ec.fieldContext___Type_isOneOf(ctx, field)
}
return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name)
},
@@ -16487,7 +16904,7 @@ func (ec *executionContext) ___Schema_directives(ctx context.Context, field grap
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Directives(), nil
})
@@ -16506,7 +16923,7 @@ func (ec *executionContext) ___Schema_directives(ctx context.Context, field grap
return ec.marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirectiveᚄ(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext___Schema_directives(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext___Schema_directives(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "__Schema",
Field: field,
@@ -16518,12 +16935,12 @@ func (ec *executionContext) fieldContext___Schema_directives(ctx context.Context
return ec.fieldContext___Directive_name(ctx, field)
case "description":
return ec.fieldContext___Directive_description(ctx, field)
+ case "isRepeatable":
+ return ec.fieldContext___Directive_isRepeatable(ctx, field)
case "locations":
return ec.fieldContext___Directive_locations(ctx, field)
case "args":
return ec.fieldContext___Directive_args(ctx, field)
- case "isRepeatable":
- return ec.fieldContext___Directive_isRepeatable(ctx, field)
}
return nil, fmt.Errorf("no field named %q was found under type __Directive", field.Name)
},
@@ -16543,7 +16960,7 @@ func (ec *executionContext) ___Type_kind(ctx context.Context, field graphql.Coll
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Kind(), nil
})
@@ -16562,7 +16979,7 @@ func (ec *executionContext) ___Type_kind(ctx context.Context, field graphql.Coll
return ec.marshalN__TypeKind2string(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext___Type_kind(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext___Type_kind(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "__Type",
Field: field,
@@ -16587,7 +17004,7 @@ func (ec *executionContext) ___Type_name(ctx context.Context, field graphql.Coll
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Name(), nil
})
@@ -16603,7 +17020,7 @@ func (ec *executionContext) ___Type_name(ctx context.Context, field graphql.Coll
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext___Type_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext___Type_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "__Type",
Field: field,
@@ -16628,7 +17045,7 @@ func (ec *executionContext) ___Type_description(ctx context.Context, field graph
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Description(), nil
})
@@ -16644,7 +17061,48 @@ func (ec *executionContext) ___Type_description(ctx context.Context, field graph
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext___Type_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext___Type_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+ fc = &graphql.FieldContext{
+ Object: "__Type",
+ Field: field,
+ IsMethod: true,
+ IsResolver: false,
+ Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
+ return nil, errors.New("field of type String does not have child fields")
+ },
+ }
+ return fc, nil
+}
+
+func (ec *executionContext) ___Type_specifiedByURL(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) {
+ fc, err := ec.fieldContext___Type_specifiedByURL(ctx, field)
+ if err != nil {
+ return graphql.Null
+ }
+ ctx = graphql.WithFieldContext(ctx, fc)
+ defer func() {
+ if r := recover(); r != nil {
+ ec.Error(ctx, ec.Recover(ctx, r))
+ ret = graphql.Null
+ }
+ }()
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
+ ctx = rctx // use context from middleware stack in children
+ return obj.SpecifiedByURL(), nil
+ })
+ if err != nil {
+ ec.Error(ctx, err)
+ return graphql.Null
+ }
+ if resTmp == nil {
+ return graphql.Null
+ }
+ res := resTmp.(*string)
+ fc.Result = res
+ return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
+}
+
+func (ec *executionContext) fieldContext___Type_specifiedByURL(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "__Type",
Field: field,
@@ -16669,7 +17127,7 @@ func (ec *executionContext) ___Type_fields(ctx context.Context, field graphql.Co
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Fields(fc.Args["includeDeprecated"].(bool)), nil
})
@@ -16735,7 +17193,7 @@ func (ec *executionContext) ___Type_interfaces(ctx context.Context, field graphq
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Interfaces(), nil
})
@@ -16751,7 +17209,7 @@ func (ec *executionContext) ___Type_interfaces(ctx context.Context, field graphq
return ec.marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext___Type_interfaces(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext___Type_interfaces(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "__Type",
Field: field,
@@ -16765,6 +17223,8 @@ func (ec *executionContext) fieldContext___Type_interfaces(ctx context.Context,
return ec.fieldContext___Type_name(ctx, field)
case "description":
return ec.fieldContext___Type_description(ctx, field)
+ case "specifiedByURL":
+ return ec.fieldContext___Type_specifiedByURL(ctx, field)
case "fields":
return ec.fieldContext___Type_fields(ctx, field)
case "interfaces":
@@ -16777,8 +17237,8 @@ func (ec *executionContext) fieldContext___Type_interfaces(ctx context.Context,
return ec.fieldContext___Type_inputFields(ctx, field)
case "ofType":
return ec.fieldContext___Type_ofType(ctx, field)
- case "specifiedByURL":
- return ec.fieldContext___Type_specifiedByURL(ctx, field)
+ case "isOneOf":
+ return ec.fieldContext___Type_isOneOf(ctx, field)
}
return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name)
},
@@ -16798,7 +17258,7 @@ func (ec *executionContext) ___Type_possibleTypes(ctx context.Context, field gra
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.PossibleTypes(), nil
})
@@ -16814,7 +17274,7 @@ func (ec *executionContext) ___Type_possibleTypes(ctx context.Context, field gra
return ec.marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext___Type_possibleTypes(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext___Type_possibleTypes(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "__Type",
Field: field,
@@ -16828,6 +17288,8 @@ func (ec *executionContext) fieldContext___Type_possibleTypes(ctx context.Contex
return ec.fieldContext___Type_name(ctx, field)
case "description":
return ec.fieldContext___Type_description(ctx, field)
+ case "specifiedByURL":
+ return ec.fieldContext___Type_specifiedByURL(ctx, field)
case "fields":
return ec.fieldContext___Type_fields(ctx, field)
case "interfaces":
@@ -16840,8 +17302,8 @@ func (ec *executionContext) fieldContext___Type_possibleTypes(ctx context.Contex
return ec.fieldContext___Type_inputFields(ctx, field)
case "ofType":
return ec.fieldContext___Type_ofType(ctx, field)
- case "specifiedByURL":
- return ec.fieldContext___Type_specifiedByURL(ctx, field)
+ case "isOneOf":
+ return ec.fieldContext___Type_isOneOf(ctx, field)
}
return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name)
},
@@ -16861,7 +17323,7 @@ func (ec *executionContext) ___Type_enumValues(ctx context.Context, field graphq
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.EnumValues(fc.Args["includeDeprecated"].(bool)), nil
})
@@ -16923,7 +17385,7 @@ func (ec *executionContext) ___Type_inputFields(ctx context.Context, field graph
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.InputFields(), nil
})
@@ -16939,7 +17401,7 @@ func (ec *executionContext) ___Type_inputFields(ctx context.Context, field graph
return ec.marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext___Type_inputFields(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext___Type_inputFields(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "__Type",
Field: field,
@@ -16955,6 +17417,10 @@ func (ec *executionContext) fieldContext___Type_inputFields(ctx context.Context,
return ec.fieldContext___InputValue_type(ctx, field)
case "defaultValue":
return ec.fieldContext___InputValue_defaultValue(ctx, field)
+ case "isDeprecated":
+ return ec.fieldContext___InputValue_isDeprecated(ctx, field)
+ case "deprecationReason":
+ return ec.fieldContext___InputValue_deprecationReason(ctx, field)
}
return nil, fmt.Errorf("no field named %q was found under type __InputValue", field.Name)
},
@@ -16974,7 +17440,7 @@ func (ec *executionContext) ___Type_ofType(ctx context.Context, field graphql.Co
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.OfType(), nil
})
@@ -16990,7 +17456,7 @@ func (ec *executionContext) ___Type_ofType(ctx context.Context, field graphql.Co
return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext___Type_ofType(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext___Type_ofType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "__Type",
Field: field,
@@ -17004,6 +17470,8 @@ func (ec *executionContext) fieldContext___Type_ofType(ctx context.Context, fiel
return ec.fieldContext___Type_name(ctx, field)
case "description":
return ec.fieldContext___Type_description(ctx, field)
+ case "specifiedByURL":
+ return ec.fieldContext___Type_specifiedByURL(ctx, field)
case "fields":
return ec.fieldContext___Type_fields(ctx, field)
case "interfaces":
@@ -17016,8 +17484,8 @@ func (ec *executionContext) fieldContext___Type_ofType(ctx context.Context, fiel
return ec.fieldContext___Type_inputFields(ctx, field)
case "ofType":
return ec.fieldContext___Type_ofType(ctx, field)
- case "specifiedByURL":
- return ec.fieldContext___Type_specifiedByURL(ctx, field)
+ case "isOneOf":
+ return ec.fieldContext___Type_isOneOf(ctx, field)
}
return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name)
},
@@ -17025,8 +17493,8 @@ func (ec *executionContext) fieldContext___Type_ofType(ctx context.Context, fiel
return fc, nil
}
-func (ec *executionContext) ___Type_specifiedByURL(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) {
- fc, err := ec.fieldContext___Type_specifiedByURL(ctx, field)
+func (ec *executionContext) ___Type_isOneOf(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) {
+ fc, err := ec.fieldContext___Type_isOneOf(ctx, field)
if err != nil {
return graphql.Null
}
@@ -17037,9 +17505,9 @@ func (ec *executionContext) ___Type_specifiedByURL(ctx context.Context, field gr
ret = graphql.Null
}
}()
- resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
+ resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
- return obj.SpecifiedByURL(), nil
+ return obj.IsOneOf(), nil
})
if err != nil {
ec.Error(ctx, err)
@@ -17048,19 +17516,19 @@ func (ec *executionContext) ___Type_specifiedByURL(ctx context.Context, field gr
if resTmp == nil {
return graphql.Null
}
- res := resTmp.(*string)
+ res := resTmp.(bool)
fc.Result = res
- return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
+ return ec.marshalOBoolean2bool(ctx, field.Selections, res)
}
-func (ec *executionContext) fieldContext___Type_specifiedByURL(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) fieldContext___Type_isOneOf(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "__Type",
Field: field,
IsMethod: true,
IsResolver: false,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
- return nil, errors.New("field of type String does not have child fields")
+ return nil, errors.New("field of type Boolean does not have child fields")
},
}
return fc, nil
@@ -17070,10 +17538,10 @@ func (ec *executionContext) fieldContext___Type_specifiedByURL(ctx context.Conte
// region **************************** input.gotpl *****************************
-func (ec *executionContext) unmarshalInputAddEmailTemplateRequest(ctx context.Context, obj interface{}) (model.AddEmailTemplateRequest, error) {
+func (ec *executionContext) unmarshalInputAddEmailTemplateRequest(ctx context.Context, obj any) (model.AddEmailTemplateRequest, error) {
var it model.AddEmailTemplateRequest
- asMap := map[string]interface{}{}
- for k, v := range obj.(map[string]interface{}) {
+ asMap := map[string]any{}
+ for k, v := range obj.(map[string]any) {
asMap[k] = v
}
@@ -17118,10 +17586,10 @@ func (ec *executionContext) unmarshalInputAddEmailTemplateRequest(ctx context.Co
return it, nil
}
-func (ec *executionContext) unmarshalInputAddWebhookRequest(ctx context.Context, obj interface{}) (model.AddWebhookRequest, error) {
+func (ec *executionContext) unmarshalInputAddWebhookRequest(ctx context.Context, obj any) (model.AddWebhookRequest, error) {
var it model.AddWebhookRequest
- asMap := map[string]interface{}{}
- for k, v := range obj.(map[string]interface{}) {
+ asMap := map[string]any{}
+ for k, v := range obj.(map[string]any) {
asMap[k] = v
}
@@ -17173,10 +17641,10 @@ func (ec *executionContext) unmarshalInputAddWebhookRequest(ctx context.Context,
return it, nil
}
-func (ec *executionContext) unmarshalInputAdminLoginInput(ctx context.Context, obj interface{}) (model.AdminLoginInput, error) {
- var it model.AdminLoginInput
- asMap := map[string]interface{}{}
- for k, v := range obj.(map[string]interface{}) {
+func (ec *executionContext) unmarshalInputAdminLoginRequest(ctx context.Context, obj any) (model.AdminLoginRequest, error) {
+ var it model.AdminLoginRequest
+ asMap := map[string]any{}
+ for k, v := range obj.(map[string]any) {
asMap[k] = v
}
@@ -17200,10 +17668,10 @@ func (ec *executionContext) unmarshalInputAdminLoginInput(ctx context.Context, o
return it, nil
}
-func (ec *executionContext) unmarshalInputAdminSignupInput(ctx context.Context, obj interface{}) (model.AdminSignupInput, error) {
- var it model.AdminSignupInput
- asMap := map[string]interface{}{}
- for k, v := range obj.(map[string]interface{}) {
+func (ec *executionContext) unmarshalInputAdminSignupRequest(ctx context.Context, obj any) (model.AdminSignupRequest, error) {
+ var it model.AdminSignupRequest
+ asMap := map[string]any{}
+ for k, v := range obj.(map[string]any) {
asMap[k] = v
}
@@ -17227,10 +17695,10 @@ func (ec *executionContext) unmarshalInputAdminSignupInput(ctx context.Context,
return it, nil
}
-func (ec *executionContext) unmarshalInputDeleteEmailTemplateRequest(ctx context.Context, obj interface{}) (model.DeleteEmailTemplateRequest, error) {
+func (ec *executionContext) unmarshalInputDeleteEmailTemplateRequest(ctx context.Context, obj any) (model.DeleteEmailTemplateRequest, error) {
var it model.DeleteEmailTemplateRequest
- asMap := map[string]interface{}{}
- for k, v := range obj.(map[string]interface{}) {
+ asMap := map[string]any{}
+ for k, v := range obj.(map[string]any) {
asMap[k] = v
}
@@ -17254,10 +17722,10 @@ func (ec *executionContext) unmarshalInputDeleteEmailTemplateRequest(ctx context
return it, nil
}
-func (ec *executionContext) unmarshalInputDeleteUserInput(ctx context.Context, obj interface{}) (model.DeleteUserInput, error) {
- var it model.DeleteUserInput
- asMap := map[string]interface{}{}
- for k, v := range obj.(map[string]interface{}) {
+func (ec *executionContext) unmarshalInputDeleteUserRequest(ctx context.Context, obj any) (model.DeleteUserRequest, error) {
+ var it model.DeleteUserRequest
+ asMap := map[string]any{}
+ for k, v := range obj.(map[string]any) {
asMap[k] = v
}
@@ -17281,10 +17749,10 @@ func (ec *executionContext) unmarshalInputDeleteUserInput(ctx context.Context, o
return it, nil
}
-func (ec *executionContext) unmarshalInputForgotPasswordInput(ctx context.Context, obj interface{}) (model.ForgotPasswordInput, error) {
- var it model.ForgotPasswordInput
- asMap := map[string]interface{}{}
- for k, v := range obj.(map[string]interface{}) {
+func (ec *executionContext) unmarshalInputForgotPasswordRequest(ctx context.Context, obj any) (model.ForgotPasswordRequest, error) {
+ var it model.ForgotPasswordRequest
+ asMap := map[string]any{}
+ for k, v := range obj.(map[string]any) {
asMap[k] = v
}
@@ -17329,10 +17797,10 @@ func (ec *executionContext) unmarshalInputForgotPasswordInput(ctx context.Contex
return it, nil
}
-func (ec *executionContext) unmarshalInputGenerateJWTKeysInput(ctx context.Context, obj interface{}) (model.GenerateJWTKeysInput, error) {
- var it model.GenerateJWTKeysInput
- asMap := map[string]interface{}{}
- for k, v := range obj.(map[string]interface{}) {
+func (ec *executionContext) unmarshalInputGenerateJWTKeysRequest(ctx context.Context, obj any) (model.GenerateJWTKeysRequest, error) {
+ var it model.GenerateJWTKeysRequest
+ asMap := map[string]any{}
+ for k, v := range obj.(map[string]any) {
asMap[k] = v
}
@@ -17356,10 +17824,10 @@ func (ec *executionContext) unmarshalInputGenerateJWTKeysInput(ctx context.Conte
return it, nil
}
-func (ec *executionContext) unmarshalInputGetUserRequest(ctx context.Context, obj interface{}) (model.GetUserRequest, error) {
+func (ec *executionContext) unmarshalInputGetUserRequest(ctx context.Context, obj any) (model.GetUserRequest, error) {
var it model.GetUserRequest
- asMap := map[string]interface{}{}
- for k, v := range obj.(map[string]interface{}) {
+ asMap := map[string]any{}
+ for k, v := range obj.(map[string]any) {
asMap[k] = v
}
@@ -17390,10 +17858,10 @@ func (ec *executionContext) unmarshalInputGetUserRequest(ctx context.Context, ob
return it, nil
}
-func (ec *executionContext) unmarshalInputInviteMemberInput(ctx context.Context, obj interface{}) (model.InviteMemberInput, error) {
- var it model.InviteMemberInput
- asMap := map[string]interface{}{}
- for k, v := range obj.(map[string]interface{}) {
+func (ec *executionContext) unmarshalInputInviteMemberRequest(ctx context.Context, obj any) (model.InviteMemberRequest, error) {
+ var it model.InviteMemberRequest
+ asMap := map[string]any{}
+ for k, v := range obj.(map[string]any) {
asMap[k] = v
}
@@ -17424,10 +17892,10 @@ func (ec *executionContext) unmarshalInputInviteMemberInput(ctx context.Context,
return it, nil
}
-func (ec *executionContext) unmarshalInputListWebhookLogRequest(ctx context.Context, obj interface{}) (model.ListWebhookLogRequest, error) {
+func (ec *executionContext) unmarshalInputListWebhookLogRequest(ctx context.Context, obj any) (model.ListWebhookLogRequest, error) {
var it model.ListWebhookLogRequest
- asMap := map[string]interface{}{}
- for k, v := range obj.(map[string]interface{}) {
+ asMap := map[string]any{}
+ for k, v := range obj.(map[string]any) {
asMap[k] = v
}
@@ -17440,7 +17908,7 @@ func (ec *executionContext) unmarshalInputListWebhookLogRequest(ctx context.Cont
switch k {
case "pagination":
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("pagination"))
- data, err := ec.unmarshalOPaginationInput2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐPaginationInput(ctx, v)
+ data, err := ec.unmarshalOPaginationRequest2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐPaginationRequest(ctx, v)
if err != nil {
return it, err
}
@@ -17458,10 +17926,10 @@ func (ec *executionContext) unmarshalInputListWebhookLogRequest(ctx context.Cont
return it, nil
}
-func (ec *executionContext) unmarshalInputLoginInput(ctx context.Context, obj interface{}) (model.LoginInput, error) {
- var it model.LoginInput
- asMap := map[string]interface{}{}
- for k, v := range obj.(map[string]interface{}) {
+func (ec *executionContext) unmarshalInputLoginRequest(ctx context.Context, obj any) (model.LoginRequest, error) {
+ var it model.LoginRequest
+ asMap := map[string]any{}
+ for k, v := range obj.(map[string]any) {
asMap[k] = v
}
@@ -17520,10 +17988,10 @@ func (ec *executionContext) unmarshalInputLoginInput(ctx context.Context, obj in
return it, nil
}
-func (ec *executionContext) unmarshalInputMagicLinkLoginInput(ctx context.Context, obj interface{}) (model.MagicLinkLoginInput, error) {
- var it model.MagicLinkLoginInput
- asMap := map[string]interface{}{}
- for k, v := range obj.(map[string]interface{}) {
+func (ec *executionContext) unmarshalInputMagicLinkLoginRequest(ctx context.Context, obj any) (model.MagicLinkLoginRequest, error) {
+ var it model.MagicLinkLoginRequest
+ asMap := map[string]any{}
+ for k, v := range obj.(map[string]any) {
asMap[k] = v
}
@@ -17575,10 +18043,10 @@ func (ec *executionContext) unmarshalInputMagicLinkLoginInput(ctx context.Contex
return it, nil
}
-func (ec *executionContext) unmarshalInputMobileLoginInput(ctx context.Context, obj interface{}) (model.MobileLoginInput, error) {
- var it model.MobileLoginInput
- asMap := map[string]interface{}{}
- for k, v := range obj.(map[string]interface{}) {
+func (ec *executionContext) unmarshalInputMobileLoginRequest(ctx context.Context, obj any) (model.MobileLoginRequest, error) {
+ var it model.MobileLoginRequest
+ asMap := map[string]any{}
+ for k, v := range obj.(map[string]any) {
asMap[k] = v
}
@@ -17630,10 +18098,10 @@ func (ec *executionContext) unmarshalInputMobileLoginInput(ctx context.Context,
return it, nil
}
-func (ec *executionContext) unmarshalInputMobileSignUpInput(ctx context.Context, obj interface{}) (model.MobileSignUpInput, error) {
- var it model.MobileSignUpInput
- asMap := map[string]interface{}{}
- for k, v := range obj.(map[string]interface{}) {
+func (ec *executionContext) unmarshalInputMobileSignUpRequest(ctx context.Context, obj any) (model.MobileSignUpRequest, error) {
+ var it model.MobileSignUpRequest
+ asMap := map[string]any{}
+ for k, v := range obj.(map[string]any) {
asMap[k] = v
}
@@ -17769,10 +18237,10 @@ func (ec *executionContext) unmarshalInputMobileSignUpInput(ctx context.Context,
return it, nil
}
-func (ec *executionContext) unmarshalInputOAuthRevokeInput(ctx context.Context, obj interface{}) (model.OAuthRevokeInput, error) {
- var it model.OAuthRevokeInput
- asMap := map[string]interface{}{}
- for k, v := range obj.(map[string]interface{}) {
+func (ec *executionContext) unmarshalInputOAuthRevokeRequest(ctx context.Context, obj any) (model.OAuthRevokeRequest, error) {
+ var it model.OAuthRevokeRequest
+ asMap := map[string]any{}
+ for k, v := range obj.(map[string]any) {
asMap[k] = v
}
@@ -17796,10 +18264,10 @@ func (ec *executionContext) unmarshalInputOAuthRevokeInput(ctx context.Context,
return it, nil
}
-func (ec *executionContext) unmarshalInputPaginatedInput(ctx context.Context, obj interface{}) (model.PaginatedInput, error) {
- var it model.PaginatedInput
- asMap := map[string]interface{}{}
- for k, v := range obj.(map[string]interface{}) {
+func (ec *executionContext) unmarshalInputPaginatedRequest(ctx context.Context, obj any) (model.PaginatedRequest, error) {
+ var it model.PaginatedRequest
+ asMap := map[string]any{}
+ for k, v := range obj.(map[string]any) {
asMap[k] = v
}
@@ -17812,7 +18280,7 @@ func (ec *executionContext) unmarshalInputPaginatedInput(ctx context.Context, ob
switch k {
case "pagination":
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("pagination"))
- data, err := ec.unmarshalOPaginationInput2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐPaginationInput(ctx, v)
+ data, err := ec.unmarshalOPaginationRequest2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐPaginationRequest(ctx, v)
if err != nil {
return it, err
}
@@ -17823,10 +18291,10 @@ func (ec *executionContext) unmarshalInputPaginatedInput(ctx context.Context, ob
return it, nil
}
-func (ec *executionContext) unmarshalInputPaginationInput(ctx context.Context, obj interface{}) (model.PaginationInput, error) {
- var it model.PaginationInput
- asMap := map[string]interface{}{}
- for k, v := range obj.(map[string]interface{}) {
+func (ec *executionContext) unmarshalInputPaginationRequest(ctx context.Context, obj any) (model.PaginationRequest, error) {
+ var it model.PaginationRequest
+ asMap := map[string]any{}
+ for k, v := range obj.(map[string]any) {
asMap[k] = v
}
@@ -17857,10 +18325,10 @@ func (ec *executionContext) unmarshalInputPaginationInput(ctx context.Context, o
return it, nil
}
-func (ec *executionContext) unmarshalInputResendOTPRequest(ctx context.Context, obj interface{}) (model.ResendOTPRequest, error) {
+func (ec *executionContext) unmarshalInputResendOTPRequest(ctx context.Context, obj any) (model.ResendOTPRequest, error) {
var it model.ResendOTPRequest
- asMap := map[string]interface{}{}
- for k, v := range obj.(map[string]interface{}) {
+ asMap := map[string]any{}
+ for k, v := range obj.(map[string]any) {
asMap[k] = v
}
@@ -17898,10 +18366,10 @@ func (ec *executionContext) unmarshalInputResendOTPRequest(ctx context.Context,
return it, nil
}
-func (ec *executionContext) unmarshalInputResendVerifyEmailInput(ctx context.Context, obj interface{}) (model.ResendVerifyEmailInput, error) {
- var it model.ResendVerifyEmailInput
- asMap := map[string]interface{}{}
- for k, v := range obj.(map[string]interface{}) {
+func (ec *executionContext) unmarshalInputResendVerifyEmailRequest(ctx context.Context, obj any) (model.ResendVerifyEmailRequest, error) {
+ var it model.ResendVerifyEmailRequest
+ asMap := map[string]any{}
+ for k, v := range obj.(map[string]any) {
asMap[k] = v
}
@@ -17939,10 +18407,10 @@ func (ec *executionContext) unmarshalInputResendVerifyEmailInput(ctx context.Con
return it, nil
}
-func (ec *executionContext) unmarshalInputResetPasswordInput(ctx context.Context, obj interface{}) (model.ResetPasswordInput, error) {
- var it model.ResetPasswordInput
- asMap := map[string]interface{}{}
- for k, v := range obj.(map[string]interface{}) {
+func (ec *executionContext) unmarshalInputResetPasswordRequest(ctx context.Context, obj any) (model.ResetPasswordRequest, error) {
+ var it model.ResetPasswordRequest
+ asMap := map[string]any{}
+ for k, v := range obj.(map[string]any) {
asMap[k] = v
}
@@ -17994,10 +18462,10 @@ func (ec *executionContext) unmarshalInputResetPasswordInput(ctx context.Context
return it, nil
}
-func (ec *executionContext) unmarshalInputSessionQueryInput(ctx context.Context, obj interface{}) (model.SessionQueryInput, error) {
- var it model.SessionQueryInput
- asMap := map[string]interface{}{}
- for k, v := range obj.(map[string]interface{}) {
+func (ec *executionContext) unmarshalInputSessionQueryRequest(ctx context.Context, obj any) (model.SessionQueryRequest, error) {
+ var it model.SessionQueryRequest
+ asMap := map[string]any{}
+ for k, v := range obj.(map[string]any) {
asMap[k] = v
}
@@ -18028,10 +18496,10 @@ func (ec *executionContext) unmarshalInputSessionQueryInput(ctx context.Context,
return it, nil
}
-func (ec *executionContext) unmarshalInputSignUpInput(ctx context.Context, obj interface{}) (model.SignUpInput, error) {
- var it model.SignUpInput
- asMap := map[string]interface{}{}
- for k, v := range obj.(map[string]interface{}) {
+func (ec *executionContext) unmarshalInputSignUpRequest(ctx context.Context, obj any) (model.SignUpRequest, error) {
+ var it model.SignUpRequest
+ asMap := map[string]any{}
+ for k, v := range obj.(map[string]any) {
asMap[k] = v
}
@@ -18167,10 +18635,10 @@ func (ec *executionContext) unmarshalInputSignUpInput(ctx context.Context, obj i
return it, nil
}
-func (ec *executionContext) unmarshalInputTestEndpointRequest(ctx context.Context, obj interface{}) (model.TestEndpointRequest, error) {
+func (ec *executionContext) unmarshalInputTestEndpointRequest(ctx context.Context, obj any) (model.TestEndpointRequest, error) {
var it model.TestEndpointRequest
- asMap := map[string]interface{}{}
- for k, v := range obj.(map[string]interface{}) {
+ asMap := map[string]any{}
+ for k, v := range obj.(map[string]any) {
asMap[k] = v
}
@@ -18215,10 +18683,10 @@ func (ec *executionContext) unmarshalInputTestEndpointRequest(ctx context.Contex
return it, nil
}
-func (ec *executionContext) unmarshalInputUpdateAccessInput(ctx context.Context, obj interface{}) (model.UpdateAccessInput, error) {
- var it model.UpdateAccessInput
- asMap := map[string]interface{}{}
- for k, v := range obj.(map[string]interface{}) {
+func (ec *executionContext) unmarshalInputUpdateAccessRequest(ctx context.Context, obj any) (model.UpdateAccessRequest, error) {
+ var it model.UpdateAccessRequest
+ asMap := map[string]any{}
+ for k, v := range obj.(map[string]any) {
asMap[k] = v
}
@@ -18242,10 +18710,10 @@ func (ec *executionContext) unmarshalInputUpdateAccessInput(ctx context.Context,
return it, nil
}
-func (ec *executionContext) unmarshalInputUpdateEmailTemplateRequest(ctx context.Context, obj interface{}) (model.UpdateEmailTemplateRequest, error) {
+func (ec *executionContext) unmarshalInputUpdateEmailTemplateRequest(ctx context.Context, obj any) (model.UpdateEmailTemplateRequest, error) {
var it model.UpdateEmailTemplateRequest
- asMap := map[string]interface{}{}
- for k, v := range obj.(map[string]interface{}) {
+ asMap := map[string]any{}
+ for k, v := range obj.(map[string]any) {
asMap[k] = v
}
@@ -18297,10 +18765,10 @@ func (ec *executionContext) unmarshalInputUpdateEmailTemplateRequest(ctx context
return it, nil
}
-func (ec *executionContext) unmarshalInputUpdateEnvInput(ctx context.Context, obj interface{}) (model.UpdateEnvInput, error) {
- var it model.UpdateEnvInput
- asMap := map[string]interface{}{}
- for k, v := range obj.(map[string]interface{}) {
+func (ec *executionContext) unmarshalInputUpdateEnvRequest(ctx context.Context, obj any) (model.UpdateEnvRequest, error) {
+ var it model.UpdateEnvRequest
+ asMap := map[string]any{}
+ for k, v := range obj.(map[string]any) {
asMap[k] = v
}
@@ -18751,10 +19219,10 @@ func (ec *executionContext) unmarshalInputUpdateEnvInput(ctx context.Context, ob
return it, nil
}
-func (ec *executionContext) unmarshalInputUpdateProfileInput(ctx context.Context, obj interface{}) (model.UpdateProfileInput, error) {
- var it model.UpdateProfileInput
- asMap := map[string]interface{}{}
- for k, v := range obj.(map[string]interface{}) {
+func (ec *executionContext) unmarshalInputUpdateProfileRequest(ctx context.Context, obj any) (model.UpdateProfileRequest, error) {
+ var it model.UpdateProfileRequest
+ asMap := map[string]any{}
+ for k, v := range obj.(map[string]any) {
asMap[k] = v
}
@@ -18869,10 +19337,10 @@ func (ec *executionContext) unmarshalInputUpdateProfileInput(ctx context.Context
return it, nil
}
-func (ec *executionContext) unmarshalInputUpdateUserInput(ctx context.Context, obj interface{}) (model.UpdateUserInput, error) {
- var it model.UpdateUserInput
- asMap := map[string]interface{}{}
- for k, v := range obj.(map[string]interface{}) {
+func (ec *executionContext) unmarshalInputUpdateUserRequest(ctx context.Context, obj any) (model.UpdateUserRequest, error) {
+ var it model.UpdateUserRequest
+ asMap := map[string]any{}
+ for k, v := range obj.(map[string]any) {
asMap[k] = v
}
@@ -18994,10 +19462,10 @@ func (ec *executionContext) unmarshalInputUpdateUserInput(ctx context.Context, o
return it, nil
}
-func (ec *executionContext) unmarshalInputUpdateWebhookRequest(ctx context.Context, obj interface{}) (model.UpdateWebhookRequest, error) {
+func (ec *executionContext) unmarshalInputUpdateWebhookRequest(ctx context.Context, obj any) (model.UpdateWebhookRequest, error) {
var it model.UpdateWebhookRequest
- asMap := map[string]interface{}{}
- for k, v := range obj.(map[string]interface{}) {
+ asMap := map[string]any{}
+ for k, v := range obj.(map[string]any) {
asMap[k] = v
}
@@ -19056,10 +19524,10 @@ func (ec *executionContext) unmarshalInputUpdateWebhookRequest(ctx context.Conte
return it, nil
}
-func (ec *executionContext) unmarshalInputValidateJWTTokenInput(ctx context.Context, obj interface{}) (model.ValidateJWTTokenInput, error) {
- var it model.ValidateJWTTokenInput
- asMap := map[string]interface{}{}
- for k, v := range obj.(map[string]interface{}) {
+func (ec *executionContext) unmarshalInputValidateJWTTokenRequest(ctx context.Context, obj any) (model.ValidateJWTTokenRequest, error) {
+ var it model.ValidateJWTTokenRequest
+ asMap := map[string]any{}
+ for k, v := range obj.(map[string]any) {
asMap[k] = v
}
@@ -19097,10 +19565,10 @@ func (ec *executionContext) unmarshalInputValidateJWTTokenInput(ctx context.Cont
return it, nil
}
-func (ec *executionContext) unmarshalInputValidateSessionInput(ctx context.Context, obj interface{}) (model.ValidateSessionInput, error) {
- var it model.ValidateSessionInput
- asMap := map[string]interface{}{}
- for k, v := range obj.(map[string]interface{}) {
+func (ec *executionContext) unmarshalInputValidateSessionRequest(ctx context.Context, obj any) (model.ValidateSessionRequest, error) {
+ var it model.ValidateSessionRequest
+ asMap := map[string]any{}
+ for k, v := range obj.(map[string]any) {
asMap[k] = v
}
@@ -19131,10 +19599,10 @@ func (ec *executionContext) unmarshalInputValidateSessionInput(ctx context.Conte
return it, nil
}
-func (ec *executionContext) unmarshalInputVerifyEmailInput(ctx context.Context, obj interface{}) (model.VerifyEmailInput, error) {
- var it model.VerifyEmailInput
- asMap := map[string]interface{}{}
- for k, v := range obj.(map[string]interface{}) {
+func (ec *executionContext) unmarshalInputVerifyEmailRequest(ctx context.Context, obj any) (model.VerifyEmailRequest, error) {
+ var it model.VerifyEmailRequest
+ asMap := map[string]any{}
+ for k, v := range obj.(map[string]any) {
asMap[k] = v
}
@@ -19165,10 +19633,10 @@ func (ec *executionContext) unmarshalInputVerifyEmailInput(ctx context.Context,
return it, nil
}
-func (ec *executionContext) unmarshalInputVerifyOTPRequest(ctx context.Context, obj interface{}) (model.VerifyOTPRequest, error) {
+func (ec *executionContext) unmarshalInputVerifyOTPRequest(ctx context.Context, obj any) (model.VerifyOTPRequest, error) {
var it model.VerifyOTPRequest
- asMap := map[string]interface{}{}
- for k, v := range obj.(map[string]interface{}) {
+ asMap := map[string]any{}
+ for k, v := range obj.(map[string]any) {
asMap[k] = v
}
@@ -19220,10 +19688,10 @@ func (ec *executionContext) unmarshalInputVerifyOTPRequest(ctx context.Context,
return it, nil
}
-func (ec *executionContext) unmarshalInputWebhookRequest(ctx context.Context, obj interface{}) (model.WebhookRequest, error) {
+func (ec *executionContext) unmarshalInputWebhookRequest(ctx context.Context, obj any) (model.WebhookRequest, error) {
var it model.WebhookRequest
- asMap := map[string]interface{}{}
- for k, v := range obj.(map[string]interface{}) {
+ asMap := map[string]any{}
+ for k, v := range obj.(map[string]any) {
asMap[k] = v
}
@@ -20670,67 +21138,6 @@ func (ec *executionContext) _Response(ctx context.Context, sel ast.SelectionSet,
return out
}
-var sMSVerificationRequestsImplementors = []string{"SMSVerificationRequests"}
-
-func (ec *executionContext) _SMSVerificationRequests(ctx context.Context, sel ast.SelectionSet, obj *model.SMSVerificationRequests) graphql.Marshaler {
- fields := graphql.CollectFields(ec.OperationContext, sel, sMSVerificationRequestsImplementors)
-
- out := graphql.NewFieldSet(fields)
- deferred := make(map[string]*graphql.FieldSet)
- for i, field := range fields {
- switch field.Name {
- case "__typename":
- out.Values[i] = graphql.MarshalString("SMSVerificationRequests")
- case "id":
- out.Values[i] = ec._SMSVerificationRequests_id(ctx, field, obj)
- if out.Values[i] == graphql.Null {
- out.Invalids++
- }
- case "code":
- out.Values[i] = ec._SMSVerificationRequests_code(ctx, field, obj)
- if out.Values[i] == graphql.Null {
- out.Invalids++
- }
- case "code_expires_at":
- out.Values[i] = ec._SMSVerificationRequests_code_expires_at(ctx, field, obj)
- if out.Values[i] == graphql.Null {
- out.Invalids++
- }
- case "phone_number":
- out.Values[i] = ec._SMSVerificationRequests_phone_number(ctx, field, obj)
- if out.Values[i] == graphql.Null {
- out.Invalids++
- }
- case "created_at":
- out.Values[i] = ec._SMSVerificationRequests_created_at(ctx, field, obj)
- if out.Values[i] == graphql.Null {
- out.Invalids++
- }
- case "updated_at":
- out.Values[i] = ec._SMSVerificationRequests_updated_at(ctx, field, obj)
- default:
- panic("unknown field " + strconv.Quote(field.Name))
- }
- }
- out.Dispatch(ctx)
- if out.Invalids > 0 {
- return graphql.Null
- }
-
- atomic.AddInt32(&ec.deferred, int32(len(deferred)))
-
- for label, dfs := range deferred {
- ec.processDeferredGroup(graphql.DeferredGroup{
- Label: label,
- Path: graphql.GetPath(ctx),
- FieldSet: dfs,
- Context: ctx,
- })
- }
-
- return out
-}
-
var testEndpointResponseImplementors = []string{"TestEndpointResponse"}
func (ec *executionContext) _TestEndpointResponse(ctx context.Context, sel ast.SelectionSet, obj *model.TestEndpointResponse) graphql.Marshaler {
@@ -20815,6 +21222,9 @@ func (ec *executionContext) _User(ctx context.Context, sel ast.SelectionSet, obj
out.Values[i] = ec._User_phone_number(ctx, field, obj)
case "phone_number_verified":
out.Values[i] = ec._User_phone_number_verified(ctx, field, obj)
+ if out.Values[i] == graphql.Null {
+ out.Invalids++
+ }
case "picture":
out.Values[i] = ec._User_picture(ctx, field, obj)
case "roles":
@@ -21293,6 +21703,11 @@ func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionS
}
case "description":
out.Values[i] = ec.___Directive_description(ctx, field, obj)
+ case "isRepeatable":
+ out.Values[i] = ec.___Directive_isRepeatable(ctx, field, obj)
+ if out.Values[i] == graphql.Null {
+ out.Invalids++
+ }
case "locations":
out.Values[i] = ec.___Directive_locations(ctx, field, obj)
if out.Values[i] == graphql.Null {
@@ -21303,11 +21718,6 @@ func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionS
if out.Values[i] == graphql.Null {
out.Invalids++
}
- case "isRepeatable":
- out.Values[i] = ec.___Directive_isRepeatable(ctx, field, obj)
- if out.Values[i] == graphql.Null {
- out.Invalids++
- }
default:
panic("unknown field " + strconv.Quote(field.Name))
}
@@ -21462,6 +21872,13 @@ func (ec *executionContext) ___InputValue(ctx context.Context, sel ast.Selection
}
case "defaultValue":
out.Values[i] = ec.___InputValue_defaultValue(ctx, field, obj)
+ case "isDeprecated":
+ out.Values[i] = ec.___InputValue_isDeprecated(ctx, field, obj)
+ if out.Values[i] == graphql.Null {
+ out.Invalids++
+ }
+ case "deprecationReason":
+ out.Values[i] = ec.___InputValue_deprecationReason(ctx, field, obj)
default:
panic("unknown field " + strconv.Quote(field.Name))
}
@@ -21560,6 +21977,8 @@ func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, o
out.Values[i] = ec.___Type_name(ctx, field, obj)
case "description":
out.Values[i] = ec.___Type_description(ctx, field, obj)
+ case "specifiedByURL":
+ out.Values[i] = ec.___Type_specifiedByURL(ctx, field, obj)
case "fields":
out.Values[i] = ec.___Type_fields(ctx, field, obj)
case "interfaces":
@@ -21572,8 +21991,8 @@ func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, o
out.Values[i] = ec.___Type_inputFields(ctx, field, obj)
case "ofType":
out.Values[i] = ec.___Type_ofType(ctx, field, obj)
- case "specifiedByURL":
- out.Values[i] = ec.___Type_specifiedByURL(ctx, field, obj)
+ case "isOneOf":
+ out.Values[i] = ec.___Type_isOneOf(ctx, field, obj)
default:
panic("unknown field " + strconv.Quote(field.Name))
}
@@ -21601,31 +22020,31 @@ func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, o
// region ***************************** type.gotpl *****************************
-func (ec *executionContext) unmarshalNAddEmailTemplateRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐAddEmailTemplateRequest(ctx context.Context, v interface{}) (model.AddEmailTemplateRequest, error) {
+func (ec *executionContext) unmarshalNAddEmailTemplateRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐAddEmailTemplateRequest(ctx context.Context, v any) (model.AddEmailTemplateRequest, error) {
res, err := ec.unmarshalInputAddEmailTemplateRequest(ctx, v)
return res, graphql.ErrorOnPath(ctx, err)
}
-func (ec *executionContext) unmarshalNAddWebhookRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐAddWebhookRequest(ctx context.Context, v interface{}) (model.AddWebhookRequest, error) {
+func (ec *executionContext) unmarshalNAddWebhookRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐAddWebhookRequest(ctx context.Context, v any) (model.AddWebhookRequest, error) {
res, err := ec.unmarshalInputAddWebhookRequest(ctx, v)
return res, graphql.ErrorOnPath(ctx, err)
}
-func (ec *executionContext) unmarshalNAdminLoginInput2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐAdminLoginInput(ctx context.Context, v interface{}) (model.AdminLoginInput, error) {
- res, err := ec.unmarshalInputAdminLoginInput(ctx, v)
+func (ec *executionContext) unmarshalNAdminLoginRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐAdminLoginRequest(ctx context.Context, v any) (model.AdminLoginRequest, error) {
+ res, err := ec.unmarshalInputAdminLoginRequest(ctx, v)
return res, graphql.ErrorOnPath(ctx, err)
}
-func (ec *executionContext) unmarshalNAdminSignupInput2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐAdminSignupInput(ctx context.Context, v interface{}) (model.AdminSignupInput, error) {
- res, err := ec.unmarshalInputAdminSignupInput(ctx, v)
+func (ec *executionContext) unmarshalNAdminSignupRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐAdminSignupRequest(ctx context.Context, v any) (model.AdminSignupRequest, error) {
+ res, err := ec.unmarshalInputAdminSignupRequest(ctx, v)
return res, graphql.ErrorOnPath(ctx, err)
}
-func (ec *executionContext) marshalNAuthResponse2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐAuthResponse(ctx context.Context, sel ast.SelectionSet, v model.AuthResponse) graphql.Marshaler {
+func (ec *executionContext) marshalNAuthResponse2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐAuthResponse(ctx context.Context, sel ast.SelectionSet, v model.AuthResponse) graphql.Marshaler {
return ec._AuthResponse(ctx, sel, &v)
}
-func (ec *executionContext) marshalNAuthResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐAuthResponse(ctx context.Context, sel ast.SelectionSet, v *model.AuthResponse) graphql.Marshaler {
+func (ec *executionContext) marshalNAuthResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐAuthResponse(ctx context.Context, sel ast.SelectionSet, v *model.AuthResponse) graphql.Marshaler {
if v == nil {
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
ec.Errorf(ctx, "the requested element is null which the schema does not allow")
@@ -21635,12 +22054,13 @@ func (ec *executionContext) marshalNAuthResponse2ᚖgithubᚗcomᚋauthorizerdev
return ec._AuthResponse(ctx, sel, v)
}
-func (ec *executionContext) unmarshalNBoolean2bool(ctx context.Context, v interface{}) (bool, error) {
+func (ec *executionContext) unmarshalNBoolean2bool(ctx context.Context, v any) (bool, error) {
res, err := graphql.UnmarshalBoolean(v)
return res, graphql.ErrorOnPath(ctx, err)
}
func (ec *executionContext) marshalNBoolean2bool(ctx context.Context, sel ast.SelectionSet, v bool) graphql.Marshaler {
+ _ = sel
res := graphql.MarshalBoolean(v)
if res == graphql.Null {
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
@@ -21650,17 +22070,17 @@ func (ec *executionContext) marshalNBoolean2bool(ctx context.Context, sel ast.Se
return res
}
-func (ec *executionContext) unmarshalNDeleteEmailTemplateRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐDeleteEmailTemplateRequest(ctx context.Context, v interface{}) (model.DeleteEmailTemplateRequest, error) {
+func (ec *executionContext) unmarshalNDeleteEmailTemplateRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐDeleteEmailTemplateRequest(ctx context.Context, v any) (model.DeleteEmailTemplateRequest, error) {
res, err := ec.unmarshalInputDeleteEmailTemplateRequest(ctx, v)
return res, graphql.ErrorOnPath(ctx, err)
}
-func (ec *executionContext) unmarshalNDeleteUserInput2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐDeleteUserInput(ctx context.Context, v interface{}) (model.DeleteUserInput, error) {
- res, err := ec.unmarshalInputDeleteUserInput(ctx, v)
+func (ec *executionContext) unmarshalNDeleteUserRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐDeleteUserRequest(ctx context.Context, v any) (model.DeleteUserRequest, error) {
+ res, err := ec.unmarshalInputDeleteUserRequest(ctx, v)
return res, graphql.ErrorOnPath(ctx, err)
}
-func (ec *executionContext) marshalNEmailTemplate2ᚕᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐEmailTemplateᚄ(ctx context.Context, sel ast.SelectionSet, v []*model.EmailTemplate) graphql.Marshaler {
+func (ec *executionContext) marshalNEmailTemplate2ᚕᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐEmailTemplateᚄ(ctx context.Context, sel ast.SelectionSet, v []*model.EmailTemplate) graphql.Marshaler {
ret := make(graphql.Array, len(v))
var wg sync.WaitGroup
isLen1 := len(v) == 1
@@ -21684,7 +22104,7 @@ func (ec *executionContext) marshalNEmailTemplate2ᚕᚖgithubᚗcomᚋauthorize
if !isLen1 {
defer wg.Done()
}
- ret[i] = ec.marshalNEmailTemplate2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐEmailTemplate(ctx, sel, v[i])
+ ret[i] = ec.marshalNEmailTemplate2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐEmailTemplate(ctx, sel, v[i])
}
if isLen1 {
f(i)
@@ -21704,7 +22124,7 @@ func (ec *executionContext) marshalNEmailTemplate2ᚕᚖgithubᚗcomᚋauthorize
return ret
}
-func (ec *executionContext) marshalNEmailTemplate2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐEmailTemplate(ctx context.Context, sel ast.SelectionSet, v *model.EmailTemplate) graphql.Marshaler {
+func (ec *executionContext) marshalNEmailTemplate2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐEmailTemplate(ctx context.Context, sel ast.SelectionSet, v *model.EmailTemplate) graphql.Marshaler {
if v == nil {
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
ec.Errorf(ctx, "the requested element is null which the schema does not allow")
@@ -21714,11 +22134,11 @@ func (ec *executionContext) marshalNEmailTemplate2ᚖgithubᚗcomᚋauthorizerde
return ec._EmailTemplate(ctx, sel, v)
}
-func (ec *executionContext) marshalNEmailTemplates2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐEmailTemplates(ctx context.Context, sel ast.SelectionSet, v model.EmailTemplates) graphql.Marshaler {
+func (ec *executionContext) marshalNEmailTemplates2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐEmailTemplates(ctx context.Context, sel ast.SelectionSet, v model.EmailTemplates) graphql.Marshaler {
return ec._EmailTemplates(ctx, sel, &v)
}
-func (ec *executionContext) marshalNEmailTemplates2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐEmailTemplates(ctx context.Context, sel ast.SelectionSet, v *model.EmailTemplates) graphql.Marshaler {
+func (ec *executionContext) marshalNEmailTemplates2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐEmailTemplates(ctx context.Context, sel ast.SelectionSet, v *model.EmailTemplates) graphql.Marshaler {
if v == nil {
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
ec.Errorf(ctx, "the requested element is null which the schema does not allow")
@@ -21728,11 +22148,11 @@ func (ec *executionContext) marshalNEmailTemplates2ᚖgithubᚗcomᚋauthorizerd
return ec._EmailTemplates(ctx, sel, v)
}
-func (ec *executionContext) marshalNEnv2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐEnv(ctx context.Context, sel ast.SelectionSet, v model.Env) graphql.Marshaler {
+func (ec *executionContext) marshalNEnv2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐEnv(ctx context.Context, sel ast.SelectionSet, v model.Env) graphql.Marshaler {
return ec._Env(ctx, sel, &v)
}
-func (ec *executionContext) marshalNEnv2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐEnv(ctx context.Context, sel ast.SelectionSet, v *model.Env) graphql.Marshaler {
+func (ec *executionContext) marshalNEnv2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐEnv(ctx context.Context, sel ast.SelectionSet, v *model.Env) graphql.Marshaler {
if v == nil {
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
ec.Errorf(ctx, "the requested element is null which the schema does not allow")
@@ -21742,16 +22162,16 @@ func (ec *executionContext) marshalNEnv2ᚖgithubᚗcomᚋauthorizerdevᚋauthor
return ec._Env(ctx, sel, v)
}
-func (ec *executionContext) unmarshalNForgotPasswordInput2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐForgotPasswordInput(ctx context.Context, v interface{}) (model.ForgotPasswordInput, error) {
- res, err := ec.unmarshalInputForgotPasswordInput(ctx, v)
+func (ec *executionContext) unmarshalNForgotPasswordRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐForgotPasswordRequest(ctx context.Context, v any) (model.ForgotPasswordRequest, error) {
+ res, err := ec.unmarshalInputForgotPasswordRequest(ctx, v)
return res, graphql.ErrorOnPath(ctx, err)
}
-func (ec *executionContext) marshalNForgotPasswordResponse2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐForgotPasswordResponse(ctx context.Context, sel ast.SelectionSet, v model.ForgotPasswordResponse) graphql.Marshaler {
+func (ec *executionContext) marshalNForgotPasswordResponse2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐForgotPasswordResponse(ctx context.Context, sel ast.SelectionSet, v model.ForgotPasswordResponse) graphql.Marshaler {
return ec._ForgotPasswordResponse(ctx, sel, &v)
}
-func (ec *executionContext) marshalNForgotPasswordResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐForgotPasswordResponse(ctx context.Context, sel ast.SelectionSet, v *model.ForgotPasswordResponse) graphql.Marshaler {
+func (ec *executionContext) marshalNForgotPasswordResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐForgotPasswordResponse(ctx context.Context, sel ast.SelectionSet, v *model.ForgotPasswordResponse) graphql.Marshaler {
if v == nil {
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
ec.Errorf(ctx, "the requested element is null which the schema does not allow")
@@ -21761,16 +22181,16 @@ func (ec *executionContext) marshalNForgotPasswordResponse2ᚖgithubᚗcomᚋaut
return ec._ForgotPasswordResponse(ctx, sel, v)
}
-func (ec *executionContext) unmarshalNGenerateJWTKeysInput2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐGenerateJWTKeysInput(ctx context.Context, v interface{}) (model.GenerateJWTKeysInput, error) {
- res, err := ec.unmarshalInputGenerateJWTKeysInput(ctx, v)
+func (ec *executionContext) unmarshalNGenerateJWTKeysRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐGenerateJWTKeysRequest(ctx context.Context, v any) (model.GenerateJWTKeysRequest, error) {
+ res, err := ec.unmarshalInputGenerateJWTKeysRequest(ctx, v)
return res, graphql.ErrorOnPath(ctx, err)
}
-func (ec *executionContext) marshalNGenerateJWTKeysResponse2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐGenerateJWTKeysResponse(ctx context.Context, sel ast.SelectionSet, v model.GenerateJWTKeysResponse) graphql.Marshaler {
+func (ec *executionContext) marshalNGenerateJWTKeysResponse2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐGenerateJWTKeysResponse(ctx context.Context, sel ast.SelectionSet, v model.GenerateJWTKeysResponse) graphql.Marshaler {
return ec._GenerateJWTKeysResponse(ctx, sel, &v)
}
-func (ec *executionContext) marshalNGenerateJWTKeysResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐGenerateJWTKeysResponse(ctx context.Context, sel ast.SelectionSet, v *model.GenerateJWTKeysResponse) graphql.Marshaler {
+func (ec *executionContext) marshalNGenerateJWTKeysResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐGenerateJWTKeysResponse(ctx context.Context, sel ast.SelectionSet, v *model.GenerateJWTKeysResponse) graphql.Marshaler {
if v == nil {
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
ec.Errorf(ctx, "the requested element is null which the schema does not allow")
@@ -21780,17 +22200,18 @@ func (ec *executionContext) marshalNGenerateJWTKeysResponse2ᚖgithubᚗcomᚋau
return ec._GenerateJWTKeysResponse(ctx, sel, v)
}
-func (ec *executionContext) unmarshalNGetUserRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐGetUserRequest(ctx context.Context, v interface{}) (model.GetUserRequest, error) {
+func (ec *executionContext) unmarshalNGetUserRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐGetUserRequest(ctx context.Context, v any) (model.GetUserRequest, error) {
res, err := ec.unmarshalInputGetUserRequest(ctx, v)
return res, graphql.ErrorOnPath(ctx, err)
}
-func (ec *executionContext) unmarshalNID2string(ctx context.Context, v interface{}) (string, error) {
+func (ec *executionContext) unmarshalNID2string(ctx context.Context, v any) (string, error) {
res, err := graphql.UnmarshalID(v)
return res, graphql.ErrorOnPath(ctx, err)
}
func (ec *executionContext) marshalNID2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler {
+ _ = sel
res := graphql.MarshalID(v)
if res == graphql.Null {
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
@@ -21800,12 +22221,13 @@ func (ec *executionContext) marshalNID2string(ctx context.Context, sel ast.Selec
return res
}
-func (ec *executionContext) unmarshalNInt642int64(ctx context.Context, v interface{}) (int64, error) {
+func (ec *executionContext) unmarshalNInt642int64(ctx context.Context, v any) (int64, error) {
res, err := graphql.UnmarshalInt64(v)
return res, graphql.ErrorOnPath(ctx, err)
}
func (ec *executionContext) marshalNInt642int64(ctx context.Context, sel ast.SelectionSet, v int64) graphql.Marshaler {
+ _ = sel
res := graphql.MarshalInt64(v)
if res == graphql.Null {
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
@@ -21815,16 +22237,16 @@ func (ec *executionContext) marshalNInt642int64(ctx context.Context, sel ast.Sel
return res
}
-func (ec *executionContext) unmarshalNInviteMemberInput2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐInviteMemberInput(ctx context.Context, v interface{}) (model.InviteMemberInput, error) {
- res, err := ec.unmarshalInputInviteMemberInput(ctx, v)
+func (ec *executionContext) unmarshalNInviteMemberRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐInviteMemberRequest(ctx context.Context, v any) (model.InviteMemberRequest, error) {
+ res, err := ec.unmarshalInputInviteMemberRequest(ctx, v)
return res, graphql.ErrorOnPath(ctx, err)
}
-func (ec *executionContext) marshalNInviteMembersResponse2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐInviteMembersResponse(ctx context.Context, sel ast.SelectionSet, v model.InviteMembersResponse) graphql.Marshaler {
+func (ec *executionContext) marshalNInviteMembersResponse2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐInviteMembersResponse(ctx context.Context, sel ast.SelectionSet, v model.InviteMembersResponse) graphql.Marshaler {
return ec._InviteMembersResponse(ctx, sel, &v)
}
-func (ec *executionContext) marshalNInviteMembersResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐInviteMembersResponse(ctx context.Context, sel ast.SelectionSet, v *model.InviteMembersResponse) graphql.Marshaler {
+func (ec *executionContext) marshalNInviteMembersResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐInviteMembersResponse(ctx context.Context, sel ast.SelectionSet, v *model.InviteMembersResponse) graphql.Marshaler {
if v == nil {
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
ec.Errorf(ctx, "the requested element is null which the schema does not allow")
@@ -21834,21 +22256,21 @@ func (ec *executionContext) marshalNInviteMembersResponse2ᚖgithubᚗcomᚋauth
return ec._InviteMembersResponse(ctx, sel, v)
}
-func (ec *executionContext) unmarshalNLoginInput2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐLoginInput(ctx context.Context, v interface{}) (model.LoginInput, error) {
- res, err := ec.unmarshalInputLoginInput(ctx, v)
+func (ec *executionContext) unmarshalNLoginRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐLoginRequest(ctx context.Context, v any) (model.LoginRequest, error) {
+ res, err := ec.unmarshalInputLoginRequest(ctx, v)
return res, graphql.ErrorOnPath(ctx, err)
}
-func (ec *executionContext) unmarshalNMagicLinkLoginInput2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐMagicLinkLoginInput(ctx context.Context, v interface{}) (model.MagicLinkLoginInput, error) {
- res, err := ec.unmarshalInputMagicLinkLoginInput(ctx, v)
+func (ec *executionContext) unmarshalNMagicLinkLoginRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐMagicLinkLoginRequest(ctx context.Context, v any) (model.MagicLinkLoginRequest, error) {
+ res, err := ec.unmarshalInputMagicLinkLoginRequest(ctx, v)
return res, graphql.ErrorOnPath(ctx, err)
}
-func (ec *executionContext) marshalNMeta2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐMeta(ctx context.Context, sel ast.SelectionSet, v model.Meta) graphql.Marshaler {
+func (ec *executionContext) marshalNMeta2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐMeta(ctx context.Context, sel ast.SelectionSet, v model.Meta) graphql.Marshaler {
return ec._Meta(ctx, sel, &v)
}
-func (ec *executionContext) marshalNMeta2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐMeta(ctx context.Context, sel ast.SelectionSet, v *model.Meta) graphql.Marshaler {
+func (ec *executionContext) marshalNMeta2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐMeta(ctx context.Context, sel ast.SelectionSet, v *model.Meta) graphql.Marshaler {
if v == nil {
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
ec.Errorf(ctx, "the requested element is null which the schema does not allow")
@@ -21858,17 +22280,17 @@ func (ec *executionContext) marshalNMeta2ᚖgithubᚗcomᚋauthorizerdevᚋautho
return ec._Meta(ctx, sel, v)
}
-func (ec *executionContext) unmarshalNMobileLoginInput2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐMobileLoginInput(ctx context.Context, v interface{}) (model.MobileLoginInput, error) {
- res, err := ec.unmarshalInputMobileLoginInput(ctx, v)
+func (ec *executionContext) unmarshalNMobileLoginRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐMobileLoginRequest(ctx context.Context, v any) (model.MobileLoginRequest, error) {
+ res, err := ec.unmarshalInputMobileLoginRequest(ctx, v)
return res, graphql.ErrorOnPath(ctx, err)
}
-func (ec *executionContext) unmarshalNOAuthRevokeInput2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐOAuthRevokeInput(ctx context.Context, v interface{}) (model.OAuthRevokeInput, error) {
- res, err := ec.unmarshalInputOAuthRevokeInput(ctx, v)
+func (ec *executionContext) unmarshalNOAuthRevokeRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐOAuthRevokeRequest(ctx context.Context, v any) (model.OAuthRevokeRequest, error) {
+ res, err := ec.unmarshalInputOAuthRevokeRequest(ctx, v)
return res, graphql.ErrorOnPath(ctx, err)
}
-func (ec *executionContext) marshalNPagination2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐPagination(ctx context.Context, sel ast.SelectionSet, v *model.Pagination) graphql.Marshaler {
+func (ec *executionContext) marshalNPagination2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐPagination(ctx context.Context, sel ast.SelectionSet, v *model.Pagination) graphql.Marshaler {
if v == nil {
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
ec.Errorf(ctx, "the requested element is null which the schema does not allow")
@@ -21878,26 +22300,26 @@ func (ec *executionContext) marshalNPagination2ᚖgithubᚗcomᚋauthorizerdev
return ec._Pagination(ctx, sel, v)
}
-func (ec *executionContext) unmarshalNResendOTPRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐResendOTPRequest(ctx context.Context, v interface{}) (model.ResendOTPRequest, error) {
+func (ec *executionContext) unmarshalNResendOTPRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐResendOTPRequest(ctx context.Context, v any) (model.ResendOTPRequest, error) {
res, err := ec.unmarshalInputResendOTPRequest(ctx, v)
return res, graphql.ErrorOnPath(ctx, err)
}
-func (ec *executionContext) unmarshalNResendVerifyEmailInput2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐResendVerifyEmailInput(ctx context.Context, v interface{}) (model.ResendVerifyEmailInput, error) {
- res, err := ec.unmarshalInputResendVerifyEmailInput(ctx, v)
+func (ec *executionContext) unmarshalNResendVerifyEmailRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐResendVerifyEmailRequest(ctx context.Context, v any) (model.ResendVerifyEmailRequest, error) {
+ res, err := ec.unmarshalInputResendVerifyEmailRequest(ctx, v)
return res, graphql.ErrorOnPath(ctx, err)
}
-func (ec *executionContext) unmarshalNResetPasswordInput2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐResetPasswordInput(ctx context.Context, v interface{}) (model.ResetPasswordInput, error) {
- res, err := ec.unmarshalInputResetPasswordInput(ctx, v)
+func (ec *executionContext) unmarshalNResetPasswordRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐResetPasswordRequest(ctx context.Context, v any) (model.ResetPasswordRequest, error) {
+ res, err := ec.unmarshalInputResetPasswordRequest(ctx, v)
return res, graphql.ErrorOnPath(ctx, err)
}
-func (ec *executionContext) marshalNResponse2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐResponse(ctx context.Context, sel ast.SelectionSet, v model.Response) graphql.Marshaler {
+func (ec *executionContext) marshalNResponse2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐResponse(ctx context.Context, sel ast.SelectionSet, v model.Response) graphql.Marshaler {
return ec._Response(ctx, sel, &v)
}
-func (ec *executionContext) marshalNResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐResponse(ctx context.Context, sel ast.SelectionSet, v *model.Response) graphql.Marshaler {
+func (ec *executionContext) marshalNResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐResponse(ctx context.Context, sel ast.SelectionSet, v *model.Response) graphql.Marshaler {
if v == nil {
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
ec.Errorf(ctx, "the requested element is null which the schema does not allow")
@@ -21907,17 +22329,18 @@ func (ec *executionContext) marshalNResponse2ᚖgithubᚗcomᚋauthorizerdevᚋa
return ec._Response(ctx, sel, v)
}
-func (ec *executionContext) unmarshalNSignUpInput2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐSignUpInput(ctx context.Context, v interface{}) (model.SignUpInput, error) {
- res, err := ec.unmarshalInputSignUpInput(ctx, v)
+func (ec *executionContext) unmarshalNSignUpRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐSignUpRequest(ctx context.Context, v any) (model.SignUpRequest, error) {
+ res, err := ec.unmarshalInputSignUpRequest(ctx, v)
return res, graphql.ErrorOnPath(ctx, err)
}
-func (ec *executionContext) unmarshalNString2string(ctx context.Context, v interface{}) (string, error) {
+func (ec *executionContext) unmarshalNString2string(ctx context.Context, v any) (string, error) {
res, err := graphql.UnmarshalString(v)
return res, graphql.ErrorOnPath(ctx, err)
}
func (ec *executionContext) marshalNString2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler {
+ _ = sel
res := graphql.MarshalString(v)
if res == graphql.Null {
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
@@ -21927,11 +22350,9 @@ func (ec *executionContext) marshalNString2string(ctx context.Context, sel ast.S
return res
}
-func (ec *executionContext) unmarshalNString2ᚕstringᚄ(ctx context.Context, v interface{}) ([]string, error) {
- var vSlice []interface{}
- if v != nil {
- vSlice = graphql.CoerceList(v)
- }
+func (ec *executionContext) unmarshalNString2ᚕstringᚄ(ctx context.Context, v any) ([]string, error) {
+ var vSlice []any
+ vSlice = graphql.CoerceList(v)
var err error
res := make([]string, len(vSlice))
for i := range vSlice {
@@ -21959,16 +22380,16 @@ func (ec *executionContext) marshalNString2ᚕstringᚄ(ctx context.Context, sel
return ret
}
-func (ec *executionContext) unmarshalNTestEndpointRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐTestEndpointRequest(ctx context.Context, v interface{}) (model.TestEndpointRequest, error) {
+func (ec *executionContext) unmarshalNTestEndpointRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐTestEndpointRequest(ctx context.Context, v any) (model.TestEndpointRequest, error) {
res, err := ec.unmarshalInputTestEndpointRequest(ctx, v)
return res, graphql.ErrorOnPath(ctx, err)
}
-func (ec *executionContext) marshalNTestEndpointResponse2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐTestEndpointResponse(ctx context.Context, sel ast.SelectionSet, v model.TestEndpointResponse) graphql.Marshaler {
+func (ec *executionContext) marshalNTestEndpointResponse2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐTestEndpointResponse(ctx context.Context, sel ast.SelectionSet, v model.TestEndpointResponse) graphql.Marshaler {
return ec._TestEndpointResponse(ctx, sel, &v)
}
-func (ec *executionContext) marshalNTestEndpointResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐTestEndpointResponse(ctx context.Context, sel ast.SelectionSet, v *model.TestEndpointResponse) graphql.Marshaler {
+func (ec *executionContext) marshalNTestEndpointResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐTestEndpointResponse(ctx context.Context, sel ast.SelectionSet, v *model.TestEndpointResponse) graphql.Marshaler {
if v == nil {
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
ec.Errorf(ctx, "the requested element is null which the schema does not allow")
@@ -21978,41 +22399,41 @@ func (ec *executionContext) marshalNTestEndpointResponse2ᚖgithubᚗcomᚋautho
return ec._TestEndpointResponse(ctx, sel, v)
}
-func (ec *executionContext) unmarshalNUpdateAccessInput2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐUpdateAccessInput(ctx context.Context, v interface{}) (model.UpdateAccessInput, error) {
- res, err := ec.unmarshalInputUpdateAccessInput(ctx, v)
+func (ec *executionContext) unmarshalNUpdateAccessRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐUpdateAccessRequest(ctx context.Context, v any) (model.UpdateAccessRequest, error) {
+ res, err := ec.unmarshalInputUpdateAccessRequest(ctx, v)
return res, graphql.ErrorOnPath(ctx, err)
}
-func (ec *executionContext) unmarshalNUpdateEmailTemplateRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐUpdateEmailTemplateRequest(ctx context.Context, v interface{}) (model.UpdateEmailTemplateRequest, error) {
+func (ec *executionContext) unmarshalNUpdateEmailTemplateRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐUpdateEmailTemplateRequest(ctx context.Context, v any) (model.UpdateEmailTemplateRequest, error) {
res, err := ec.unmarshalInputUpdateEmailTemplateRequest(ctx, v)
return res, graphql.ErrorOnPath(ctx, err)
}
-func (ec *executionContext) unmarshalNUpdateEnvInput2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐUpdateEnvInput(ctx context.Context, v interface{}) (model.UpdateEnvInput, error) {
- res, err := ec.unmarshalInputUpdateEnvInput(ctx, v)
+func (ec *executionContext) unmarshalNUpdateEnvRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐUpdateEnvRequest(ctx context.Context, v any) (model.UpdateEnvRequest, error) {
+ res, err := ec.unmarshalInputUpdateEnvRequest(ctx, v)
return res, graphql.ErrorOnPath(ctx, err)
}
-func (ec *executionContext) unmarshalNUpdateProfileInput2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐUpdateProfileInput(ctx context.Context, v interface{}) (model.UpdateProfileInput, error) {
- res, err := ec.unmarshalInputUpdateProfileInput(ctx, v)
+func (ec *executionContext) unmarshalNUpdateProfileRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐUpdateProfileRequest(ctx context.Context, v any) (model.UpdateProfileRequest, error) {
+ res, err := ec.unmarshalInputUpdateProfileRequest(ctx, v)
return res, graphql.ErrorOnPath(ctx, err)
}
-func (ec *executionContext) unmarshalNUpdateUserInput2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐUpdateUserInput(ctx context.Context, v interface{}) (model.UpdateUserInput, error) {
- res, err := ec.unmarshalInputUpdateUserInput(ctx, v)
+func (ec *executionContext) unmarshalNUpdateUserRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐUpdateUserRequest(ctx context.Context, v any) (model.UpdateUserRequest, error) {
+ res, err := ec.unmarshalInputUpdateUserRequest(ctx, v)
return res, graphql.ErrorOnPath(ctx, err)
}
-func (ec *executionContext) unmarshalNUpdateWebhookRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐUpdateWebhookRequest(ctx context.Context, v interface{}) (model.UpdateWebhookRequest, error) {
+func (ec *executionContext) unmarshalNUpdateWebhookRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐUpdateWebhookRequest(ctx context.Context, v any) (model.UpdateWebhookRequest, error) {
res, err := ec.unmarshalInputUpdateWebhookRequest(ctx, v)
return res, graphql.ErrorOnPath(ctx, err)
}
-func (ec *executionContext) marshalNUser2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐUser(ctx context.Context, sel ast.SelectionSet, v model.User) graphql.Marshaler {
+func (ec *executionContext) marshalNUser2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐUser(ctx context.Context, sel ast.SelectionSet, v model.User) graphql.Marshaler {
return ec._User(ctx, sel, &v)
}
-func (ec *executionContext) marshalNUser2ᚕᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐUserᚄ(ctx context.Context, sel ast.SelectionSet, v []*model.User) graphql.Marshaler {
+func (ec *executionContext) marshalNUser2ᚕᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐUserᚄ(ctx context.Context, sel ast.SelectionSet, v []*model.User) graphql.Marshaler {
ret := make(graphql.Array, len(v))
var wg sync.WaitGroup
isLen1 := len(v) == 1
@@ -22036,7 +22457,7 @@ func (ec *executionContext) marshalNUser2ᚕᚖgithubᚗcomᚋauthorizerdevᚋau
if !isLen1 {
defer wg.Done()
}
- ret[i] = ec.marshalNUser2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐUser(ctx, sel, v[i])
+ ret[i] = ec.marshalNUser2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐUser(ctx, sel, v[i])
}
if isLen1 {
f(i)
@@ -22056,7 +22477,7 @@ func (ec *executionContext) marshalNUser2ᚕᚖgithubᚗcomᚋauthorizerdevᚋau
return ret
}
-func (ec *executionContext) marshalNUser2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐUser(ctx context.Context, sel ast.SelectionSet, v *model.User) graphql.Marshaler {
+func (ec *executionContext) marshalNUser2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐUser(ctx context.Context, sel ast.SelectionSet, v *model.User) graphql.Marshaler {
if v == nil {
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
ec.Errorf(ctx, "the requested element is null which the schema does not allow")
@@ -22066,11 +22487,11 @@ func (ec *executionContext) marshalNUser2ᚖgithubᚗcomᚋauthorizerdevᚋautho
return ec._User(ctx, sel, v)
}
-func (ec *executionContext) marshalNUsers2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐUsers(ctx context.Context, sel ast.SelectionSet, v model.Users) graphql.Marshaler {
+func (ec *executionContext) marshalNUsers2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐUsers(ctx context.Context, sel ast.SelectionSet, v model.Users) graphql.Marshaler {
return ec._Users(ctx, sel, &v)
}
-func (ec *executionContext) marshalNUsers2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐUsers(ctx context.Context, sel ast.SelectionSet, v *model.Users) graphql.Marshaler {
+func (ec *executionContext) marshalNUsers2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐUsers(ctx context.Context, sel ast.SelectionSet, v *model.Users) graphql.Marshaler {
if v == nil {
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
ec.Errorf(ctx, "the requested element is null which the schema does not allow")
@@ -22080,16 +22501,16 @@ func (ec *executionContext) marshalNUsers2ᚖgithubᚗcomᚋauthorizerdevᚋauth
return ec._Users(ctx, sel, v)
}
-func (ec *executionContext) unmarshalNValidateJWTTokenInput2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐValidateJWTTokenInput(ctx context.Context, v interface{}) (model.ValidateJWTTokenInput, error) {
- res, err := ec.unmarshalInputValidateJWTTokenInput(ctx, v)
+func (ec *executionContext) unmarshalNValidateJWTTokenRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐValidateJWTTokenRequest(ctx context.Context, v any) (model.ValidateJWTTokenRequest, error) {
+ res, err := ec.unmarshalInputValidateJWTTokenRequest(ctx, v)
return res, graphql.ErrorOnPath(ctx, err)
}
-func (ec *executionContext) marshalNValidateJWTTokenResponse2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐValidateJWTTokenResponse(ctx context.Context, sel ast.SelectionSet, v model.ValidateJWTTokenResponse) graphql.Marshaler {
+func (ec *executionContext) marshalNValidateJWTTokenResponse2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐValidateJWTTokenResponse(ctx context.Context, sel ast.SelectionSet, v model.ValidateJWTTokenResponse) graphql.Marshaler {
return ec._ValidateJWTTokenResponse(ctx, sel, &v)
}
-func (ec *executionContext) marshalNValidateJWTTokenResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐValidateJWTTokenResponse(ctx context.Context, sel ast.SelectionSet, v *model.ValidateJWTTokenResponse) graphql.Marshaler {
+func (ec *executionContext) marshalNValidateJWTTokenResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐValidateJWTTokenResponse(ctx context.Context, sel ast.SelectionSet, v *model.ValidateJWTTokenResponse) graphql.Marshaler {
if v == nil {
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
ec.Errorf(ctx, "the requested element is null which the schema does not allow")
@@ -22099,11 +22520,11 @@ func (ec *executionContext) marshalNValidateJWTTokenResponse2ᚖgithubᚗcomᚋa
return ec._ValidateJWTTokenResponse(ctx, sel, v)
}
-func (ec *executionContext) marshalNValidateSessionResponse2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐValidateSessionResponse(ctx context.Context, sel ast.SelectionSet, v model.ValidateSessionResponse) graphql.Marshaler {
+func (ec *executionContext) marshalNValidateSessionResponse2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐValidateSessionResponse(ctx context.Context, sel ast.SelectionSet, v model.ValidateSessionResponse) graphql.Marshaler {
return ec._ValidateSessionResponse(ctx, sel, &v)
}
-func (ec *executionContext) marshalNValidateSessionResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐValidateSessionResponse(ctx context.Context, sel ast.SelectionSet, v *model.ValidateSessionResponse) graphql.Marshaler {
+func (ec *executionContext) marshalNValidateSessionResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐValidateSessionResponse(ctx context.Context, sel ast.SelectionSet, v *model.ValidateSessionResponse) graphql.Marshaler {
if v == nil {
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
ec.Errorf(ctx, "the requested element is null which the schema does not allow")
@@ -22113,7 +22534,7 @@ func (ec *executionContext) marshalNValidateSessionResponse2ᚖgithubᚗcomᚋau
return ec._ValidateSessionResponse(ctx, sel, v)
}
-func (ec *executionContext) marshalNVerificationRequest2ᚕᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐVerificationRequestᚄ(ctx context.Context, sel ast.SelectionSet, v []*model.VerificationRequest) graphql.Marshaler {
+func (ec *executionContext) marshalNVerificationRequest2ᚕᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐVerificationRequestᚄ(ctx context.Context, sel ast.SelectionSet, v []*model.VerificationRequest) graphql.Marshaler {
ret := make(graphql.Array, len(v))
var wg sync.WaitGroup
isLen1 := len(v) == 1
@@ -22137,7 +22558,7 @@ func (ec *executionContext) marshalNVerificationRequest2ᚕᚖgithubᚗcomᚋaut
if !isLen1 {
defer wg.Done()
}
- ret[i] = ec.marshalNVerificationRequest2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐVerificationRequest(ctx, sel, v[i])
+ ret[i] = ec.marshalNVerificationRequest2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐVerificationRequest(ctx, sel, v[i])
}
if isLen1 {
f(i)
@@ -22157,7 +22578,7 @@ func (ec *executionContext) marshalNVerificationRequest2ᚕᚖgithubᚗcomᚋaut
return ret
}
-func (ec *executionContext) marshalNVerificationRequest2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐVerificationRequest(ctx context.Context, sel ast.SelectionSet, v *model.VerificationRequest) graphql.Marshaler {
+func (ec *executionContext) marshalNVerificationRequest2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐVerificationRequest(ctx context.Context, sel ast.SelectionSet, v *model.VerificationRequest) graphql.Marshaler {
if v == nil {
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
ec.Errorf(ctx, "the requested element is null which the schema does not allow")
@@ -22167,11 +22588,11 @@ func (ec *executionContext) marshalNVerificationRequest2ᚖgithubᚗcomᚋauthor
return ec._VerificationRequest(ctx, sel, v)
}
-func (ec *executionContext) marshalNVerificationRequests2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐVerificationRequests(ctx context.Context, sel ast.SelectionSet, v model.VerificationRequests) graphql.Marshaler {
+func (ec *executionContext) marshalNVerificationRequests2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐVerificationRequests(ctx context.Context, sel ast.SelectionSet, v model.VerificationRequests) graphql.Marshaler {
return ec._VerificationRequests(ctx, sel, &v)
}
-func (ec *executionContext) marshalNVerificationRequests2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐVerificationRequests(ctx context.Context, sel ast.SelectionSet, v *model.VerificationRequests) graphql.Marshaler {
+func (ec *executionContext) marshalNVerificationRequests2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐVerificationRequests(ctx context.Context, sel ast.SelectionSet, v *model.VerificationRequests) graphql.Marshaler {
if v == nil {
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
ec.Errorf(ctx, "the requested element is null which the schema does not allow")
@@ -22181,21 +22602,21 @@ func (ec *executionContext) marshalNVerificationRequests2ᚖgithubᚗcomᚋautho
return ec._VerificationRequests(ctx, sel, v)
}
-func (ec *executionContext) unmarshalNVerifyEmailInput2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐVerifyEmailInput(ctx context.Context, v interface{}) (model.VerifyEmailInput, error) {
- res, err := ec.unmarshalInputVerifyEmailInput(ctx, v)
+func (ec *executionContext) unmarshalNVerifyEmailRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐVerifyEmailRequest(ctx context.Context, v any) (model.VerifyEmailRequest, error) {
+ res, err := ec.unmarshalInputVerifyEmailRequest(ctx, v)
return res, graphql.ErrorOnPath(ctx, err)
}
-func (ec *executionContext) unmarshalNVerifyOTPRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐVerifyOTPRequest(ctx context.Context, v interface{}) (model.VerifyOTPRequest, error) {
+func (ec *executionContext) unmarshalNVerifyOTPRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐVerifyOTPRequest(ctx context.Context, v any) (model.VerifyOTPRequest, error) {
res, err := ec.unmarshalInputVerifyOTPRequest(ctx, v)
return res, graphql.ErrorOnPath(ctx, err)
}
-func (ec *executionContext) marshalNWebhook2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐWebhook(ctx context.Context, sel ast.SelectionSet, v model.Webhook) graphql.Marshaler {
+func (ec *executionContext) marshalNWebhook2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐWebhook(ctx context.Context, sel ast.SelectionSet, v model.Webhook) graphql.Marshaler {
return ec._Webhook(ctx, sel, &v)
}
-func (ec *executionContext) marshalNWebhook2ᚕᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐWebhookᚄ(ctx context.Context, sel ast.SelectionSet, v []*model.Webhook) graphql.Marshaler {
+func (ec *executionContext) marshalNWebhook2ᚕᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐWebhookᚄ(ctx context.Context, sel ast.SelectionSet, v []*model.Webhook) graphql.Marshaler {
ret := make(graphql.Array, len(v))
var wg sync.WaitGroup
isLen1 := len(v) == 1
@@ -22219,7 +22640,7 @@ func (ec *executionContext) marshalNWebhook2ᚕᚖgithubᚗcomᚋauthorizerdev
if !isLen1 {
defer wg.Done()
}
- ret[i] = ec.marshalNWebhook2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐWebhook(ctx, sel, v[i])
+ ret[i] = ec.marshalNWebhook2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐWebhook(ctx, sel, v[i])
}
if isLen1 {
f(i)
@@ -22239,7 +22660,7 @@ func (ec *executionContext) marshalNWebhook2ᚕᚖgithubᚗcomᚋauthorizerdev
return ret
}
-func (ec *executionContext) marshalNWebhook2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐWebhook(ctx context.Context, sel ast.SelectionSet, v *model.Webhook) graphql.Marshaler {
+func (ec *executionContext) marshalNWebhook2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐWebhook(ctx context.Context, sel ast.SelectionSet, v *model.Webhook) graphql.Marshaler {
if v == nil {
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
ec.Errorf(ctx, "the requested element is null which the schema does not allow")
@@ -22249,7 +22670,7 @@ func (ec *executionContext) marshalNWebhook2ᚖgithubᚗcomᚋauthorizerdevᚋau
return ec._Webhook(ctx, sel, v)
}
-func (ec *executionContext) marshalNWebhookLog2ᚕᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐWebhookLogᚄ(ctx context.Context, sel ast.SelectionSet, v []*model.WebhookLog) graphql.Marshaler {
+func (ec *executionContext) marshalNWebhookLog2ᚕᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐWebhookLogᚄ(ctx context.Context, sel ast.SelectionSet, v []*model.WebhookLog) graphql.Marshaler {
ret := make(graphql.Array, len(v))
var wg sync.WaitGroup
isLen1 := len(v) == 1
@@ -22273,7 +22694,7 @@ func (ec *executionContext) marshalNWebhookLog2ᚕᚖgithubᚗcomᚋauthorizerde
if !isLen1 {
defer wg.Done()
}
- ret[i] = ec.marshalNWebhookLog2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐWebhookLog(ctx, sel, v[i])
+ ret[i] = ec.marshalNWebhookLog2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐWebhookLog(ctx, sel, v[i])
}
if isLen1 {
f(i)
@@ -22293,7 +22714,7 @@ func (ec *executionContext) marshalNWebhookLog2ᚕᚖgithubᚗcomᚋauthorizerde
return ret
}
-func (ec *executionContext) marshalNWebhookLog2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐWebhookLog(ctx context.Context, sel ast.SelectionSet, v *model.WebhookLog) graphql.Marshaler {
+func (ec *executionContext) marshalNWebhookLog2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐWebhookLog(ctx context.Context, sel ast.SelectionSet, v *model.WebhookLog) graphql.Marshaler {
if v == nil {
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
ec.Errorf(ctx, "the requested element is null which the schema does not allow")
@@ -22303,11 +22724,11 @@ func (ec *executionContext) marshalNWebhookLog2ᚖgithubᚗcomᚋauthorizerdev
return ec._WebhookLog(ctx, sel, v)
}
-func (ec *executionContext) marshalNWebhookLogs2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐWebhookLogs(ctx context.Context, sel ast.SelectionSet, v model.WebhookLogs) graphql.Marshaler {
+func (ec *executionContext) marshalNWebhookLogs2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐWebhookLogs(ctx context.Context, sel ast.SelectionSet, v model.WebhookLogs) graphql.Marshaler {
return ec._WebhookLogs(ctx, sel, &v)
}
-func (ec *executionContext) marshalNWebhookLogs2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐWebhookLogs(ctx context.Context, sel ast.SelectionSet, v *model.WebhookLogs) graphql.Marshaler {
+func (ec *executionContext) marshalNWebhookLogs2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐWebhookLogs(ctx context.Context, sel ast.SelectionSet, v *model.WebhookLogs) graphql.Marshaler {
if v == nil {
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
ec.Errorf(ctx, "the requested element is null which the schema does not allow")
@@ -22317,16 +22738,16 @@ func (ec *executionContext) marshalNWebhookLogs2ᚖgithubᚗcomᚋauthorizerdev
return ec._WebhookLogs(ctx, sel, v)
}
-func (ec *executionContext) unmarshalNWebhookRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐWebhookRequest(ctx context.Context, v interface{}) (model.WebhookRequest, error) {
+func (ec *executionContext) unmarshalNWebhookRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐWebhookRequest(ctx context.Context, v any) (model.WebhookRequest, error) {
res, err := ec.unmarshalInputWebhookRequest(ctx, v)
return res, graphql.ErrorOnPath(ctx, err)
}
-func (ec *executionContext) marshalNWebhooks2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐWebhooks(ctx context.Context, sel ast.SelectionSet, v model.Webhooks) graphql.Marshaler {
+func (ec *executionContext) marshalNWebhooks2githubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐWebhooks(ctx context.Context, sel ast.SelectionSet, v model.Webhooks) graphql.Marshaler {
return ec._Webhooks(ctx, sel, &v)
}
-func (ec *executionContext) marshalNWebhooks2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐWebhooks(ctx context.Context, sel ast.SelectionSet, v *model.Webhooks) graphql.Marshaler {
+func (ec *executionContext) marshalNWebhooks2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐWebhooks(ctx context.Context, sel ast.SelectionSet, v *model.Webhooks) graphql.Marshaler {
if v == nil {
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
ec.Errorf(ctx, "the requested element is null which the schema does not allow")
@@ -22384,12 +22805,13 @@ func (ec *executionContext) marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgq
return ret
}
-func (ec *executionContext) unmarshalN__DirectiveLocation2string(ctx context.Context, v interface{}) (string, error) {
+func (ec *executionContext) unmarshalN__DirectiveLocation2string(ctx context.Context, v any) (string, error) {
res, err := graphql.UnmarshalString(v)
return res, graphql.ErrorOnPath(ctx, err)
}
func (ec *executionContext) marshalN__DirectiveLocation2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler {
+ _ = sel
res := graphql.MarshalString(v)
if res == graphql.Null {
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
@@ -22399,11 +22821,9 @@ func (ec *executionContext) marshalN__DirectiveLocation2string(ctx context.Conte
return res
}
-func (ec *executionContext) unmarshalN__DirectiveLocation2ᚕstringᚄ(ctx context.Context, v interface{}) ([]string, error) {
- var vSlice []interface{}
- if v != nil {
- vSlice = graphql.CoerceList(v)
- }
+func (ec *executionContext) unmarshalN__DirectiveLocation2ᚕstringᚄ(ctx context.Context, v any) ([]string, error) {
+ var vSlice []any
+ vSlice = graphql.CoerceList(v)
var err error
res := make([]string, len(vSlice))
for i := range vSlice {
@@ -22574,12 +22994,13 @@ func (ec *executionContext) marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgen
return ec.___Type(ctx, sel, v)
}
-func (ec *executionContext) unmarshalN__TypeKind2string(ctx context.Context, v interface{}) (string, error) {
+func (ec *executionContext) unmarshalN__TypeKind2string(ctx context.Context, v any) (string, error) {
res, err := graphql.UnmarshalString(v)
return res, graphql.ErrorOnPath(ctx, err)
}
func (ec *executionContext) marshalN__TypeKind2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler {
+ _ = sel
res := graphql.MarshalString(v)
if res == graphql.Null {
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
@@ -22589,17 +23010,19 @@ func (ec *executionContext) marshalN__TypeKind2string(ctx context.Context, sel a
return res
}
-func (ec *executionContext) unmarshalOBoolean2bool(ctx context.Context, v interface{}) (bool, error) {
+func (ec *executionContext) unmarshalOBoolean2bool(ctx context.Context, v any) (bool, error) {
res, err := graphql.UnmarshalBoolean(v)
return res, graphql.ErrorOnPath(ctx, err)
}
func (ec *executionContext) marshalOBoolean2bool(ctx context.Context, sel ast.SelectionSet, v bool) graphql.Marshaler {
+ _ = sel
+ _ = ctx
res := graphql.MarshalBoolean(v)
return res
}
-func (ec *executionContext) unmarshalOBoolean2ᚖbool(ctx context.Context, v interface{}) (*bool, error) {
+func (ec *executionContext) unmarshalOBoolean2ᚖbool(ctx context.Context, v any) (*bool, error) {
if v == nil {
return nil, nil
}
@@ -22611,11 +23034,13 @@ func (ec *executionContext) marshalOBoolean2ᚖbool(ctx context.Context, sel ast
if v == nil {
return graphql.Null
}
+ _ = sel
+ _ = ctx
res := graphql.MarshalBoolean(*v)
return res
}
-func (ec *executionContext) unmarshalOID2ᚖstring(ctx context.Context, v interface{}) (*string, error) {
+func (ec *executionContext) unmarshalOID2ᚖstring(ctx context.Context, v any) (*string, error) {
if v == nil {
return nil, nil
}
@@ -22627,11 +23052,13 @@ func (ec *executionContext) marshalOID2ᚖstring(ctx context.Context, sel ast.Se
if v == nil {
return graphql.Null
}
+ _ = sel
+ _ = ctx
res := graphql.MarshalID(*v)
return res
}
-func (ec *executionContext) unmarshalOInt642ᚖint64(ctx context.Context, v interface{}) (*int64, error) {
+func (ec *executionContext) unmarshalOInt642ᚖint64(ctx context.Context, v any) (*int64, error) {
if v == nil {
return nil, nil
}
@@ -22643,11 +23070,13 @@ func (ec *executionContext) marshalOInt642ᚖint64(ctx context.Context, sel ast.
if v == nil {
return graphql.Null
}
+ _ = sel
+ _ = ctx
res := graphql.MarshalInt64(*v)
return res
}
-func (ec *executionContext) unmarshalOListWebhookLogRequest2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐListWebhookLogRequest(ctx context.Context, v interface{}) (*model.ListWebhookLogRequest, error) {
+func (ec *executionContext) unmarshalOListWebhookLogRequest2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐListWebhookLogRequest(ctx context.Context, v any) (*model.ListWebhookLogRequest, error) {
if v == nil {
return nil, nil
}
@@ -22655,7 +23084,7 @@ func (ec *executionContext) unmarshalOListWebhookLogRequest2ᚖgithubᚗcomᚋau
return &res, graphql.ErrorOnPath(ctx, err)
}
-func (ec *executionContext) unmarshalOMap2map(ctx context.Context, v interface{}) (map[string]interface{}, error) {
+func (ec *executionContext) unmarshalOMap2map(ctx context.Context, v any) (map[string]any, error) {
if v == nil {
return nil, nil
}
@@ -22663,54 +23092,54 @@ func (ec *executionContext) unmarshalOMap2map(ctx context.Context, v interface{}
return res, graphql.ErrorOnPath(ctx, err)
}
-func (ec *executionContext) marshalOMap2map(ctx context.Context, sel ast.SelectionSet, v map[string]interface{}) graphql.Marshaler {
+func (ec *executionContext) marshalOMap2map(ctx context.Context, sel ast.SelectionSet, v map[string]any) graphql.Marshaler {
if v == nil {
return graphql.Null
}
+ _ = sel
+ _ = ctx
res := graphql.MarshalMap(v)
return res
}
-func (ec *executionContext) unmarshalOMobileSignUpInput2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐMobileSignUpInput(ctx context.Context, v interface{}) (*model.MobileSignUpInput, error) {
+func (ec *executionContext) unmarshalOMobileSignUpRequest2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐMobileSignUpRequest(ctx context.Context, v any) (*model.MobileSignUpRequest, error) {
if v == nil {
return nil, nil
}
- res, err := ec.unmarshalInputMobileSignUpInput(ctx, v)
+ res, err := ec.unmarshalInputMobileSignUpRequest(ctx, v)
return &res, graphql.ErrorOnPath(ctx, err)
}
-func (ec *executionContext) unmarshalOPaginatedInput2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐPaginatedInput(ctx context.Context, v interface{}) (*model.PaginatedInput, error) {
+func (ec *executionContext) unmarshalOPaginatedRequest2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐPaginatedRequest(ctx context.Context, v any) (*model.PaginatedRequest, error) {
if v == nil {
return nil, nil
}
- res, err := ec.unmarshalInputPaginatedInput(ctx, v)
+ res, err := ec.unmarshalInputPaginatedRequest(ctx, v)
return &res, graphql.ErrorOnPath(ctx, err)
}
-func (ec *executionContext) unmarshalOPaginationInput2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐPaginationInput(ctx context.Context, v interface{}) (*model.PaginationInput, error) {
+func (ec *executionContext) unmarshalOPaginationRequest2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐPaginationRequest(ctx context.Context, v any) (*model.PaginationRequest, error) {
if v == nil {
return nil, nil
}
- res, err := ec.unmarshalInputPaginationInput(ctx, v)
+ res, err := ec.unmarshalInputPaginationRequest(ctx, v)
return &res, graphql.ErrorOnPath(ctx, err)
}
-func (ec *executionContext) unmarshalOSessionQueryInput2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐSessionQueryInput(ctx context.Context, v interface{}) (*model.SessionQueryInput, error) {
+func (ec *executionContext) unmarshalOSessionQueryRequest2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐSessionQueryRequest(ctx context.Context, v any) (*model.SessionQueryRequest, error) {
if v == nil {
return nil, nil
}
- res, err := ec.unmarshalInputSessionQueryInput(ctx, v)
+ res, err := ec.unmarshalInputSessionQueryRequest(ctx, v)
return &res, graphql.ErrorOnPath(ctx, err)
}
-func (ec *executionContext) unmarshalOString2ᚕstringᚄ(ctx context.Context, v interface{}) ([]string, error) {
+func (ec *executionContext) unmarshalOString2ᚕstringᚄ(ctx context.Context, v any) ([]string, error) {
if v == nil {
return nil, nil
}
- var vSlice []interface{}
- if v != nil {
- vSlice = graphql.CoerceList(v)
- }
+ var vSlice []any
+ vSlice = graphql.CoerceList(v)
var err error
res := make([]string, len(vSlice))
for i := range vSlice {
@@ -22741,14 +23170,12 @@ func (ec *executionContext) marshalOString2ᚕstringᚄ(ctx context.Context, sel
return ret
}
-func (ec *executionContext) unmarshalOString2ᚕᚖstring(ctx context.Context, v interface{}) ([]*string, error) {
+func (ec *executionContext) unmarshalOString2ᚕᚖstring(ctx context.Context, v any) ([]*string, error) {
if v == nil {
return nil, nil
}
- var vSlice []interface{}
- if v != nil {
- vSlice = graphql.CoerceList(v)
- }
+ var vSlice []any
+ vSlice = graphql.CoerceList(v)
var err error
res := make([]*string, len(vSlice))
for i := range vSlice {
@@ -22773,7 +23200,7 @@ func (ec *executionContext) marshalOString2ᚕᚖstring(ctx context.Context, sel
return ret
}
-func (ec *executionContext) unmarshalOString2ᚖstring(ctx context.Context, v interface{}) (*string, error) {
+func (ec *executionContext) unmarshalOString2ᚖstring(ctx context.Context, v any) (*string, error) {
if v == nil {
return nil, nil
}
@@ -22785,22 +23212,24 @@ func (ec *executionContext) marshalOString2ᚖstring(ctx context.Context, sel as
if v == nil {
return graphql.Null
}
+ _ = sel
+ _ = ctx
res := graphql.MarshalString(*v)
return res
}
-func (ec *executionContext) marshalOUser2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐUser(ctx context.Context, sel ast.SelectionSet, v *model.User) graphql.Marshaler {
+func (ec *executionContext) marshalOUser2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐUser(ctx context.Context, sel ast.SelectionSet, v *model.User) graphql.Marshaler {
if v == nil {
return graphql.Null
}
return ec._User(ctx, sel, v)
}
-func (ec *executionContext) unmarshalOValidateSessionInput2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐValidateSessionInput(ctx context.Context, v interface{}) (*model.ValidateSessionInput, error) {
+func (ec *executionContext) unmarshalOValidateSessionRequest2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋinternalᚋgraphᚋmodelᚐValidateSessionRequest(ctx context.Context, v any) (*model.ValidateSessionRequest, error) {
if v == nil {
return nil, nil
}
- res, err := ec.unmarshalInputValidateSessionInput(ctx, v)
+ res, err := ec.unmarshalInputValidateSessionRequest(ctx, v)
return &res, graphql.ErrorOnPath(ctx, err)
}
diff --git a/server/graph/model/models_gen.go b/internal/graph/model/models_gen.go
similarity index 67%
rename from server/graph/model/models_gen.go
rename to internal/graph/model/models_gen.go
index f14db1929..cb8d7bb16 100644
--- a/server/graph/model/models_gen.go
+++ b/internal/graph/model/models_gen.go
@@ -10,18 +10,18 @@ type AddEmailTemplateRequest struct {
}
type AddWebhookRequest struct {
- EventName string `json:"event_name"`
- EventDescription *string `json:"event_description,omitempty"`
- Endpoint string `json:"endpoint"`
- Enabled bool `json:"enabled"`
- Headers map[string]interface{} `json:"headers,omitempty"`
+ EventName string `json:"event_name"`
+ EventDescription *string `json:"event_description,omitempty"`
+ Endpoint string `json:"endpoint"`
+ Enabled bool `json:"enabled"`
+ Headers map[string]any `json:"headers,omitempty"`
}
-type AdminLoginInput struct {
+type AdminLoginRequest struct {
AdminSecret string `json:"admin_secret"`
}
-type AdminSignupInput struct {
+type AdminSignupRequest struct {
AdminSecret string `json:"admin_secret"`
}
@@ -44,7 +44,7 @@ type DeleteEmailTemplateRequest struct {
ID string `json:"id"`
}
-type DeleteUserInput struct {
+type DeleteUserRequest struct {
Email string `json:"email"`
}
@@ -142,7 +142,7 @@ type Error struct {
Reason string `json:"reason"`
}
-type ForgotPasswordInput struct {
+type ForgotPasswordRequest struct {
Email *string `json:"email,omitempty"`
PhoneNumber *string `json:"phone_number,omitempty"`
State *string `json:"state,omitempty"`
@@ -154,7 +154,7 @@ type ForgotPasswordResponse struct {
ShouldShowMobileOtpScreen *bool `json:"should_show_mobile_otp_screen,omitempty"`
}
-type GenerateJWTKeysInput struct {
+type GenerateJWTKeysRequest struct {
Type string `json:"type"`
}
@@ -169,7 +169,7 @@ type GetUserRequest struct {
Email *string `json:"email,omitempty"`
}
-type InviteMemberInput struct {
+type InviteMemberRequest struct {
Emails []string `json:"emails"`
RedirectURI *string `json:"redirect_uri,omitempty"`
}
@@ -180,11 +180,11 @@ type InviteMembersResponse struct {
}
type ListWebhookLogRequest struct {
- Pagination *PaginationInput `json:"pagination,omitempty"`
- WebhookID *string `json:"webhook_id,omitempty"`
+ Pagination *PaginationRequest `json:"pagination,omitempty"`
+ WebhookID *string `json:"webhook_id,omitempty"`
}
-type LoginInput struct {
+type LoginRequest struct {
Email *string `json:"email,omitempty"`
PhoneNumber *string `json:"phone_number,omitempty"`
Password string `json:"password"`
@@ -193,7 +193,7 @@ type LoginInput struct {
State *string `json:"state,omitempty"`
}
-type MagicLinkLoginInput struct {
+type MagicLinkLoginRequest struct {
Email string `json:"email"`
Roles []string `json:"roles,omitempty"`
Scope []string `json:"scope,omitempty"`
@@ -224,7 +224,7 @@ type Meta struct {
IsPhoneVerificationEnabled bool `json:"is_phone_verification_enabled"`
}
-type MobileLoginInput struct {
+type MobileLoginRequest struct {
PhoneNumber string `json:"phone_number"`
Password string `json:"password"`
Roles []string `json:"roles,omitempty"`
@@ -232,35 +232,35 @@ type MobileLoginInput struct {
State *string `json:"state,omitempty"`
}
-type MobileSignUpInput struct {
- Email *string `json:"email,omitempty"`
- GivenName *string `json:"given_name,omitempty"`
- FamilyName *string `json:"family_name,omitempty"`
- MiddleName *string `json:"middle_name,omitempty"`
- Nickname *string `json:"nickname,omitempty"`
- Gender *string `json:"gender,omitempty"`
- Birthdate *string `json:"birthdate,omitempty"`
- PhoneNumber string `json:"phone_number"`
- Picture *string `json:"picture,omitempty"`
- Password string `json:"password"`
- ConfirmPassword string `json:"confirm_password"`
- Roles []string `json:"roles,omitempty"`
- Scope []string `json:"scope,omitempty"`
- RedirectURI *string `json:"redirect_uri,omitempty"`
- IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled,omitempty"`
- State *string `json:"state,omitempty"`
- AppData map[string]interface{} `json:"app_data,omitempty"`
+type MobileSignUpRequest struct {
+ Email *string `json:"email,omitempty"`
+ GivenName *string `json:"given_name,omitempty"`
+ FamilyName *string `json:"family_name,omitempty"`
+ MiddleName *string `json:"middle_name,omitempty"`
+ Nickname *string `json:"nickname,omitempty"`
+ Gender *string `json:"gender,omitempty"`
+ Birthdate *string `json:"birthdate,omitempty"`
+ PhoneNumber string `json:"phone_number"`
+ Picture *string `json:"picture,omitempty"`
+ Password string `json:"password"`
+ ConfirmPassword string `json:"confirm_password"`
+ Roles []string `json:"roles,omitempty"`
+ Scope []string `json:"scope,omitempty"`
+ RedirectURI *string `json:"redirect_uri,omitempty"`
+ IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled,omitempty"`
+ State *string `json:"state,omitempty"`
+ AppData map[string]any `json:"app_data,omitempty"`
}
type Mutation struct {
}
-type OAuthRevokeInput struct {
+type OAuthRevokeRequest struct {
RefreshToken string `json:"refresh_token"`
}
-type PaginatedInput struct {
- Pagination *PaginationInput `json:"pagination,omitempty"`
+type PaginatedRequest struct {
+ Pagination *PaginationRequest `json:"pagination,omitempty"`
}
type Pagination struct {
@@ -270,7 +270,7 @@ type Pagination struct {
Total int64 `json:"total"`
}
-type PaginationInput struct {
+type PaginationRequest struct {
Limit *int64 `json:"limit,omitempty"`
Page *int64 `json:"page,omitempty"`
}
@@ -284,13 +284,13 @@ type ResendOTPRequest struct {
State *string `json:"state,omitempty"`
}
-type ResendVerifyEmailInput struct {
+type ResendVerifyEmailRequest struct {
Email string `json:"email"`
Identifier string `json:"identifier"`
State *string `json:"state,omitempty"`
}
-type ResetPasswordInput struct {
+type ResetPasswordRequest struct {
Token *string `json:"token,omitempty"`
Otp *string `json:"otp,omitempty"`
PhoneNumber *string `json:"phone_number,omitempty"`
@@ -302,45 +302,36 @@ type Response struct {
Message string `json:"message"`
}
-type SMSVerificationRequests struct {
- ID string `json:"id"`
- Code string `json:"code"`
- CodeExpiresAt int64 `json:"code_expires_at"`
- PhoneNumber string `json:"phone_number"`
- CreatedAt int64 `json:"created_at"`
- UpdatedAt *int64 `json:"updated_at,omitempty"`
-}
-
-type SessionQueryInput struct {
+type SessionQueryRequest struct {
Roles []string `json:"roles,omitempty"`
Scope []string `json:"scope,omitempty"`
}
-type SignUpInput struct {
- Email *string `json:"email,omitempty"`
- GivenName *string `json:"given_name,omitempty"`
- FamilyName *string `json:"family_name,omitempty"`
- MiddleName *string `json:"middle_name,omitempty"`
- Nickname *string `json:"nickname,omitempty"`
- Gender *string `json:"gender,omitempty"`
- Birthdate *string `json:"birthdate,omitempty"`
- PhoneNumber *string `json:"phone_number,omitempty"`
- Picture *string `json:"picture,omitempty"`
- Password string `json:"password"`
- ConfirmPassword string `json:"confirm_password"`
- Roles []string `json:"roles,omitempty"`
- Scope []string `json:"scope,omitempty"`
- RedirectURI *string `json:"redirect_uri,omitempty"`
- IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled,omitempty"`
- State *string `json:"state,omitempty"`
- AppData map[string]interface{} `json:"app_data,omitempty"`
+type SignUpRequest struct {
+ Email *string `json:"email,omitempty"`
+ GivenName *string `json:"given_name,omitempty"`
+ FamilyName *string `json:"family_name,omitempty"`
+ MiddleName *string `json:"middle_name,omitempty"`
+ Nickname *string `json:"nickname,omitempty"`
+ Gender *string `json:"gender,omitempty"`
+ Birthdate *string `json:"birthdate,omitempty"`
+ PhoneNumber *string `json:"phone_number,omitempty"`
+ Picture *string `json:"picture,omitempty"`
+ Password string `json:"password"`
+ ConfirmPassword string `json:"confirm_password"`
+ Roles []string `json:"roles,omitempty"`
+ Scope []string `json:"scope,omitempty"`
+ RedirectURI *string `json:"redirect_uri,omitempty"`
+ IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled,omitempty"`
+ State *string `json:"state,omitempty"`
+ AppData map[string]any `json:"app_data,omitempty"`
}
type TestEndpointRequest struct {
- Endpoint string `json:"endpoint"`
- EventName string `json:"event_name"`
- EventDescription *string `json:"event_description,omitempty"`
- Headers map[string]interface{} `json:"headers,omitempty"`
+ Endpoint string `json:"endpoint"`
+ EventName string `json:"event_name"`
+ EventDescription *string `json:"event_description,omitempty"`
+ Headers map[string]any `json:"headers,omitempty"`
}
type TestEndpointResponse struct {
@@ -348,7 +339,7 @@ type TestEndpointResponse struct {
Response *string `json:"response,omitempty"`
}
-type UpdateAccessInput struct {
+type UpdateAccessRequest struct {
UserID string `json:"user_id"`
}
@@ -360,7 +351,7 @@ type UpdateEmailTemplateRequest struct {
Design *string `json:"design,omitempty"`
}
-type UpdateEnvInput struct {
+type UpdateEnvRequest struct {
AccessTokenExpiryTime *string `json:"ACCESS_TOKEN_EXPIRY_TIME,omitempty"`
AdminSecret *string `json:"ADMIN_SECRET,omitempty"`
CustomAccessTokenScript *string `json:"CUSTOM_ACCESS_TOKEN_SCRIPT,omitempty"`
@@ -425,71 +416,71 @@ type UpdateEnvInput struct {
DisableTotpLogin *bool `json:"DISABLE_TOTP_LOGIN,omitempty"`
}
-type UpdateProfileInput struct {
- OldPassword *string `json:"old_password,omitempty"`
- NewPassword *string `json:"new_password,omitempty"`
- ConfirmNewPassword *string `json:"confirm_new_password,omitempty"`
- Email *string `json:"email,omitempty"`
- GivenName *string `json:"given_name,omitempty"`
- FamilyName *string `json:"family_name,omitempty"`
- MiddleName *string `json:"middle_name,omitempty"`
- Nickname *string `json:"nickname,omitempty"`
- Gender *string `json:"gender,omitempty"`
- Birthdate *string `json:"birthdate,omitempty"`
- PhoneNumber *string `json:"phone_number,omitempty"`
- Picture *string `json:"picture,omitempty"`
- IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled,omitempty"`
- AppData map[string]interface{} `json:"app_data,omitempty"`
-}
-
-type UpdateUserInput struct {
- ID string `json:"id"`
- Email *string `json:"email,omitempty"`
- EmailVerified *bool `json:"email_verified,omitempty"`
- GivenName *string `json:"given_name,omitempty"`
- FamilyName *string `json:"family_name,omitempty"`
- MiddleName *string `json:"middle_name,omitempty"`
- Nickname *string `json:"nickname,omitempty"`
- Gender *string `json:"gender,omitempty"`
- Birthdate *string `json:"birthdate,omitempty"`
- PhoneNumber *string `json:"phone_number,omitempty"`
- PhoneNumberVerified *bool `json:"phone_number_verified,omitempty"`
- Picture *string `json:"picture,omitempty"`
- Roles []*string `json:"roles,omitempty"`
- IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled,omitempty"`
- AppData map[string]interface{} `json:"app_data,omitempty"`
+type UpdateProfileRequest struct {
+ OldPassword *string `json:"old_password,omitempty"`
+ NewPassword *string `json:"new_password,omitempty"`
+ ConfirmNewPassword *string `json:"confirm_new_password,omitempty"`
+ Email *string `json:"email,omitempty"`
+ GivenName *string `json:"given_name,omitempty"`
+ FamilyName *string `json:"family_name,omitempty"`
+ MiddleName *string `json:"middle_name,omitempty"`
+ Nickname *string `json:"nickname,omitempty"`
+ Gender *string `json:"gender,omitempty"`
+ Birthdate *string `json:"birthdate,omitempty"`
+ PhoneNumber *string `json:"phone_number,omitempty"`
+ Picture *string `json:"picture,omitempty"`
+ IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled,omitempty"`
+ AppData map[string]any `json:"app_data,omitempty"`
+}
+
+type UpdateUserRequest struct {
+ ID string `json:"id"`
+ Email *string `json:"email,omitempty"`
+ EmailVerified *bool `json:"email_verified,omitempty"`
+ GivenName *string `json:"given_name,omitempty"`
+ FamilyName *string `json:"family_name,omitempty"`
+ MiddleName *string `json:"middle_name,omitempty"`
+ Nickname *string `json:"nickname,omitempty"`
+ Gender *string `json:"gender,omitempty"`
+ Birthdate *string `json:"birthdate,omitempty"`
+ PhoneNumber *string `json:"phone_number,omitempty"`
+ PhoneNumberVerified *bool `json:"phone_number_verified,omitempty"`
+ Picture *string `json:"picture,omitempty"`
+ Roles []*string `json:"roles,omitempty"`
+ IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled,omitempty"`
+ AppData map[string]any `json:"app_data,omitempty"`
}
type UpdateWebhookRequest struct {
- ID string `json:"id"`
- EventName *string `json:"event_name,omitempty"`
- EventDescription *string `json:"event_description,omitempty"`
- Endpoint *string `json:"endpoint,omitempty"`
- Enabled *bool `json:"enabled,omitempty"`
- Headers map[string]interface{} `json:"headers,omitempty"`
+ ID string `json:"id"`
+ EventName *string `json:"event_name,omitempty"`
+ EventDescription *string `json:"event_description,omitempty"`
+ Endpoint *string `json:"endpoint,omitempty"`
+ Enabled *bool `json:"enabled,omitempty"`
+ Headers map[string]any `json:"headers,omitempty"`
}
type User struct {
- ID string `json:"id"`
- Email *string `json:"email,omitempty"`
- EmailVerified bool `json:"email_verified"`
- SignupMethods string `json:"signup_methods"`
- GivenName *string `json:"given_name,omitempty"`
- FamilyName *string `json:"family_name,omitempty"`
- MiddleName *string `json:"middle_name,omitempty"`
- Nickname *string `json:"nickname,omitempty"`
- PreferredUsername *string `json:"preferred_username,omitempty"`
- Gender *string `json:"gender,omitempty"`
- Birthdate *string `json:"birthdate,omitempty"`
- PhoneNumber *string `json:"phone_number,omitempty"`
- PhoneNumberVerified *bool `json:"phone_number_verified,omitempty"`
- Picture *string `json:"picture,omitempty"`
- Roles []string `json:"roles"`
- CreatedAt *int64 `json:"created_at,omitempty"`
- UpdatedAt *int64 `json:"updated_at,omitempty"`
- RevokedTimestamp *int64 `json:"revoked_timestamp,omitempty"`
- IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled,omitempty"`
- AppData map[string]interface{} `json:"app_data,omitempty"`
+ ID string `json:"id"`
+ Email *string `json:"email,omitempty"`
+ EmailVerified bool `json:"email_verified"`
+ SignupMethods string `json:"signup_methods"`
+ GivenName *string `json:"given_name,omitempty"`
+ FamilyName *string `json:"family_name,omitempty"`
+ MiddleName *string `json:"middle_name,omitempty"`
+ Nickname *string `json:"nickname,omitempty"`
+ PreferredUsername *string `json:"preferred_username,omitempty"`
+ Gender *string `json:"gender,omitempty"`
+ Birthdate *string `json:"birthdate,omitempty"`
+ PhoneNumber *string `json:"phone_number,omitempty"`
+ PhoneNumberVerified bool `json:"phone_number_verified"`
+ Picture *string `json:"picture,omitempty"`
+ Roles []string `json:"roles"`
+ CreatedAt *int64 `json:"created_at,omitempty"`
+ UpdatedAt *int64 `json:"updated_at,omitempty"`
+ RevokedTimestamp *int64 `json:"revoked_timestamp,omitempty"`
+ IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled,omitempty"`
+ AppData map[string]any `json:"app_data,omitempty"`
}
type Users struct {
@@ -497,18 +488,18 @@ type Users struct {
Users []*User `json:"users"`
}
-type ValidateJWTTokenInput struct {
+type ValidateJWTTokenRequest struct {
TokenType string `json:"token_type"`
Token string `json:"token"`
Roles []string `json:"roles,omitempty"`
}
type ValidateJWTTokenResponse struct {
- IsValid bool `json:"is_valid"`
- Claims map[string]interface{} `json:"claims,omitempty"`
+ IsValid bool `json:"is_valid"`
+ Claims map[string]any `json:"claims,omitempty"`
}
-type ValidateSessionInput struct {
+type ValidateSessionRequest struct {
Cookie string `json:"cookie"`
Roles []string `json:"roles,omitempty"`
}
@@ -535,7 +526,7 @@ type VerificationRequests struct {
VerificationRequests []*VerificationRequest `json:"verification_requests"`
}
-type VerifyEmailInput struct {
+type VerifyEmailRequest struct {
Token string `json:"token"`
State *string `json:"state,omitempty"`
}
@@ -549,14 +540,14 @@ type VerifyOTPRequest struct {
}
type Webhook struct {
- ID string `json:"id"`
- EventName *string `json:"event_name,omitempty"`
- EventDescription *string `json:"event_description,omitempty"`
- Endpoint *string `json:"endpoint,omitempty"`
- Enabled *bool `json:"enabled,omitempty"`
- Headers map[string]interface{} `json:"headers,omitempty"`
- CreatedAt *int64 `json:"created_at,omitempty"`
- UpdatedAt *int64 `json:"updated_at,omitempty"`
+ ID string `json:"id"`
+ EventName *string `json:"event_name,omitempty"`
+ EventDescription *string `json:"event_description,omitempty"`
+ Endpoint *string `json:"endpoint,omitempty"`
+ Enabled *bool `json:"enabled,omitempty"`
+ Headers map[string]any `json:"headers,omitempty"`
+ CreatedAt *int64 `json:"created_at,omitempty"`
+ UpdatedAt *int64 `json:"updated_at,omitempty"`
}
type WebhookLog struct {
diff --git a/server/graph/resolver.go b/internal/graph/resolver.go
similarity index 55%
rename from server/graph/resolver.go
rename to internal/graph/resolver.go
index a25c09c61..ce42d3205 100644
--- a/server/graph/resolver.go
+++ b/internal/graph/resolver.go
@@ -1,7 +1,13 @@
package graph
+import (
+ "github.com/authorizerdev/authorizer/internal/graphql"
+)
+
// This file will not be regenerated automatically.
//
// It serves as dependency injection for your app, add any dependencies you require here.
-type Resolver struct{}
+type Resolver struct {
+ GraphQLProvider graphql.Provider
+}
diff --git a/server/graph/schema.graphqls b/internal/graph/schema.graphqls
similarity index 84%
rename from server/graph/schema.graphqls
rename to internal/graph/schema.graphqls
index 10202210b..ee070c17c 100644
--- a/server/graph/schema.graphqls
+++ b/internal/graph/schema.graphqls
@@ -50,7 +50,7 @@ type User {
gender: String
birthdate: String
phone_number: String
- phone_number_verified: Boolean
+ phone_number_verified: Boolean!
picture: String
roles: [String!]!
created_at: Int64
@@ -82,15 +82,6 @@ type VerificationRequests {
verification_requests: [VerificationRequest!]!
}
-type SMSVerificationRequests {
- id: ID!
- code: String!
- code_expires_at: Int64!
- phone_number: String!
- created_at: Int64!
- updated_at: Int64
-}
-
type Error {
message: String!
reason: String!
@@ -270,7 +261,7 @@ type EmailTemplates {
email_templates: [EmailTemplate!]!
}
-input UpdateEnvInput {
+input UpdateEnvRequest {
ACCESS_TOKEN_EXPIRY_TIME: String
ADMIN_SECRET: String
CUSTOM_ACCESS_TOKEN_SCRIPT: String
@@ -335,16 +326,16 @@ input UpdateEnvInput {
DISABLE_TOTP_LOGIN: Boolean
}
-input AdminLoginInput {
+input AdminLoginRequest {
admin_secret: String!
}
-input AdminSignupInput {
+input AdminSignupRequest {
admin_secret: String!
}
# Deprecated from v1.2.0
-input MobileSignUpInput {
+input MobileSignUpRequest {
email: String
given_name: String
family_name: String
@@ -367,7 +358,7 @@ input MobileSignUpInput {
app_data: Map
}
-input SignUpInput {
+input SignUpRequest {
email: String
given_name: String
family_name: String
@@ -390,7 +381,7 @@ input SignUpInput {
app_data: Map
}
-input LoginInput {
+input LoginRequest {
email: String
phone_number: String
password: String!
@@ -403,7 +394,7 @@ input LoginInput {
}
# Deprecated from v1.2.0
-input MobileLoginInput {
+input MobileLoginRequest {
phone_number: String!
password: String!
roles: [String!]
@@ -414,7 +405,7 @@ input MobileLoginInput {
state: String
}
-input VerifyEmailInput {
+input VerifyEmailRequest {
token: String!
# state is used for authorization code grant flow
# it is used to get code for an on-going auth process during login
@@ -422,7 +413,7 @@ input VerifyEmailInput {
state: String
}
-input ResendVerifyEmailInput {
+input ResendVerifyEmailRequest {
email: String!
identifier: String!
# state is used for authorization code grant flow
@@ -431,7 +422,7 @@ input ResendVerifyEmailInput {
state: String
}
-input UpdateProfileInput {
+input UpdateProfileRequest {
old_password: String
new_password: String
confirm_new_password: String
@@ -448,7 +439,7 @@ input UpdateProfileInput {
app_data: Map
}
-input UpdateUserInput {
+input UpdateUserRequest {
id: ID!
email: String
email_verified: Boolean
@@ -466,14 +457,14 @@ input UpdateUserInput {
app_data: Map
}
-input ForgotPasswordInput {
+input ForgotPasswordRequest {
email: String
phone_number: String
state: String
redirect_uri: String
}
-input ResetPasswordInput {
+input ResetPasswordRequest {
token: String
otp: String
phone_number: String
@@ -481,11 +472,11 @@ input ResetPasswordInput {
confirm_password: String!
}
-input DeleteUserInput {
+input DeleteUserRequest {
email: String!
}
-input MagicLinkLoginInput {
+input MagicLinkLoginRequest {
email: String!
roles: [String!]
scope: [String!]
@@ -493,50 +484,50 @@ input MagicLinkLoginInput {
redirect_uri: String
}
-input SessionQueryInput {
+input SessionQueryRequest {
roles: [String!]
scope: [String!]
}
-input PaginationInput {
+input PaginationRequest {
limit: Int64
page: Int64
}
-input PaginatedInput {
- pagination: PaginationInput
+input PaginatedRequest {
+ pagination: PaginationRequest
}
-input OAuthRevokeInput {
+input OAuthRevokeRequest {
refresh_token: String!
}
-input InviteMemberInput {
+input InviteMemberRequest {
emails: [String!]!
redirect_uri: String
}
-input UpdateAccessInput {
+input UpdateAccessRequest {
user_id: String!
}
-input ValidateJWTTokenInput {
+input ValidateJWTTokenRequest {
token_type: String!
token: String!
roles: [String!]
}
-input ValidateSessionInput {
+input ValidateSessionRequest {
cookie: String!
roles: [String!]
}
-input GenerateJWTKeysInput {
+input GenerateJWTKeysRequest {
type: String!
}
input ListWebhookLogRequest {
- pagination: PaginationInput
+ pagination: PaginationRequest
webhook_id: String
}
@@ -618,34 +609,37 @@ input GetUserRequest {
}
type Mutation {
- signup(params: SignUpInput!): AuthResponse!
+ signup(params: SignUpRequest!): AuthResponse!
# Deprecated from v1.2.0
- mobile_signup(params: MobileSignUpInput): AuthResponse!
- login(params: LoginInput!): AuthResponse!
+ mobile_signup(params: MobileSignUpRequest): AuthResponse!
+ login(params: LoginRequest!): AuthResponse!
# Deprecated from v1.2.0
- mobile_login(params: MobileLoginInput!): AuthResponse!
- magic_link_login(params: MagicLinkLoginInput!): Response!
+ mobile_login(params: MobileLoginRequest!): AuthResponse!
+ magic_link_login(params: MagicLinkLoginRequest!): Response!
logout: Response!
- update_profile(params: UpdateProfileInput!): Response!
- verify_email(params: VerifyEmailInput!): AuthResponse!
- resend_verify_email(params: ResendVerifyEmailInput!): Response!
- forgot_password(params: ForgotPasswordInput!): ForgotPasswordResponse!
- reset_password(params: ResetPasswordInput!): Response!
- revoke(params: OAuthRevokeInput!): Response!
+ update_profile(params: UpdateProfileRequest!): Response!
+ verify_email(params: VerifyEmailRequest!): AuthResponse!
+ resend_verify_email(params: ResendVerifyEmailRequest!): Response!
+ forgot_password(params: ForgotPasswordRequest!): ForgotPasswordResponse!
+ reset_password(params: ResetPasswordRequest!): Response!
+ revoke(params: OAuthRevokeRequest!): Response!
verify_otp(params: VerifyOTPRequest!): AuthResponse!
resend_otp(params: ResendOTPRequest!): Response!
deactivate_account: Response!
# admin only apis
- _delete_user(params: DeleteUserInput!): Response!
- _update_user(params: UpdateUserInput!): User!
- _admin_signup(params: AdminSignupInput!): Response!
- _admin_login(params: AdminLoginInput!): Response!
+ _delete_user(params: DeleteUserRequest!): Response!
+ _update_user(params: UpdateUserRequest!): User!
+ # deprecated from v2.0.0
+ _admin_signup(params: AdminSignupRequest!): Response!
+ _admin_login(params: AdminLoginRequest!): Response!
_admin_logout: Response!
- _update_env(params: UpdateEnvInput!): Response!
- _invite_members(params: InviteMemberInput!): InviteMembersResponse!
- _revoke_access(param: UpdateAccessInput!): Response!
- _enable_access(param: UpdateAccessInput!): Response!
- _generate_jwt_keys(params: GenerateJWTKeysInput!): GenerateJWTKeysResponse!
+ # Deprecated from v2.0.0
+ _update_env(params: UpdateEnvRequest!): Response!
+ _invite_members(params: InviteMemberRequest!): InviteMembersResponse!
+ _revoke_access(param: UpdateAccessRequest!): Response!
+ _enable_access(param: UpdateAccessRequest!): Response!
+ # Deprecated from v2.0.0
+ _generate_jwt_keys(params: GenerateJWTKeysRequest!): GenerateJWTKeysResponse!
_add_webhook(params: AddWebhookRequest!): Response!
_update_webhook(params: UpdateWebhookRequest!): Response!
_delete_webhook(params: WebhookRequest!): Response!
@@ -657,18 +651,19 @@ type Mutation {
type Query {
meta: Meta!
- session(params: SessionQueryInput): AuthResponse!
+ session(params: SessionQueryRequest): AuthResponse!
profile: User!
- validate_jwt_token(params: ValidateJWTTokenInput!): ValidateJWTTokenResponse!
- validate_session(params: ValidateSessionInput): ValidateSessionResponse!
+ validate_jwt_token(params: ValidateJWTTokenRequest!): ValidateJWTTokenResponse!
+ validate_session(params: ValidateSessionRequest): ValidateSessionResponse!
# admin only apis
- _users(params: PaginatedInput): Users!
+ _users(params: PaginatedRequest): Users!
_user(params: GetUserRequest!): User!
- _verification_requests(params: PaginatedInput): VerificationRequests!
+ _verification_requests(params: PaginatedRequest): VerificationRequests!
_admin_session: Response!
+ # Deprecated from v2.0.0
_env: Env!
_webhook(params: WebhookRequest!): Webhook!
- _webhooks(params: PaginatedInput): Webhooks!
+ _webhooks(params: PaginatedRequest): Webhooks!
_webhook_logs(params: ListWebhookLogRequest): WebhookLogs!
- _email_templates(params: PaginatedInput): EmailTemplates!
+ _email_templates(params: PaginatedRequest): EmailTemplates!
}
diff --git a/server/graph/schema.resolvers.go b/internal/graph/schema.resolvers.go
similarity index 62%
rename from server/graph/schema.resolvers.go
rename to internal/graph/schema.resolvers.go
index e4ef95261..36892600e 100644
--- a/server/graph/schema.resolvers.go
+++ b/internal/graph/schema.resolvers.go
@@ -2,244 +2,244 @@ package graph
// This file will be automatically regenerated based on the schema, any resolver implementations
// will be copied through when generating and any unknown code will be moved to the end.
-// Code generated by github.com/99designs/gqlgen version v0.17.45
+// Code generated by github.com/99designs/gqlgen version v0.17.73
import (
"context"
+ "fmt"
- "github.com/authorizerdev/authorizer/server/graph/generated"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/resolvers"
+ "github.com/authorizerdev/authorizer/internal/graph/generated"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
)
// 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)
+func (r *mutationResolver) Signup(ctx context.Context, params model.SignUpRequest) (*model.AuthResponse, error) {
+ return r.GraphQLProvider.SignUp(ctx, ¶ms)
}
// MobileSignup is the resolver for the mobile_signup field.
-func (r *mutationResolver) MobileSignup(ctx context.Context, params *model.MobileSignUpInput) (*model.AuthResponse, error) {
- return resolvers.MobileSignupResolver(ctx, params)
+func (r *mutationResolver) MobileSignup(ctx context.Context, params *model.MobileSignUpRequest) (*model.AuthResponse, error) {
+ return nil, fmt.Errorf("deprecated, use signup with mobile phone_number")
}
// 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)
+func (r *mutationResolver) Login(ctx context.Context, params model.LoginRequest) (*model.AuthResponse, error) {
+ return r.GraphQLProvider.Login(ctx, ¶ms)
}
// MobileLogin is the resolver for the mobile_login field.
-func (r *mutationResolver) MobileLogin(ctx context.Context, params model.MobileLoginInput) (*model.AuthResponse, error) {
- return resolvers.MobileLoginResolver(ctx, params)
+func (r *mutationResolver) MobileLogin(ctx context.Context, params model.MobileLoginRequest) (*model.AuthResponse, error) {
+ return nil, fmt.Errorf("deprecated, use login with mobile phone_number")
}
// 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)
+func (r *mutationResolver) MagicLinkLogin(ctx context.Context, params model.MagicLinkLoginRequest) (*model.Response, error) {
+ return r.GraphQLProvider.MagicLinkLogin(ctx, ¶ms)
}
// Logout is the resolver for the logout field.
func (r *mutationResolver) Logout(ctx context.Context) (*model.Response, error) {
- return resolvers.LogoutResolver(ctx)
+ return r.GraphQLProvider.Logout(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)
+func (r *mutationResolver) UpdateProfile(ctx context.Context, params model.UpdateProfileRequest) (*model.Response, error) {
+ return r.GraphQLProvider.UpdateProfile(ctx, ¶ms)
}
// 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)
+func (r *mutationResolver) VerifyEmail(ctx context.Context, params model.VerifyEmailRequest) (*model.AuthResponse, error) {
+ return r.GraphQLProvider.VerifyEmail(ctx, ¶ms)
}
// 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)
+func (r *mutationResolver) ResendVerifyEmail(ctx context.Context, params model.ResendVerifyEmailRequest) (*model.Response, error) {
+ return r.GraphQLProvider.ResendVerifyEmail(ctx, ¶ms)
}
// ForgotPassword is the resolver for the forgot_password field.
-func (r *mutationResolver) ForgotPassword(ctx context.Context, params model.ForgotPasswordInput) (*model.ForgotPasswordResponse, error) {
- return resolvers.ForgotPasswordResolver(ctx, params)
+func (r *mutationResolver) ForgotPassword(ctx context.Context, params model.ForgotPasswordRequest) (*model.ForgotPasswordResponse, error) {
+ return r.GraphQLProvider.ForgotPassword(ctx, ¶ms)
}
// 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)
+func (r *mutationResolver) ResetPassword(ctx context.Context, params model.ResetPasswordRequest) (*model.Response, error) {
+ return r.GraphQLProvider.ResetPassword(ctx, ¶ms)
}
// 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)
+func (r *mutationResolver) Revoke(ctx context.Context, params model.OAuthRevokeRequest) (*model.Response, error) {
+ return r.GraphQLProvider.Revoke(ctx, ¶ms)
}
// 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)
+ return r.GraphQLProvider.VerifyOTP(ctx, ¶ms)
}
// 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)
+ return r.GraphQLProvider.ResendOTP(ctx, ¶ms)
}
// DeactivateAccount is the resolver for the deactivate_account field.
func (r *mutationResolver) DeactivateAccount(ctx context.Context) (*model.Response, error) {
- return resolvers.DeactivateAccountResolver(ctx)
+ return r.GraphQLProvider.DeactivateAccount(ctx)
}
// 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)
+func (r *mutationResolver) DeleteUser(ctx context.Context, params model.DeleteUserRequest) (*model.Response, error) {
+ return r.GraphQLProvider.DeleteUser(ctx, ¶ms)
}
// 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)
+func (r *mutationResolver) UpdateUser(ctx context.Context, params model.UpdateUserRequest) (*model.User, error) {
+ return r.GraphQLProvider.UpdateUser(ctx, ¶ms)
}
// 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)
+func (r *mutationResolver) AdminSignup(ctx context.Context, params model.AdminSignupRequest) (*model.Response, error) {
+ return nil, fmt.Errorf("deprecated. please configure admin secret via cli args")
}
// 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)
+func (r *mutationResolver) AdminLogin(ctx context.Context, params model.AdminLoginRequest) (*model.Response, error) {
+ return r.GraphQLProvider.AdminLogin(ctx, ¶ms)
}
// AdminLogout is the resolver for the _admin_logout field.
func (r *mutationResolver) AdminLogout(ctx context.Context) (*model.Response, error) {
- return resolvers.AdminLogoutResolver(ctx)
+ return r.GraphQLProvider.AdminLogout(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)
+func (r *mutationResolver) UpdateEnv(ctx context.Context, params model.UpdateEnvRequest) (*model.Response, error) {
+ return nil, fmt.Errorf("deprecated. please configure env via cli args")
}
// InviteMembers is the resolver for the _invite_members field.
-func (r *mutationResolver) InviteMembers(ctx context.Context, params model.InviteMemberInput) (*model.InviteMembersResponse, error) {
- return resolvers.InviteMembersResolver(ctx, params)
+func (r *mutationResolver) InviteMembers(ctx context.Context, params model.InviteMemberRequest) (*model.InviteMembersResponse, error) {
+ return r.GraphQLProvider.InviteMembers(ctx, ¶ms)
}
// 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)
+func (r *mutationResolver) RevokeAccess(ctx context.Context, param model.UpdateAccessRequest) (*model.Response, error) {
+ return r.GraphQLProvider.RevokeAccess(ctx, ¶m)
}
// 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)
+func (r *mutationResolver) EnableAccess(ctx context.Context, param model.UpdateAccessRequest) (*model.Response, error) {
+ return r.GraphQLProvider.EnableAccess(ctx, ¶m)
}
// 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)
+func (r *mutationResolver) GenerateJwtKeys(ctx context.Context, params model.GenerateJWTKeysRequest) (*model.GenerateJWTKeysResponse, error) {
+ return nil, fmt.Errorf("deprecated. please configure jwt keys via cli args")
}
// 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)
+ return r.GraphQLProvider.AddWebhook(ctx, ¶ms)
}
// 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)
+ return r.GraphQLProvider.UpdateWebhook(ctx, ¶ms)
}
// 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)
+ return r.GraphQLProvider.DeleteWebhook(ctx, ¶ms)
}
// 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)
+ return r.GraphQLProvider.TestEndpoint(ctx, ¶ms)
}
// 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)
+ return r.GraphQLProvider.AddEmailTemplate(ctx, ¶ms)
}
// 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)
+ return r.GraphQLProvider.UpdateEmailTemplate(ctx, ¶ms)
}
// 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)
+ return r.GraphQLProvider.DeleteEmailTemplate(ctx, ¶ms)
}
// Meta is the resolver for the meta field.
func (r *queryResolver) Meta(ctx context.Context) (*model.Meta, error) {
- return resolvers.MetaResolver(ctx)
+ return r.GraphQLProvider.Meta(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)
+func (r *queryResolver) Session(ctx context.Context, params *model.SessionQueryRequest) (*model.AuthResponse, error) {
+ return r.GraphQLProvider.Session(ctx, params)
}
// Profile is the resolver for the profile field.
func (r *queryResolver) Profile(ctx context.Context) (*model.User, error) {
- return resolvers.ProfileResolver(ctx)
+ return r.GraphQLProvider.Profile(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)
+func (r *queryResolver) ValidateJwtToken(ctx context.Context, params model.ValidateJWTTokenRequest) (*model.ValidateJWTTokenResponse, error) {
+ return r.GraphQLProvider.ValidateJWTToken(ctx, ¶ms)
}
// ValidateSession is the resolver for the validate_session field.
-func (r *queryResolver) ValidateSession(ctx context.Context, params *model.ValidateSessionInput) (*model.ValidateSessionResponse, error) {
- return resolvers.ValidateSessionResolver(ctx, params)
+func (r *queryResolver) ValidateSession(ctx context.Context, params *model.ValidateSessionRequest) (*model.ValidateSessionResponse, error) {
+ return r.GraphQLProvider.ValidateSession(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)
+func (r *queryResolver) Users(ctx context.Context, params *model.PaginatedRequest) (*model.Users, error) {
+ return r.GraphQLProvider.Users(ctx, params)
}
// User is the resolver for the _user field.
func (r *queryResolver) User(ctx context.Context, params model.GetUserRequest) (*model.User, error) {
- return resolvers.UserResolver(ctx, params)
+ return r.GraphQLProvider.User(ctx, ¶ms)
}
// 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)
+func (r *queryResolver) VerificationRequests(ctx context.Context, params *model.PaginatedRequest) (*model.VerificationRequests, error) {
+ return r.GraphQLProvider.VerificationRequests(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)
+ return r.GraphQLProvider.AdminSession(ctx)
}
// Env is the resolver for the _env field.
func (r *queryResolver) Env(ctx context.Context) (*model.Env, error) {
- return resolvers.EnvResolver(ctx)
+ return nil, fmt.Errorf("deprecated. please configure env via cli args")
}
// 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)
+ return r.GraphQLProvider.Webhook(ctx, ¶ms)
}
// 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)
+func (r *queryResolver) Webhooks(ctx context.Context, params *model.PaginatedRequest) (*model.Webhooks, error) {
+ return r.GraphQLProvider.Webhooks(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)
+ return r.GraphQLProvider.WebhookLogs(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)
+func (r *queryResolver) EmailTemplates(ctx context.Context, params *model.PaginatedRequest) (*model.EmailTemplates, error) {
+ return r.GraphQLProvider.EmailTemplates(ctx, params)
}
// Mutation returns generated.MutationResolver implementation.
diff --git a/internal/graphql/_deprecated_admin_signup.go b/internal/graphql/_deprecated_admin_signup.go
new file mode 100644
index 000000000..d7820e219
--- /dev/null
+++ b/internal/graphql/_deprecated_admin_signup.go
@@ -0,0 +1,83 @@
+package graphql
+
+import (
+ "context"
+ "fmt"
+
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+)
+
+// AdminSignup is a resolver for admin signup
+// Permissions: none,
+// Deprecated and admin secret can only be set via cli args
+func (g *graphqlProvider) AdminSignup(ctx context.Context, params *model.AdminSignupInput) (*model.Response, error) {
+ // var res *model.Response
+
+ // gc, err := utils.GinContextFromContext(ctx)
+ // if err != nil {
+ // log.Debug("Failed to get GinContext: ", err)
+ // return res, err
+ // }
+
+ // if strings.TrimSpace(params.AdminSecret) == "" {
+ // log.Debug("Admin secret is empty")
+ // err = fmt.Errorf("please select secure admin secret")
+ // return res, err
+ // }
+
+ // if len(params.AdminSecret) < 6 {
+ // log.Debug("Admin secret is too short")
+ // err = fmt.Errorf("admin secret must be at least 6 characters")
+ // return res, err
+ // }
+
+ // adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
+ // if err != nil {
+ // log.Debug("Error getting admin secret: ", err)
+ // adminSecret = ""
+ // }
+
+ // if adminSecret != "" {
+ // log.Debug("Admin secret is already set")
+ // err = fmt.Errorf("admin sign up already completed")
+ // return res, err
+ // }
+
+ // memorystore.Provider.UpdateEnvVariable(constants.EnvKeyAdminSecret, params.AdminSecret)
+ // // consvert EnvData to JSON
+ // storeData, err := memorystore.Provider.GetEnvStore()
+ // if err != nil {
+ // log.Debug("Error getting env store: ", err)
+ // return res, err
+ // }
+
+ // env, err := db.Provider.GetEnv(ctx)
+ // if err != nil {
+ // log.Debug("Failed to get env: ", err)
+ // return res, err
+ // }
+
+ // envData, err := crypto.EncryptEnvData(storeData)
+ // if err != nil {
+ // log.Debug("Failed to encrypt envstore: ", err)
+ // return res, err
+ // }
+
+ // env.EnvData = envData
+ // if _, err := db.Provider.UpdateEnv(ctx, env); err != nil {
+ // log.Debug("Failed to update env: ", err)
+ // return res, err
+ // }
+
+ // hashedKey, err := crypto.EncryptPassword(params.AdminSecret)
+ // if err != nil {
+ // log.Debug("Failed to encrypt admin session key: ", err)
+ // return res, err
+ // }
+ // cookie.SetAdminCookie(gc, hashedKey)
+
+ // res = &model.Response{
+ // Message: "admin signed up successfully",
+ // }
+ return nil, fmt.Errorf("deprecated. please configure admin secret via cli args")
+}
diff --git a/internal/graphql/_deprecated_env.go b/internal/graphql/_deprecated_env.go
new file mode 100644
index 000000000..40af7d84d
--- /dev/null
+++ b/internal/graphql/_deprecated_env.go
@@ -0,0 +1,15 @@
+package graphql
+
+import (
+ "context"
+ "fmt"
+
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+)
+
+// Env is a resolver for config query
+// Permissions: authorizer:admin
+// Deprecated: this is deprecated
+func (g *graphqlProvider) Env(ctx context.Context) (*model.Env, error) {
+ return nil, fmt.Errorf("deprecated")
+}
diff --git a/internal/graphql/_deprecated_generate_jwt_keys.go b/internal/graphql/_deprecated_generate_jwt_keys.go
new file mode 100644
index 000000000..8af0b5a4c
--- /dev/null
+++ b/internal/graphql/_deprecated_generate_jwt_keys.go
@@ -0,0 +1,67 @@
+package graphql
+
+import (
+ "context"
+ "fmt"
+
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+)
+
+// GenerateJWTKeysResolver mutation to generate new jwt keys
+// Permissions: authorizer:admin
+// Deprecated for
+func (g *graphqlProvider) GenerateJWTKeysResolver(ctx context.Context, params model.GenerateJWTKeysInput) (*model.GenerateJWTKeysResponse, error) {
+ // gc, err := utils.GinContextFromContext(ctx)
+ // if err != nil {
+ // log.Debug("Failed to get GinContext: ", err)
+ // return nil, err
+ // }
+
+ // if !token.IsSuperAdmin(gc) {
+ // log.Debug("Not logged in as super admin")
+ // return nil, fmt.Errorf("unauthorized")
+ // }
+
+ // clientID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyClientID)
+ // if err != nil {
+ // log.Debug("Error getting client id: ", err)
+ // return nil, err
+ // }
+ // if crypto.IsHMACA(params.Type) {
+ // secret, _, err := crypto.NewHMACKey(params.Type, clientID)
+ // if err != nil {
+ // log.Debug("Failed to generate new HMAC key: ", err)
+ // return nil, err
+ // }
+ // return &model.GenerateJWTKeysResponse{
+ // Secret: &secret,
+ // }, nil
+ // }
+
+ // if crypto.IsRSA(params.Type) {
+ // _, privateKey, publicKey, _, err := crypto.NewRSAKey(params.Type, clientID)
+ // if err != nil {
+ // log.Debug("Failed to generate new RSA key: ", err)
+ // return nil, err
+ // }
+ // return &model.GenerateJWTKeysResponse{
+ // PrivateKey: &privateKey,
+ // PublicKey: &publicKey,
+ // }, nil
+ // }
+
+ // if crypto.IsECDSA(params.Type) {
+ // _, privateKey, publicKey, _, err := crypto.NewECDSAKey(params.Type, clientID)
+ // if err != nil {
+ // log.Debug("Failed to generate new ECDSA key: ", err)
+ // return nil, err
+ // }
+ // return &model.GenerateJWTKeysResponse{
+ // PrivateKey: &privateKey,
+ // PublicKey: &publicKey,
+ // }, nil
+ // }
+
+ // log.Debug("Invalid algorithm: ", params.Type)
+ return nil, fmt.Errorf("deprecated")
+}
diff --git a/internal/graphql/_deprecated_mobile_login.go b/internal/graphql/_deprecated_mobile_login.go
new file mode 100644
index 000000000..fe6184cbf
--- /dev/null
+++ b/internal/graphql/_deprecated_mobile_login.go
@@ -0,0 +1,213 @@
+package graphql
+
+import (
+ "context"
+ "fmt"
+
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+)
+
+// MobileLoginResolver is a resolver for mobile login mutation
+func MobileLoginResolver(ctx context.Context, params model.MobileLoginInput) (*model.AuthResponse, error) {
+ // var res *model.AuthResponse
+
+ // gc, err := utils.GinContextFromContext(ctx)
+ // if err != nil {
+ // log.Debug("Failed to get GinContext: ", err)
+ // return res, err
+ // }
+
+ // isBasicAuthDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableMobileBasicAuthentication)
+ // if err != nil {
+ // log.Debug("Error getting mobile basic auth disabled: ", err)
+ // isBasicAuthDisabled = true
+ // }
+
+ // if isBasicAuthDisabled {
+ // log.Debug("Basic authentication is disabled.")
+ // return res, fmt.Errorf(`phone number based basic authentication is disabled for this instance`)
+ // }
+
+ // log := log.WithFields(log.Fields{
+ // "phone_number": params.PhoneNumber,
+ // })
+
+ // user, err := db.Provider.GetUserByPhoneNumber(ctx, params.PhoneNumber)
+ // if err != nil {
+ // log.Debug("Failed to get user by phone number: ", err)
+ // return res, fmt.Errorf(`bad user credentials`)
+ // }
+
+ // if user.RevokedTimestamp != nil {
+ // log.Debug("User access is revoked")
+ // return res, fmt.Errorf(`user access has been revoked`)
+ // }
+
+ // if !strings.Contains(user.SignupMethods, constants.AuthRecipeMethodMobileBasicAuth) {
+ // log.Debug("User signup method is not mobile basic auth")
+ // return res, fmt.Errorf(`user has not signed up with phone number & password`)
+ // }
+
+ // if user.PhoneNumberVerifiedAt == nil {
+ // log.Debug("User phone number is not verified")
+ // return res, fmt.Errorf(`phone number is not verified`)
+ // }
+
+ // err = bcrypt.CompareHashAndPassword([]byte(*user.Password), []byte(params.Password))
+
+ // if err != nil {
+ // log.Debug("Failed to compare password: ", err)
+ // return res, fmt.Errorf(`bad user credentials`)
+ // }
+
+ // defaultRolesString, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyDefaultRoles)
+ // roles := []string{}
+ // if err != nil {
+ // log.Debug("Error getting default roles: ", err)
+ // defaultRolesString = ""
+ // } else {
+ // roles = strings.Split(defaultRolesString, ",")
+ // }
+
+ // currentRoles := strings.Split(user.Roles, ",")
+ // if len(params.Roles) > 0 {
+ // if !validators.IsValidRoles(params.Roles, currentRoles) {
+ // log.Debug("Invalid roles: ", params.Roles)
+ // return res, fmt.Errorf(`invalid roles`)
+ // }
+
+ // roles = params.Roles
+ // }
+
+ // disablePhoneVerification, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisablePhoneVerification)
+ // if err != nil {
+ // log.Debug("Error getting disable phone verification: ", err)
+ // }
+ // if disablePhoneVerification {
+ // now := time.Now().Unix()
+ // user.PhoneNumberVerifiedAt = &now
+ // }
+ // isSMSServiceEnabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyIsSMSServiceEnabled)
+ // if err != nil || !isSMSServiceEnabled {
+ // log.Debug("SMS service not enabled: ", err)
+ // }
+ // if disablePhoneVerification {
+ // now := time.Now().Unix()
+ // user.PhoneNumberVerifiedAt = &now
+ // }
+ // isMFADisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableMultiFactorAuthentication)
+ // if err != nil || !isMFADisabled {
+ // log.Debug("MFA service not enabled: ", err)
+ // }
+ // if !disablePhoneVerification && isSMSServiceEnabled && !isMFADisabled {
+ // duration, _ := time.ParseDuration("10m")
+ // smsCode := utils.GenerateOTP()
+
+ // smsBody := strings.Builder{}
+ // smsBody.WriteString("Your verification code is: ")
+ // smsBody.WriteString(smsCode)
+ // expires := time.Now().Add(duration).Unix()
+ // _, err := db.Provider.UpsertOTP(ctx, &models.OTP{
+ // PhoneNumber: params.PhoneNumber,
+ // Otp: smsCode,
+ // ExpiresAt: expires,
+ // })
+ // if err != nil {
+ // log.Debug("error while upserting OTP: ", err.Error())
+ // return nil, err
+ // }
+
+ // mfaSession := uuid.NewString()
+ // err = memorystore.Provider.SetMfaSession(user.ID, mfaSession, expires)
+ // if err != nil {
+ // log.Debug("Failed to add mfasession: ", err)
+ // return nil, err
+ // }
+ // cookie.SetMfaSession(gc, mfaSession)
+
+ // go func() {
+ // utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, constants.AuthRecipeMethodMobileBasicAuth, user)
+ // smsproviders.SendSMS(params.PhoneNumber, smsBody.String())
+ // }()
+ // return &model.AuthResponse{
+ // Message: "Please check the OTP",
+ // ShouldShowMobileOtpScreen: refs.NewBoolRef(true),
+ // }, nil
+ // }
+
+ // scope := []string{"openid", "email", "profile"}
+ // if params.Scope != nil && len(scope) > 0 {
+ // scope = params.Scope
+ // }
+
+ // code := ""
+ // codeChallenge := ""
+ // nonce := ""
+ // if params.State != nil {
+ // // Get state from store
+ // authorizeState, _ := memorystore.Provider.GetState(refs.StringValue(params.State))
+ // if authorizeState != "" {
+ // authorizeStateSplit := strings.Split(authorizeState, "@@")
+ // if len(authorizeStateSplit) > 1 {
+ // code = authorizeStateSplit[0]
+ // codeChallenge = authorizeStateSplit[1]
+ // } else {
+ // nonce = authorizeState
+ // }
+ // go memorystore.Provider.RemoveState(refs.StringValue(params.State))
+ // }
+ // }
+
+ // if nonce == "" {
+ // nonce = uuid.New().String()
+ // }
+
+ // authToken, err := token.CreateAuthToken(gc, user, roles, scope, constants.AuthRecipeMethodMobileBasicAuth, nonce, code)
+ // if err != nil {
+ // log.Debug("Failed to create auth token", err)
+ // return res, err
+ // }
+
+ // // TODO add to other login options as well
+ // // Code challenge could be optional if PKCE flow is not used
+ // if code != "" {
+ // if err := memorystore.Provider.SetState(code, codeChallenge+"@@"+authToken.FingerPrintHash); err != nil {
+ // log.Debug("SetState failed: ", err)
+ // return res, err
+ // }
+ // }
+
+ // expiresIn := authToken.AccessToken.ExpiresAt - time.Now().Unix()
+ // if expiresIn <= 0 {
+ // expiresIn = 1
+ // }
+
+ // res = &model.AuthResponse{
+ // Message: `Logged in successfully`,
+ // AccessToken: &authToken.AccessToken.Token,
+ // IDToken: &authToken.IDToken.Token,
+ // ExpiresIn: &expiresIn,
+ // User: user.AsAPIUser(),
+ // }
+
+ // cookie.SetSession(gc, authToken.FingerPrintHash)
+ // sessionStoreKey := constants.AuthRecipeMethodMobileBasicAuth + ":" + user.ID
+ // memorystore.Provider.SetUserSession(sessionStoreKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash, authToken.SessionTokenExpiresAt)
+ // memorystore.Provider.SetUserSession(sessionStoreKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token, authToken.AccessToken.ExpiresAt)
+
+ // if authToken.RefreshToken != nil {
+ // res.RefreshToken = &authToken.RefreshToken.Token
+ // memorystore.Provider.SetUserSession(sessionStoreKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token, authToken.RefreshToken.ExpiresAt)
+ // }
+
+ // go func() {
+ // utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, constants.AuthRecipeMethodMobileBasicAuth, user)
+ // db.Provider.AddSession(ctx, &models.Session{
+ // UserID: user.ID,
+ // UserAgent: utils.GetUserAgent(gc.Request),
+ // IP: utils.GetIP(gc.Request),
+ // })
+ // }()
+
+ return nil, fmt.Errorf("deprecated, use login with mobile phone")
+}
diff --git a/internal/graphql/_deprecated_mobile_signup.go b/internal/graphql/_deprecated_mobile_signup.go
new file mode 100644
index 000000000..b5fdcb020
--- /dev/null
+++ b/internal/graphql/_deprecated_mobile_signup.go
@@ -0,0 +1,296 @@
+package graphql
+
+import (
+ "context"
+ "fmt"
+
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+)
+
+// MobileSignupResolver is a resolver for mobile_basic_auth_signup mutation
+func MobileSignupResolver(ctx context.Context, params *model.MobileSignUpInput) (*model.AuthResponse, error) {
+ // var res *model.AuthResponse
+
+ // gc, err := utils.GinContextFromContext(ctx)
+ // if err != nil {
+ // log.Debug("Failed to get GinContext: ", err)
+ // return res, err
+ // }
+
+ // isSignupDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableSignUp)
+ // if err != nil {
+ // log.Debug("Error getting signup disabled: ", err)
+ // isSignupDisabled = true
+ // }
+ // if isSignupDisabled {
+ // log.Debug("Signup is disabled")
+ // return res, fmt.Errorf(`signup is disabled for this instance`)
+ // }
+
+ // isBasicAuthDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableMobileBasicAuthentication)
+ // if err != nil {
+ // log.Debug("Error getting basic auth disabled: ", err)
+ // isBasicAuthDisabled = true
+ // }
+
+ // if isBasicAuthDisabled {
+ // log.Debug("Mobile based Basic authentication is disabled")
+ // return res, fmt.Errorf(`phone number based basic authentication is disabled for this instance`)
+ // }
+
+ // if params.ConfirmPassword != params.Password {
+ // log.Debug("Passwords do not match")
+ // return res, fmt.Errorf(`password and confirm password does not match`)
+ // }
+
+ // if err := validators.IsValidPassword(params.Password); err != nil {
+ // log.Debug("Invalid password")
+ // return res, err
+ // }
+
+ // mobile := strings.TrimSpace(params.PhoneNumber)
+ // if mobile == "" || len(mobile) < 10 {
+ // log.Debug("Invalid phone number")
+ // return res, fmt.Errorf("invalid phone number")
+ // }
+
+ // emailInput := strings.ToLower(strings.TrimSpace(refs.StringValue(params.Email)))
+
+ // // if email is null set random dummy email for db constraint
+
+ // if emailInput != "" && !validators.IsValidEmail(emailInput) {
+ // log.Debug("Invalid email: ", emailInput)
+ // return res, fmt.Errorf(`invalid email address`)
+ // }
+
+ // if emailInput == "" {
+ // emailInput = mobile + "@authorizer.dev"
+ // }
+
+ // log := log.WithFields(log.Fields{
+ // "email": emailInput,
+ // "phone_number": mobile,
+ // })
+ // // find user with email
+ // existingUser, err := db.Provider.GetUserByPhoneNumber(ctx, mobile)
+ // if err != nil {
+ // log.Debug("Failed to get user by email: ", err)
+ // }
+ // if existingUser != nil {
+ // if existingUser.PhoneNumberVerifiedAt != nil {
+ // // email is verified
+ // log.Debug("Phone number is already verified and signed up.")
+ // return res, fmt.Errorf(`%s has already signed up`, mobile)
+ // } else if existingUser.ID != "" && existingUser.PhoneNumberVerifiedAt == nil {
+ // log.Debug("Phone number is already signed up. Verification pending...")
+ // return res, fmt.Errorf("%s has already signed up. please complete the phone number verification process or reset the password", mobile)
+ // }
+ // }
+
+ // inputRoles := []string{}
+ // if len(params.Roles) > 0 {
+ // // check if roles exists
+ // rolesString, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyRoles)
+ // roles := []string{}
+ // if err != nil {
+ // log.Debug("Error getting roles: ", err)
+ // return res, err
+ // } else {
+ // roles = strings.Split(rolesString, ",")
+ // }
+ // if !validators.IsValidRoles(params.Roles, roles) {
+ // log.Debug("Invalid roles: ", params.Roles)
+ // return res, fmt.Errorf(`invalid roles`)
+ // } else {
+ // inputRoles = params.Roles
+ // }
+ // } else {
+ // inputRolesString, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyDefaultRoles)
+ // if err != nil {
+ // log.Debug("Error getting default roles: ", err)
+ // return res, err
+ // } else {
+ // inputRoles = strings.Split(inputRolesString, ",")
+ // }
+ // }
+
+ // user := &models.User{
+ // Email: &emailInput,
+ // PhoneNumber: &mobile,
+ // }
+
+ // user.Roles = strings.Join(inputRoles, ",")
+
+ // password, _ := crypto.EncryptPassword(params.Password)
+ // user.Password = &password
+
+ // if params.GivenName != nil {
+ // user.GivenName = params.GivenName
+ // }
+
+ // if params.FamilyName != nil {
+ // user.FamilyName = params.FamilyName
+ // }
+
+ // if params.MiddleName != nil {
+ // user.MiddleName = params.MiddleName
+ // }
+
+ // if params.Nickname != nil {
+ // user.Nickname = params.Nickname
+ // }
+
+ // if params.Gender != nil {
+ // user.Gender = params.Gender
+ // }
+
+ // if params.Birthdate != nil {
+ // user.Birthdate = params.Birthdate
+ // }
+
+ // if params.Picture != nil {
+ // user.Picture = params.Picture
+ // }
+
+ // if params.IsMultiFactorAuthEnabled != nil {
+ // user.IsMultiFactorAuthEnabled = params.IsMultiFactorAuthEnabled
+ // }
+
+ // isMFAEnforced, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyEnforceMultiFactorAuthentication)
+ // if err != nil {
+ // log.Debug("MFA service not enabled: ", err)
+ // isMFAEnforced = false
+ // }
+
+ // if isMFAEnforced {
+ // user.IsMultiFactorAuthEnabled = refs.NewBoolRef(true)
+ // }
+
+ // disablePhoneVerification, _ := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisablePhoneVerification)
+ // if disablePhoneVerification {
+ // now := time.Now().Unix()
+ // user.PhoneNumberVerifiedAt = &now
+ // }
+ // isSMSServiceEnabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyIsSMSServiceEnabled)
+ // if err != nil || !isSMSServiceEnabled {
+ // log.Debug("SMS service not enabled: ", err)
+ // }
+
+ // user.SignupMethods = constants.AuthRecipeMethodMobileBasicAuth
+ // user, err = db.Provider.AddUser(ctx, user)
+
+ // if err != nil {
+ // log.Debug("Failed to add user: ", err)
+ // return res, err
+ // }
+ // if !disablePhoneVerification && isSMSServiceEnabled {
+ // duration, _ := time.ParseDuration("10m")
+ // smsCode := utils.GenerateOTP()
+
+ // smsBody := strings.Builder{}
+ // smsBody.WriteString("Your verification code is: ")
+ // smsBody.WriteString(smsCode)
+
+ // // TODO: For those who enabled the webhook to call their sms vendor separately - sending the otp to their api
+ // if err != nil {
+ // log.Debug("error while upserting user: ", err.Error())
+ // return nil, err
+ // }
+ // _, err = db.Provider.UpsertOTP(ctx, &models.OTP{
+ // PhoneNumber: mobile,
+ // Otp: smsCode,
+ // ExpiresAt: time.Now().Add(duration).Unix(),
+ // })
+ // if err != nil {
+ // log.Debug("error while upserting OTP: ", err.Error())
+ // return nil, err
+ // }
+ // go func() {
+ // smsproviders.SendSMS(mobile, smsBody.String())
+ // utils.RegisterEvent(ctx, constants.UserCreatedWebhookEvent, constants.AuthRecipeMethodBasicAuth, user)
+ // }()
+ // return &model.AuthResponse{
+ // Message: "Please check the OTP in your inbox",
+ // ShouldShowMobileOtpScreen: refs.NewBoolRef(true),
+ // }, nil
+ // }
+
+ // roles := strings.Split(user.Roles, ",")
+ // userToReturn := user.AsAPIUser()
+
+ // scope := []string{"openid", "email", "profile"}
+ // if params.Scope != nil && len(scope) > 0 {
+ // scope = params.Scope
+ // }
+
+ // code := ""
+ // codeChallenge := ""
+ // nonce := ""
+ // if params.State != nil {
+ // // Get state from store
+ // authorizeState, _ := memorystore.Provider.GetState(refs.StringValue(params.State))
+ // if authorizeState != "" {
+ // authorizeStateSplit := strings.Split(authorizeState, "@@")
+ // if len(authorizeStateSplit) > 1 {
+ // code = authorizeStateSplit[0]
+ // codeChallenge = authorizeStateSplit[1]
+ // } else {
+ // nonce = authorizeState
+ // }
+ // go memorystore.Provider.RemoveState(refs.StringValue(params.State))
+ // }
+ // }
+
+ // if nonce == "" {
+ // nonce = uuid.New().String()
+ // }
+
+ // authToken, err := token.CreateAuthToken(gc, user, roles, scope, constants.AuthRecipeMethodMobileBasicAuth, nonce, code)
+ // if err != nil {
+ // log.Debug("Failed to create auth token: ", err)
+ // return res, err
+ // }
+
+ // // Code challenge could be optional if PKCE flow is not used
+ // if code != "" {
+ // if err := memorystore.Provider.SetState(code, codeChallenge+"@@"+authToken.FingerPrintHash); err != nil {
+ // log.Debug("SetState failed: ", err)
+ // return res, err
+ // }
+ // }
+
+ // expiresIn := authToken.AccessToken.ExpiresAt - time.Now().Unix()
+ // if expiresIn <= 0 {
+ // expiresIn = 1
+ // }
+
+ // res = &model.AuthResponse{
+ // Message: `Signed up successfully.`,
+ // AccessToken: &authToken.AccessToken.Token,
+ // ExpiresIn: &expiresIn,
+ // User: userToReturn,
+ // }
+
+ // sessionKey := constants.AuthRecipeMethodMobileBasicAuth + ":" + user.ID
+ // cookie.SetSession(gc, authToken.FingerPrintHash)
+ // memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash, authToken.SessionTokenExpiresAt)
+ // memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token, authToken.AccessToken.ExpiresAt)
+
+ // if authToken.RefreshToken != nil {
+ // res.RefreshToken = &authToken.RefreshToken.Token
+ // memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token, authToken.RefreshToken.ExpiresAt)
+ // }
+
+ // go func() {
+ // utils.RegisterEvent(ctx, constants.UserSignUpWebhookEvent, constants.AuthRecipeMethodMobileBasicAuth, user)
+ // // User is also logged in with signup
+ // utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, constants.AuthRecipeMethodMobileBasicAuth, user)
+ // db.Provider.AddSession(ctx, &models.Session{
+ // UserID: user.ID,
+ // UserAgent: utils.GetUserAgent(gc.Request),
+ // IP: utils.GetIP(gc.Request),
+ // })
+ // }()
+
+ return nil, fmt.Errorf("deprecated, use signup with mobile phone")
+}
diff --git a/internal/graphql/_deprecated_update_env.go b/internal/graphql/_deprecated_update_env.go
new file mode 100644
index 000000000..9e4a0f729
--- /dev/null
+++ b/internal/graphql/_deprecated_update_env.go
@@ -0,0 +1,429 @@
+package graphql
+
+import (
+ "context"
+ "fmt"
+ "strings"
+ "time"
+
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/db"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/memorystore"
+ "github.com/authorizerdev/authorizer/internal/utils"
+)
+
+// check if login methods have been disabled
+// remove the session tokens for those methods
+// TODO: run on start up of service
+func clearSessionIfRequired(currentData, updatedData map[string]interface{}) {
+ isCurrentBasicAuthEnabled := !currentData[constants.EnvKeyDisableBasicAuthentication].(bool)
+ isCurrentMobileBasicAuthEnabled := !currentData[constants.EnvKeyDisableMobileBasicAuthentication].(bool)
+ isCurrentMagicLinkLoginEnabled := !currentData[constants.EnvKeyDisableMagicLinkLogin].(bool)
+ isCurrentAppleLoginEnabled := currentData[constants.EnvKeyAppleClientID] != nil && currentData[constants.EnvKeyAppleClientSecret] != nil && currentData[constants.EnvKeyAppleClientID].(string) != "" && currentData[constants.EnvKeyAppleClientSecret].(string) != ""
+ isCurrentFacebookLoginEnabled := currentData[constants.EnvKeyFacebookClientID] != nil && currentData[constants.EnvKeyFacebookClientSecret] != nil && currentData[constants.EnvKeyFacebookClientID].(string) != "" && currentData[constants.EnvKeyFacebookClientSecret].(string) != ""
+ isCurrentGoogleLoginEnabled := currentData[constants.EnvKeyGoogleClientID] != nil && currentData[constants.EnvKeyGoogleClientSecret] != nil && currentData[constants.EnvKeyGoogleClientID].(string) != "" && currentData[constants.EnvKeyGoogleClientSecret].(string) != ""
+ isCurrentGithubLoginEnabled := currentData[constants.EnvKeyGithubClientID] != nil && currentData[constants.EnvKeyGithubClientSecret] != nil && currentData[constants.EnvKeyGithubClientID].(string) != "" && currentData[constants.EnvKeyGithubClientSecret].(string) != ""
+ isCurrentLinkedInLoginEnabled := currentData[constants.EnvKeyLinkedInClientID] != nil && currentData[constants.EnvKeyLinkedInClientSecret] != nil && currentData[constants.EnvKeyLinkedInClientID].(string) != "" && currentData[constants.EnvKeyLinkedInClientSecret].(string) != ""
+ isCurrentTwitterLoginEnabled := currentData[constants.EnvKeyTwitterClientID] != nil && currentData[constants.EnvKeyTwitterClientSecret] != nil && currentData[constants.EnvKeyTwitterClientID].(string) != "" && currentData[constants.EnvKeyTwitterClientSecret].(string) != ""
+ isCurrentMicrosoftLoginEnabled := currentData[constants.EnvKeyMicrosoftClientID] != nil && currentData[constants.EnvKeyMicrosoftClientSecret] != nil && currentData[constants.EnvKeyMicrosoftClientID].(string) != "" && currentData[constants.EnvKeyMicrosoftClientSecret].(string) != ""
+ isCurrentTwitchLoginEnabled := currentData[constants.EnvKeyTwitchClientID] != nil && currentData[constants.EnvKeyTwitchClientSecret] != nil && currentData[constants.EnvKeyTwitchClientID].(string) != "" && currentData[constants.EnvKeyTwitchClientSecret].(string) != ""
+
+ isUpdatedBasicAuthEnabled := !updatedData[constants.EnvKeyDisableBasicAuthentication].(bool)
+ isUpdatedMobileBasicAuthEnabled := !updatedData[constants.EnvKeyDisableMobileBasicAuthentication].(bool)
+ isUpdatedMagicLinkLoginEnabled := !updatedData[constants.EnvKeyDisableMagicLinkLogin].(bool)
+ isUpdatedAppleLoginEnabled := updatedData[constants.EnvKeyAppleClientID] != nil && updatedData[constants.EnvKeyAppleClientSecret] != nil && updatedData[constants.EnvKeyAppleClientID].(string) != "" && updatedData[constants.EnvKeyAppleClientSecret].(string) != ""
+ isUpdatedFacebookLoginEnabled := updatedData[constants.EnvKeyFacebookClientID] != nil && updatedData[constants.EnvKeyFacebookClientSecret] != nil && updatedData[constants.EnvKeyFacebookClientID].(string) != "" && updatedData[constants.EnvKeyFacebookClientSecret].(string) != ""
+ isUpdatedGoogleLoginEnabled := updatedData[constants.EnvKeyGoogleClientID] != nil && updatedData[constants.EnvKeyGoogleClientSecret] != nil && updatedData[constants.EnvKeyGoogleClientID].(string) != "" && updatedData[constants.EnvKeyGoogleClientSecret].(string) != ""
+ isUpdatedGithubLoginEnabled := updatedData[constants.EnvKeyGithubClientID] != nil && updatedData[constants.EnvKeyGithubClientSecret] != nil && updatedData[constants.EnvKeyGithubClientID].(string) != "" && updatedData[constants.EnvKeyGithubClientSecret].(string) != ""
+ isUpdatedLinkedInLoginEnabled := updatedData[constants.EnvKeyLinkedInClientID] != nil && updatedData[constants.EnvKeyLinkedInClientSecret] != nil && updatedData[constants.EnvKeyLinkedInClientID].(string) != "" && updatedData[constants.EnvKeyLinkedInClientSecret].(string) != ""
+ isUpdatedTwitterLoginEnabled := updatedData[constants.EnvKeyTwitterClientID] != nil && updatedData[constants.EnvKeyTwitterClientSecret] != nil && updatedData[constants.EnvKeyTwitterClientID].(string) != "" && updatedData[constants.EnvKeyTwitterClientSecret].(string) != ""
+ isUpdatedMicrosoftLoginEnabled := updatedData[constants.EnvKeyMicrosoftClientID] != nil && updatedData[constants.EnvKeyMicrosoftClientSecret] != nil && updatedData[constants.EnvKeyMicrosoftClientID].(string) != "" && updatedData[constants.EnvKeyMicrosoftClientSecret].(string) != ""
+ isUpdatedTwitchLoginEnabled := updatedData[constants.EnvKeyTwitchClientID] != nil && updatedData[constants.EnvKeyTwitchClientSecret] != nil && updatedData[constants.EnvKeyTwitchClientID].(string) != "" && updatedData[constants.EnvKeyTwitchClientSecret].(string) != ""
+
+ if isCurrentBasicAuthEnabled && !isUpdatedBasicAuthEnabled {
+ memorystore.Provider.DeleteSessionForNamespace(constants.AuthRecipeMethodBasicAuth)
+ }
+
+ if isCurrentMobileBasicAuthEnabled && !isUpdatedMobileBasicAuthEnabled {
+ memorystore.Provider.DeleteSessionForNamespace(constants.AuthRecipeMethodMobileBasicAuth)
+ }
+
+ if isCurrentMagicLinkLoginEnabled && !isUpdatedMagicLinkLoginEnabled {
+ memorystore.Provider.DeleteSessionForNamespace(constants.AuthRecipeMethodMagicLinkLogin)
+ }
+
+ if isCurrentAppleLoginEnabled && !isUpdatedAppleLoginEnabled {
+ memorystore.Provider.DeleteSessionForNamespace(constants.AuthRecipeMethodApple)
+ }
+
+ if isCurrentFacebookLoginEnabled && !isUpdatedFacebookLoginEnabled {
+ memorystore.Provider.DeleteSessionForNamespace(constants.AuthRecipeMethodFacebook)
+ }
+
+ if isCurrentGoogleLoginEnabled && !isUpdatedGoogleLoginEnabled {
+ memorystore.Provider.DeleteSessionForNamespace(constants.AuthRecipeMethodGoogle)
+ }
+
+ if isCurrentGithubLoginEnabled && !isUpdatedGithubLoginEnabled {
+ memorystore.Provider.DeleteSessionForNamespace(constants.AuthRecipeMethodGithub)
+ }
+
+ if isCurrentLinkedInLoginEnabled && !isUpdatedLinkedInLoginEnabled {
+ memorystore.Provider.DeleteSessionForNamespace(constants.AuthRecipeMethodLinkedIn)
+ }
+
+ if isCurrentTwitterLoginEnabled && !isUpdatedTwitterLoginEnabled {
+ memorystore.Provider.DeleteSessionForNamespace(constants.AuthRecipeMethodTwitter)
+ }
+
+ if isCurrentMicrosoftLoginEnabled && !isUpdatedMicrosoftLoginEnabled {
+ memorystore.Provider.DeleteSessionForNamespace(constants.AuthRecipeMethodMicrosoft)
+ }
+
+ if isCurrentTwitchLoginEnabled && !isUpdatedTwitchLoginEnabled {
+ memorystore.Provider.DeleteSessionForNamespace(constants.AuthRecipeMethodTwitch)
+ }
+}
+
+// updateRoles will update DB for user roles, if a role is deleted by admin
+// then this function will those roles from user roles if exists
+// TODO: run on start up of service
+func updateRoles(ctx context.Context, deletedRoles []string) error {
+ data, err := db.Provider.ListUsers(ctx, &model.Pagination{
+ Limit: 1,
+ Offset: 1,
+ })
+ if err != nil {
+ return err
+ }
+
+ allData, err := db.Provider.ListUsers(ctx, &model.Pagination{
+ Limit: data.Pagination.Total,
+ })
+ if err != nil {
+ return err
+ }
+
+ chunkSize := 1000
+ totalUsers := len(allData.Users)
+
+ for start := 0; start < totalUsers; start += chunkSize {
+ end := start + chunkSize
+ if end > totalUsers {
+ end = totalUsers
+ }
+
+ chunkUsers := allData.Users[start:end]
+
+ for i := range chunkUsers {
+ roles := utils.DeleteFromArray(chunkUsers[i].Roles, deletedRoles)
+ if len(chunkUsers[i].Roles) != len(roles) {
+ updatedValues := map[string]interface{}{
+ "roles": strings.Join(roles, ","),
+ "updated_at": time.Now().Unix(),
+ }
+ id := []string{chunkUsers[i].ID}
+ err = db.Provider.UpdateUsers(ctx, updatedValues, id)
+ if err != nil {
+ return err
+ }
+ }
+ }
+ }
+ return nil
+}
+
+// UpdateEnvResolver is a resolver for update config mutation
+// This is admin only mutation
+func UpdateEnvResolver(ctx context.Context, params model.UpdateEnvInput) (*model.Response, error) {
+ // var res *model.Response
+
+ // gc, err := utils.GinContextFromContext(ctx)
+ // if err != nil {
+ // log.Debug("Failed to get GinContext: ", err)
+ // return res, err
+ // }
+
+ // if !token.IsSuperAdmin(gc) {
+ // log.Debug("Not logged in as super admin")
+ // return res, fmt.Errorf("unauthorized")
+ // }
+
+ // currentData, err := memorystore.Provider.GetEnvStore()
+ // if err != nil {
+ // log.Debug("Failed to get env store: ", err)
+ // return res, err
+ // }
+
+ // // clone currentData in new var
+ // // that will be updated based on the req
+ // updatedData := make(map[string]interface{})
+ // for key, val := range currentData {
+ // updatedData[key] = val
+ // }
+
+ // isJWTUpdated := false
+ // algo := updatedData[constants.EnvKeyJwtType].(string)
+ // if params.JwtType != nil {
+ // algo = *params.JwtType
+ // if !crypto.IsHMACA(algo) && !crypto.IsECDSA(algo) && !crypto.IsRSA(algo) {
+ // log.Debug("Invalid JWT type: ", algo)
+ // return res, fmt.Errorf("invalid jwt type")
+ // }
+
+ // updatedData[constants.EnvKeyJwtType] = algo
+ // isJWTUpdated = true
+ // }
+
+ // if params.JwtSecret != nil || params.JwtPublicKey != nil || params.JwtPrivateKey != nil {
+ // isJWTUpdated = true
+ // }
+
+ // if isJWTUpdated {
+ // // use to reset when type is changed from rsa, edsa -> hmac or vice a versa
+ // defaultSecret := ""
+ // defaultPublicKey := ""
+ // defaultPrivateKey := ""
+ // // check if jwt secret is provided
+ // if crypto.IsHMACA(algo) {
+ // if params.JwtSecret == nil {
+ // log.Debug("JWT secret is required for HMAC")
+ // return res, fmt.Errorf("jwt secret is required for HMAC algorithm")
+ // }
+
+ // // reset public key and private key
+ // params.JwtPrivateKey = &defaultPrivateKey
+ // params.JwtPublicKey = &defaultPublicKey
+ // }
+
+ // if crypto.IsRSA(algo) {
+ // if params.JwtPrivateKey == nil || params.JwtPublicKey == nil {
+ // log.Debug("JWT private key and public key are required for RSA: ", *params.JwtPrivateKey, *params.JwtPublicKey)
+ // return res, fmt.Errorf("jwt private and public key is required for RSA (PKCS1) / ECDSA algorithm")
+ // }
+
+ // // reset the jwt secret
+ // params.JwtSecret = &defaultSecret
+ // _, err = crypto.ParseRsaPrivateKeyFromPemStr(*params.JwtPrivateKey)
+ // if err != nil {
+ // log.Debug("Invalid JWT private key: ", err)
+ // return res, err
+ // }
+
+ // _, err := crypto.ParseRsaPublicKeyFromPemStr(*params.JwtPublicKey)
+ // if err != nil {
+ // log.Debug("Invalid JWT public key: ", err)
+ // return res, err
+ // }
+ // }
+
+ // if crypto.IsECDSA(algo) {
+ // if params.JwtPrivateKey == nil || params.JwtPublicKey == nil {
+ // log.Debug("JWT private key and public key are required for ECDSA: ", *params.JwtPrivateKey, *params.JwtPublicKey)
+ // return res, fmt.Errorf("jwt private and public key is required for RSA (PKCS1) / ECDSA algorithm")
+ // }
+
+ // // reset the jwt secret
+ // params.JwtSecret = &defaultSecret
+ // _, err = crypto.ParseEcdsaPrivateKeyFromPemStr(*params.JwtPrivateKey)
+ // if err != nil {
+ // log.Debug("Invalid JWT private key: ", err)
+ // return res, err
+ // }
+
+ // _, err := crypto.ParseEcdsaPublicKeyFromPemStr(*params.JwtPublicKey)
+ // if err != nil {
+ // log.Debug("Invalid JWT public key: ", err)
+ // return res, err
+ // }
+ // }
+
+ // }
+
+ // var data map[string]interface{}
+ // byteData, err := json.Marshal(params)
+ // if err != nil {
+ // log.Debug("Failed to marshal update env input: ", err)
+ // return res, fmt.Errorf("error marshalling params: %t", err)
+ // }
+
+ // err = json.Unmarshal(byteData, &data)
+ // if err != nil {
+ // log.Debug("Failed to unmarshal update env input: ", err)
+ // return res, fmt.Errorf("error un-marshalling params: %t", err)
+ // }
+
+ // // in case of admin secret change update the cookie with new hash
+ // if params.AdminSecret != nil {
+ // if params.OldAdminSecret == nil {
+ // log.Debug("Old admin secret is required for admin secret update")
+ // return res, errors.New("admin secret and old admin secret are required for secret change")
+ // }
+ // oldAdminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
+ // if err != nil {
+ // log.Debug("Failed to get old admin secret: ", err)
+ // return res, err
+ // }
+ // if *params.OldAdminSecret != oldAdminSecret {
+ // log.Debug("Old admin secret is invalid")
+ // return res, errors.New("old admin secret is not correct")
+ // }
+
+ // if len(*params.AdminSecret) < 6 {
+ // log.Debug("Admin secret is too short")
+ // err = fmt.Errorf("admin secret must be at least 6 characters")
+ // return res, err
+ // }
+
+ // }
+
+ // for key, value := range data {
+ // if value != nil {
+ // fieldType := reflect.TypeOf(value).String()
+
+ // if fieldType == "string" {
+ // updatedData[key] = value.(string)
+ // }
+
+ // if fieldType == "bool" {
+ // updatedData[key] = value.(bool)
+ // }
+ // if fieldType == "[]interface {}" {
+ // stringArr := utils.ConvertInterfaceToStringSlice(value)
+ // updatedData[key] = strings.Join(stringArr, ",")
+ // }
+ // }
+ // }
+
+ // // handle derivative cases like disabling email verification & magic login
+ // // in case SMTP is off but env is set to true
+ // if updatedData[constants.EnvKeySmtpHost] == "" || updatedData[constants.EnvKeySmtpUsername] == "" || updatedData[constants.EnvKeySmtpPassword] == "" || updatedData[constants.EnvKeySenderEmail] == "" && updatedData[constants.EnvKeySmtpPort] == "" {
+ // updatedData[constants.EnvKeyIsEmailServiceEnabled] = false
+ // if !updatedData[constants.EnvKeyDisableEmailVerification].(bool) {
+ // updatedData[constants.EnvKeyDisableEmailVerification] = true
+ // }
+ // if !updatedData[constants.EnvKeyDisableMailOTPLogin].(bool) {
+ // updatedData[constants.EnvKeyDisableMailOTPLogin] = true
+ // }
+ // if !updatedData[constants.EnvKeyDisableMagicLinkLogin].(bool) {
+ // updatedData[constants.EnvKeyDisableMailOTPLogin] = true
+ // }
+ // }
+
+ // if updatedData[constants.EnvKeySmtpHost] != "" || updatedData[constants.EnvKeySmtpUsername] != "" || updatedData[constants.EnvKeySmtpPassword] != "" || updatedData[constants.EnvKeySenderEmail] != "" && updatedData[constants.EnvKeySmtpPort] != "" {
+ // updatedData[constants.EnvKeyIsEmailServiceEnabled] = true
+ // }
+
+ // if updatedData[constants.EnvKeyTwilioAPIKey] == "" || updatedData[constants.EnvKeyTwilioAPISecret] == "" || updatedData[constants.EnvKeyTwilioAccountSID] == "" || updatedData[constants.EnvKeyTwilioSender] == "" {
+ // updatedData[constants.EnvKeyIsSMSServiceEnabled] = false
+ // if !updatedData[constants.EnvKeyIsSMSServiceEnabled].(bool) {
+ // updatedData[constants.EnvKeyDisablePhoneVerification] = true
+ // }
+ // }
+
+ // if updatedData[constants.EnvKeyDisableMultiFactorAuthentication].(bool) && updatedData[constants.EnvKeyIsEmailServiceEnabled].(bool) {
+ // updatedData[constants.EnvKeyDisableMailOTPLogin] = true
+ // }
+
+ // if !currentData[constants.EnvKeyEnforceMultiFactorAuthentication].(bool) && updatedData[constants.EnvKeyEnforceMultiFactorAuthentication].(bool) && !updatedData[constants.EnvKeyDisableMultiFactorAuthentication].(bool) {
+ // go db.Provider.UpdateUsers(ctx, map[string]interface{}{
+ // "is_multi_factor_auth_enabled": true,
+ // }, nil)
+ // }
+
+ // previousRoles := strings.Split(currentData[constants.EnvKeyRoles].(string), ",")
+ // previousProtectedRoles := strings.Split(currentData[constants.EnvKeyProtectedRoles].(string), ",")
+ // updatedRoles := strings.Split(updatedData[constants.EnvKeyRoles].(string), ",")
+ // updatedDefaultRoles := strings.Split(updatedData[constants.EnvKeyDefaultRoles].(string), ",")
+ // updatedProtectedRoles := strings.Split(updatedData[constants.EnvKeyProtectedRoles].(string), ",")
+ // // check the roles change
+ // if len(updatedRoles) > 0 && len(updatedDefaultRoles) > 0 {
+ // // should be subset of roles
+ // for _, role := range updatedDefaultRoles {
+ // if !utils.StringSliceContains(updatedRoles, role) {
+ // log.Debug("Default roles should be subset of roles")
+ // return res, fmt.Errorf("default role %s is not in roles", role)
+ // }
+ // }
+ // }
+
+ // if len(updatedProtectedRoles) > 0 {
+ // for _, role := range updatedProtectedRoles {
+ // if utils.StringSliceContains(updatedRoles, role) || utils.StringSliceContains(updatedDefaultRoles, role) {
+ // log.Debug("Protected roles should not be in roles or default roles")
+ // return res, fmt.Errorf("protected role %s found roles or default roles", role)
+ // }
+ // }
+ // }
+
+ // deletedRoles := utils.FindDeletedValues(previousRoles, updatedRoles)
+ // if len(deletedRoles) > 0 {
+ // go updateRoles(ctx, deletedRoles)
+ // }
+
+ // deletedProtectedRoles := utils.FindDeletedValues(previousProtectedRoles, updatedProtectedRoles)
+ // if len(deletedProtectedRoles) > 0 {
+ // go updateRoles(ctx, deletedProtectedRoles)
+ // }
+
+ // // Update local store
+ // memorystore.Provider.UpdateEnvStore(updatedData)
+ // jwk, err := crypto.GenerateJWKBasedOnEnv()
+ // if err != nil {
+ // log.Debug("Failed to generate JWK: ", err)
+ // return res, err
+ // }
+ // // updating jwk
+ // err = memorystore.Provider.UpdateEnvVariable(constants.EnvKeyJWK, jwk)
+ // if err != nil {
+ // log.Debug("Failed to update JWK: ", err)
+ // return res, err
+ // }
+
+ // err = oauth.InitOAuth()
+ // if err != nil {
+ // return res, err
+ // }
+
+ // // Fetch the current db store and update it
+ // env, err := db.Provider.GetEnv(ctx)
+ // if err != nil {
+ // log.Debug("Failed to get env: ", err)
+ // return res, err
+ // }
+
+ // if params.AdminSecret != nil {
+ // adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
+ // if err != nil {
+ // log.Debug("Failed to get admin secret: ", err)
+ // return res, err
+ // }
+ // hashedKey, err := crypto.EncryptPassword(adminSecret)
+ // if err != nil {
+ // log.Debug("Failed to encrypt admin secret: ", err)
+ // return res, err
+ // }
+ // cookie.SetAdminCookie(gc, hashedKey)
+ // }
+
+ // encryptedConfig, err := crypto.EncryptEnvData(updatedData)
+ // if err != nil {
+ // log.Debug("Failed to encrypt env data: ", err)
+ // return res, err
+ // }
+
+ // env.EnvData = encryptedConfig
+ // _, err = db.Provider.UpdateEnv(ctx, env)
+ // if err != nil {
+ // log.Debug("Failed to update env: ", err)
+ // return res, err
+ // }
+
+ // go clearSessionIfRequired(currentData, updatedData)
+
+ // res = &model.Response{
+ // Message: "configurations updated successfully",
+ // }
+ return nil, fmt.Errorf("deprecated")
+}
diff --git a/internal/graphql/add_email_template.go b/internal/graphql/add_email_template.go
new file mode 100644
index 000000000..e487a007f
--- /dev/null
+++ b/internal/graphql/add_email_template.go
@@ -0,0 +1,64 @@
+package graphql
+
+import (
+ "context"
+ "fmt"
+ "strings"
+
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/refs"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
+ "github.com/authorizerdev/authorizer/internal/utils"
+ "github.com/authorizerdev/authorizer/internal/validators"
+)
+
+// AddEmailTemplate is the method to add email template.
+// Permissions: authorizer:admin
+func (g *graphqlProvider) AddEmailTemplate(ctx context.Context, params *model.AddEmailTemplateRequest) (*model.Response, error) {
+ log := g.Log.With().Str("func", "AddEmailTemplate").Logger()
+ gc, err := utils.GinContextFromContext(ctx)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get GinContext")
+ return nil, err
+ }
+ if !g.TokenProvider.IsSuperAdmin(gc) {
+ log.Debug().Msg("Not logged in as super admin")
+ return nil, fmt.Errorf("unauthorized")
+ }
+
+ if !validators.IsValidEmailTemplateEventName(params.EventName) {
+ log.Debug().Str("EventName", params.EventName).Msg("Invalid Event Name")
+ return nil, fmt.Errorf("invalid event name %s", params.EventName)
+ }
+
+ if strings.TrimSpace(params.Subject) == "" {
+ log.Debug().Msg("subject is missing")
+ return nil, fmt.Errorf("empty subject not allowed")
+ }
+
+ if strings.TrimSpace(params.Template) == "" {
+ log.Debug().Msg("template is missing")
+ return nil, fmt.Errorf("empty template not allowed")
+ }
+
+ var design string
+
+ if params.Design == nil || strings.TrimSpace(refs.StringValue(params.Design)) == "" {
+ design = ""
+ }
+
+ _, err = g.StorageProvider.AddEmailTemplate(ctx, &schemas.EmailTemplate{
+ EventName: params.EventName,
+ Template: params.Template,
+ Subject: params.Subject,
+ Design: design,
+ })
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to add email template in db")
+ return nil, err
+ }
+
+ return &model.Response{
+ Message: `Email template added successfully`,
+ }, nil
+}
diff --git a/server/resolvers/add_webhook.go b/internal/graphql/add_webhook.go
similarity index 51%
rename from server/resolvers/add_webhook.go
rename to internal/graphql/add_webhook.go
index 3380779e9..a92af1f15 100644
--- a/server/resolvers/add_webhook.go
+++ b/internal/graphql/add_webhook.go
@@ -1,4 +1,4 @@
-package resolvers
+package graphql
import (
"context"
@@ -6,33 +6,32 @@ import (
"fmt"
"strings"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/db/models"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/refs"
- "github.com/authorizerdev/authorizer/server/token"
- "github.com/authorizerdev/authorizer/server/utils"
- "github.com/authorizerdev/authorizer/server/validators"
- log "github.com/sirupsen/logrus"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/refs"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
+ "github.com/authorizerdev/authorizer/internal/utils"
+ "github.com/authorizerdev/authorizer/internal/validators"
)
-// AddWebhookResolver resolver for add webhook mutation
-func AddWebhookResolver(ctx context.Context, params model.AddWebhookRequest) (*model.Response, error) {
+// AddWebhook is the method to add webhook.
+// Permissions: authorizer:admin
+func (g *graphqlProvider) AddWebhook(ctx context.Context, params *model.AddWebhookRequest) (*model.Response, error) {
+ log := g.Log.With().Str("func", "AddWebhook").Logger()
gc, err := utils.GinContextFromContext(ctx)
if err != nil {
- log.Debug("Failed to get GinContext: ", err)
+ log.Debug().Err(err).Msg("Failed to get GinContext")
return nil, err
}
- if !token.IsSuperAdmin(gc) {
- log.Debug("Not logged in as super admin")
+ if !g.TokenProvider.IsSuperAdmin(gc) {
+ log.Debug().Msg("Not logged in as super admin")
return nil, fmt.Errorf("unauthorized")
}
if !validators.IsValidWebhookEventName(params.EventName) {
- log.Debug("Invalid Event Name: ", params.EventName)
+ log.Debug().Str("EventName", params.EventName).Msg("Invalid Event Name")
return nil, fmt.Errorf("invalid event name %s", params.EventName)
}
if strings.TrimSpace(params.Endpoint) == "" {
- log.Debug("empty endpoint not allowed")
+ log.Debug().Msg("endpoint is missing")
return nil, fmt.Errorf("empty endpoint not allowed")
}
headerBytes, err := json.Marshal(params.Headers)
@@ -43,7 +42,7 @@ func AddWebhookResolver(ctx context.Context, params model.AddWebhookRequest) (*m
if params.EventDescription == nil {
params.EventDescription = refs.NewStringRef(strings.Join(strings.Split(params.EventName, "."), " "))
}
- _, err = db.Provider.AddWebhook(ctx, &models.Webhook{
+ _, err = g.StorageProvider.AddWebhook(ctx, &schemas.Webhook{
EventDescription: refs.StringValue(params.EventDescription),
EventName: params.EventName,
EndPoint: params.Endpoint,
@@ -51,7 +50,7 @@ func AddWebhookResolver(ctx context.Context, params model.AddWebhookRequest) (*m
Headers: string(headerBytes),
})
if err != nil {
- log.Debug("Failed to add webhook: ", err)
+ log.Debug().Err(err).Msg("Failed to add webhook in db")
return nil, err
}
diff --git a/internal/graphql/admin_login.go b/internal/graphql/admin_login.go
new file mode 100644
index 000000000..e35e0ab40
--- /dev/null
+++ b/internal/graphql/admin_login.go
@@ -0,0 +1,38 @@
+package graphql
+
+import (
+ "context"
+ "fmt"
+
+ "github.com/authorizerdev/authorizer/internal/cookie"
+ "github.com/authorizerdev/authorizer/internal/crypto"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/utils"
+)
+
+// AdminLogin is the method to login as admin.
+// Permissions: none
+func (g *graphqlProvider) AdminLogin(ctx context.Context, params *model.AdminLoginRequest) (*model.Response, error) {
+ log := g.Log.With().Str("func", "AdminLogin").Logger()
+ var res *model.Response
+ gc, err := utils.GinContextFromContext(ctx)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get GinContext")
+ return res, fmt.Errorf("internal server error")
+ }
+ if params.AdminSecret != g.Config.AdminSecret {
+ log.Debug().Msg("Invalid admin secret")
+ return res, fmt.Errorf(`invalid admin secret`)
+ }
+
+ hashedKey, err := crypto.EncryptPassword(g.Config.AdminSecret)
+ if err != nil {
+ return res, err
+ }
+ cookie.SetAdminCookie(gc, hashedKey, g.Config.AdminCookieSecure)
+
+ res = &model.Response{
+ Message: "admin logged in successfully",
+ }
+ return res, nil
+}
diff --git a/internal/graphql/admin_logout.go b/internal/graphql/admin_logout.go
new file mode 100644
index 000000000..fc7f127bc
--- /dev/null
+++ b/internal/graphql/admin_logout.go
@@ -0,0 +1,32 @@
+package graphql
+
+import (
+ "context"
+ "fmt"
+
+ "github.com/authorizerdev/authorizer/internal/cookie"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/utils"
+)
+
+// AdminLogout is the method to logout as admin.
+// Permissions: authorizer:admin
+func (g *graphqlProvider) AdminLogout(ctx context.Context) (*model.Response, error) {
+ log := g.Log.With().Str("func", "AdminLogout").Logger()
+ gc, err := utils.GinContextFromContext(ctx)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get GinContext")
+ return nil, err
+ }
+ if !g.TokenProvider.IsSuperAdmin(gc) {
+ log.Debug().Msg("Not logged in as super admin")
+ return nil, fmt.Errorf("unauthorized")
+ }
+
+ cookie.DeleteAdminCookie(gc, g.Config.AdminCookieSecure)
+
+ res := &model.Response{
+ Message: "admin logged out successfully",
+ }
+ return res, nil
+}
diff --git a/internal/graphql/admin_session.go b/internal/graphql/admin_session.go
new file mode 100644
index 000000000..db00fecfe
--- /dev/null
+++ b/internal/graphql/admin_session.go
@@ -0,0 +1,37 @@
+package graphql
+
+import (
+ "context"
+ "fmt"
+
+ "github.com/authorizerdev/authorizer/internal/cookie"
+ "github.com/authorizerdev/authorizer/internal/crypto"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/utils"
+)
+
+// AdminSession is the method to get admin session.
+// Permissions: authorizer:admin
+func (g *graphqlProvider) AdminSession(ctx context.Context) (*model.Response, error) {
+ log := g.Log.With().Str("func", "AdminLogout").Logger()
+ gc, err := utils.GinContextFromContext(ctx)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get GinContext")
+ return nil, err
+ }
+ if !g.TokenProvider.IsSuperAdmin(gc) {
+ log.Debug().Msg("Not logged in as super admin")
+ return nil, fmt.Errorf("unauthorized")
+ }
+ hashedKey, err := crypto.EncryptPassword(g.Config.AdminSecret)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to encrypt admin secret")
+ return nil, err
+ }
+ cookie.SetAdminCookie(gc, hashedKey, g.Config.AdminCookieSecure)
+
+ res := &model.Response{
+ Message: "admin session refreshed successfully",
+ }
+ return res, nil
+}
diff --git a/internal/graphql/deactivate_account.go b/internal/graphql/deactivate_account.go
new file mode 100644
index 000000000..9e7aa5f46
--- /dev/null
+++ b/internal/graphql/deactivate_account.go
@@ -0,0 +1,49 @@
+package graphql
+
+import (
+ "context"
+ "time"
+
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/utils"
+)
+
+// DeactivateAccount is the method for the deactivate_account field.
+// Permissions: authorized user
+func (g *graphqlProvider) DeactivateAccount(ctx context.Context) (*model.Response, error) {
+ log := g.Log.With().Str("func", "DeactivateAccount").Logger()
+ var res *model.Response
+ gc, err := utils.GinContextFromContext(ctx)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get GinContext")
+ return res, err
+ }
+
+ tokenData, err := g.TokenProvider.GetUserIDFromSessionOrAccessToken(gc)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get user id from session or access token")
+ return res, err
+ }
+ log = log.With().Str("userID", tokenData.UserID).Logger()
+ user, err := g.StorageProvider.GetUserByID(ctx, tokenData.UserID)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get user by id")
+ return res, err
+ }
+ now := time.Now().Unix()
+ user.RevokedTimestamp = &now
+ user, err = g.StorageProvider.UpdateUser(ctx, user)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to update user")
+ return res, err
+ }
+ go func() {
+ g.MemoryStoreProvider.DeleteAllUserSessions(user.ID)
+ g.EventsProvider.RegisterEvent(ctx, constants.UserDeactivatedWebhookEvent, "", user)
+ }()
+ res = &model.Response{
+ Message: `user account deactivated successfully`,
+ }
+ return res, nil
+}
diff --git a/internal/graphql/delete_email_template.go b/internal/graphql/delete_email_template.go
new file mode 100644
index 000000000..cdc3c1bbc
--- /dev/null
+++ b/internal/graphql/delete_email_template.go
@@ -0,0 +1,48 @@
+package graphql
+
+import (
+ "context"
+ "fmt"
+ "strings"
+
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/utils"
+)
+
+// DeleteEmailTemplate is the method to delete an email template.
+// Permissions: authorizer:admin
+func (g *graphqlProvider) DeleteEmailTemplate(ctx context.Context, params *model.DeleteEmailTemplateRequest) (*model.Response, error) {
+ log := g.Log.With().Str("func", "DeleteEmailTemplate").Logger()
+ gc, err := utils.GinContextFromContext(ctx)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get GinContext")
+ return nil, err
+ }
+
+ if !g.TokenProvider.IsSuperAdmin(gc) {
+ log.Debug().Msg("Not logged in as super admin")
+ return nil, fmt.Errorf("unauthorized")
+ }
+
+ if strings.TrimSpace(params.ID) == "" {
+ return nil, fmt.Errorf("email template ID required")
+ }
+
+ log = log.With().Str("emailTemplateID", params.ID).Logger()
+
+ emailTemplate, err := g.StorageProvider.GetEmailTemplateByID(ctx, params.ID)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get email template by id")
+ return nil, err
+ }
+
+ err = g.StorageProvider.DeleteEmailTemplate(ctx, emailTemplate)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to delete email template")
+ return nil, err
+ }
+
+ return &model.Response{
+ Message: "Email templated deleted successfully",
+ }, nil
+}
diff --git a/internal/graphql/delete_user.go b/internal/graphql/delete_user.go
new file mode 100644
index 000000000..0d6742a6c
--- /dev/null
+++ b/internal/graphql/delete_user.go
@@ -0,0 +1,94 @@
+package graphql
+
+import (
+ "context"
+ "fmt"
+
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/refs"
+ "github.com/authorizerdev/authorizer/internal/utils"
+)
+
+// DeleteUser is the method to delete a user.
+// Permissions: authorizer:admin
+func (g *graphqlProvider) DeleteUser(ctx context.Context, params *model.DeleteUserRequest) (*model.Response, error) {
+ log := g.Log.With().Str("func", "DeleteUser").Logger()
+
+ var res *model.Response
+ gc, err := utils.GinContextFromContext(ctx)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get GinContext")
+ return res, err
+ }
+
+ if !g.TokenProvider.IsSuperAdmin(gc) {
+ log.Debug().Msg("Not logged in as super admin")
+ return nil, fmt.Errorf("unauthorized")
+ }
+
+ log = log.With().Str("email", params.Email).Logger()
+ user, err := g.StorageProvider.GetUserByEmail(ctx, params.Email)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get user by email")
+ return res, err
+ }
+
+ err = g.StorageProvider.DeleteUser(ctx, user)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to delete user")
+ return res, err
+ }
+
+ res = &model.Response{
+ Message: `user deleted successfully`,
+ }
+
+ go func() {
+ // delete otp for given email
+ otp, err := g.StorageProvider.GetOTPByEmail(ctx, refs.StringValue(user.Email))
+ if err != nil {
+ log.Debug().Err(err).Msg("No OTP found for email")
+ // continue
+ } else {
+ err := g.StorageProvider.DeleteOTP(ctx, otp)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to delete otp for given email")
+ // continue
+ }
+ }
+
+ // delete otp for given phone number
+ otp, err = g.StorageProvider.GetOTPByPhoneNumber(ctx, refs.StringValue(user.PhoneNumber))
+ if err != nil {
+ log.Debug().Err(err).Msg("No OTP found for phone number")
+ // continue
+ } else {
+ err := g.StorageProvider.DeleteOTP(ctx, otp)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to delete otp for given phone number")
+ // continue
+ }
+ }
+
+ // delete verification requests for given email
+ for _, vt := range constants.VerificationTypes {
+ verificationRequest, err := g.StorageProvider.GetVerificationRequestByEmail(ctx, refs.StringValue(user.Email), vt)
+ if err != nil {
+ log.Debug().Err(err).Msg("No verification request found for email")
+ // continue
+ } else {
+ err := g.StorageProvider.DeleteVerificationRequest(ctx, verificationRequest)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to delete verification request for given email")
+ // continue
+ }
+ }
+ }
+
+ g.MemoryStoreProvider.DeleteAllUserSessions(user.ID)
+ g.EventsProvider.RegisterEvent(ctx, constants.UserDeletedWebhookEvent, "", user)
+ }()
+
+ return res, nil
+}
diff --git a/internal/graphql/delete_webhook.go b/internal/graphql/delete_webhook.go
new file mode 100644
index 000000000..0df0e9f9c
--- /dev/null
+++ b/internal/graphql/delete_webhook.go
@@ -0,0 +1,48 @@
+package graphql
+
+import (
+ "context"
+ "fmt"
+
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/utils"
+)
+
+// DeleteWebhook is the method to delete a webhook.
+// Permissions: authorizer:admin
+func (g *graphqlProvider) DeleteWebhook(ctx context.Context, params *model.WebhookRequest) (*model.Response, error) {
+ log := g.Log.With().Str("func", "DeleteWebhook").Logger()
+ gc, err := utils.GinContextFromContext(ctx)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get GinContext")
+ return nil, err
+ }
+
+ if !g.TokenProvider.IsSuperAdmin(gc) {
+ log.Debug().Msg("Not logged in as super admin")
+ return nil, fmt.Errorf("unauthorized")
+ }
+
+ if params.ID == "" {
+ log.Debug().Msg("Webhook ID required")
+ return nil, fmt.Errorf("webhook ID required")
+ }
+
+ log = log.With().Str("webhookID", params.ID).Logger()
+
+ webhook, err := g.StorageProvider.GetWebhookByID(ctx, params.ID)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get webhook by ID")
+ return nil, err
+ }
+
+ err = g.StorageProvider.DeleteWebhook(ctx, webhook)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to delete webhook")
+ return nil, err
+ }
+
+ return &model.Response{
+ Message: "Webhook deleted successfully",
+ }, nil
+}
diff --git a/internal/graphql/email_templates.go b/internal/graphql/email_templates.go
new file mode 100644
index 000000000..eac83a127
--- /dev/null
+++ b/internal/graphql/email_templates.go
@@ -0,0 +1,41 @@
+package graphql
+
+import (
+ "context"
+ "fmt"
+
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/utils"
+)
+
+// EmailTemplates is the method to get all email templates.
+// Permissions: authorizer:admin
+func (g *graphqlProvider) EmailTemplates(ctx context.Context, params *model.PaginatedRequest) (*model.EmailTemplates, error) {
+ log := g.Log.With().Str("func", "EmailTemplates").Logger()
+ gc, err := utils.GinContextFromContext(ctx)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get GinContext")
+ return nil, err
+ }
+
+ if !g.TokenProvider.IsSuperAdmin(gc) {
+ log.Debug().Msg("Not logged in as super admin")
+ return nil, fmt.Errorf("unauthorized")
+ }
+
+ pagination := utils.GetPagination(params)
+ emailTemplates, pagination, err := g.StorageProvider.ListEmailTemplate(ctx, pagination)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get email templates")
+ return nil, err
+ }
+ resItems := make([]*model.EmailTemplate, len(emailTemplates))
+ for _, emailTemplate := range emailTemplates {
+ resItems = append(resItems, emailTemplate.AsAPIEmailTemplate())
+ }
+
+ return &model.EmailTemplates{
+ Pagination: pagination,
+ EmailTemplates: resItems,
+ }, nil
+}
diff --git a/internal/graphql/enable_access.go b/internal/graphql/enable_access.go
new file mode 100644
index 000000000..f4f516dd6
--- /dev/null
+++ b/internal/graphql/enable_access.go
@@ -0,0 +1,52 @@
+package graphql
+
+import (
+ "context"
+ "fmt"
+
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/utils"
+)
+
+// EnableAccess is the method to enable access for a user.
+// Permissions: authorizer:admin
+func (g *graphqlProvider) EnableAccess(ctx context.Context, params *model.UpdateAccessRequest) (*model.Response, error) {
+ log := g.Log.With().Str("func", "EnableAccess").Logger()
+
+ gc, err := utils.GinContextFromContext(ctx)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get GinContext")
+ return nil, err
+ }
+
+ if !g.TokenProvider.IsSuperAdmin(gc) {
+ log.Debug().Msg("Not logged in as super admin")
+ return nil, fmt.Errorf("unauthorized")
+ }
+
+ if params.UserID == "" {
+ return nil, fmt.Errorf("user ID is missing")
+ }
+
+ log = log.With().Str("user_id", params.UserID).Logger()
+
+ user, err := g.StorageProvider.GetUserByID(ctx, params.UserID)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get user by ID")
+ return nil, err
+ }
+
+ user.RevokedTimestamp = nil
+
+ user, err = g.StorageProvider.UpdateUser(ctx, user)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to update user")
+ return nil, err
+ }
+ go g.EventsProvider.RegisterEvent(ctx, constants.UserAccessEnabledWebhookEvent, "", user)
+
+ return &model.Response{
+ Message: `user access enabled successfully`,
+ }, nil
+}
diff --git a/internal/graphql/forgot_password.go b/internal/graphql/forgot_password.go
new file mode 100644
index 000000000..5e1d0ef4b
--- /dev/null
+++ b/internal/graphql/forgot_password.go
@@ -0,0 +1,151 @@
+package graphql
+
+import (
+ "context"
+ "fmt"
+ "strings"
+ "time"
+
+ "github.com/google/uuid"
+
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/cookie"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/parsers"
+ "github.com/authorizerdev/authorizer/internal/refs"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
+ "github.com/authorizerdev/authorizer/internal/token"
+ "github.com/authorizerdev/authorizer/internal/utils"
+)
+
+// ForgotPassword is a for forgot password mutation
+// It sends an email or sms with a verification token
+// Permissions: none
+func (g *graphqlProvider) ForgotPassword(ctx context.Context, params *model.ForgotPasswordRequest) (*model.ForgotPasswordResponse, error) {
+ log := g.Log.With().Str("func", "ForgotPassword").Logger()
+ gc, err := utils.GinContextFromContext(ctx)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get GinContext")
+ return nil, err
+ }
+ isBasicAuthEnabled := g.Config.EnableBasicAuthentication
+ isEmailVerificationEnabled := g.Config.EnableEmailVerification
+ isMobileBasicAuthEnabled := g.Config.EnableMobileBasicAuthentication
+ isMobileVerificationEnabled := g.Config.EnablePhoneVerification
+ email := refs.StringValue(params.Email)
+ phoneNumber := refs.StringValue(params.PhoneNumber)
+ if email == "" && phoneNumber == "" {
+ log.Debug().Msg("Email or phone number is required")
+ return nil, fmt.Errorf(`email or phone number is required`)
+ }
+ log = log.With().Str("email", email).Str("phoneNumber", phoneNumber).Logger()
+ isEmailLogin := email != ""
+ isMobileLogin := phoneNumber != ""
+ if !isBasicAuthEnabled && isEmailLogin && isEmailVerificationEnabled {
+ log.Debug().Msgf("Basic authentication is disabled.")
+ return nil, fmt.Errorf(`basic authentication is disabled for this instance`)
+ }
+ if !isMobileBasicAuthEnabled && isMobileLogin && isMobileVerificationEnabled {
+ log.Debug().Msgf("Mobile basic authentication is disabled.")
+ return nil, fmt.Errorf(`mobile basic authentication is disabled for this instance`)
+ }
+ var user *schemas.User
+ if isEmailLogin {
+ user, err = g.StorageProvider.GetUserByEmail(ctx, email)
+ log.Debug().Err(err).Msg("Failed to get user by email")
+ } else {
+ user, err = g.StorageProvider.GetUserByPhoneNumber(ctx, phoneNumber)
+ log.Debug().Err(err).Msg("Failed to get user by phone number")
+ }
+ if err != nil {
+ return nil, fmt.Errorf(`bad user credentials`)
+ }
+ hostname := parsers.GetHost(gc)
+ _, nonceHash, err := utils.GenerateNonce()
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to generate nonce")
+ return nil, err
+ }
+ if user.RevokedTimestamp != nil {
+ log.Debug().Msg("User access has been revoked")
+ return nil, fmt.Errorf(`user access has been revoked`)
+ }
+ if isEmailLogin {
+ redirectURI := ""
+ // give higher preference to params redirect uri
+ if strings.TrimSpace(refs.StringValue(params.RedirectURI)) != "" {
+ redirectURI = refs.StringValue(params.RedirectURI)
+ } else {
+ redirectURI = g.Config.ResetPasswordURL
+ if redirectURI == "" {
+ log.Debug().Err(err).Msg("Failed to get reset password url")
+ redirectURI = hostname + "/app/reset-password"
+ }
+ }
+
+ verificationToken, err := g.TokenProvider.CreateVerificationToken(&token.AuthTokenConfig{
+ LoginMethod: constants.AuthRecipeMethodBasicAuth,
+ Nonce: nonceHash,
+ User: user,
+ HostName: hostname,
+ }, redirectURI, constants.VerificationTypeForgotPassword)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to create verification token")
+ return nil, err
+ }
+ _, err = g.StorageProvider.AddVerificationRequest(ctx, &schemas.VerificationRequest{
+ Token: verificationToken,
+ Identifier: constants.VerificationTypeForgotPassword,
+ ExpiresAt: time.Now().Add(time.Minute * 30).Unix(),
+ Email: email,
+ Nonce: nonceHash,
+ RedirectURI: redirectURI,
+ })
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to add verification request")
+ return nil, err
+ }
+ // execute it as go routine so that we can reduce the api latency
+ go g.EmailProvider.SendEmail([]string{email}, constants.VerificationTypeForgotPassword, map[string]interface{}{
+ "user": user.ToMap(),
+ "organization": utils.GetOrganization(g.Config),
+ "verification_url": utils.GetForgotPasswordURL(verificationToken, redirectURI),
+ })
+ return &model.ForgotPasswordResponse{
+ Message: `Please check your inbox! We have sent a password reset link.`,
+ }, nil
+ }
+ if isMobileLogin {
+ expiresAt := time.Now().Add(1 * time.Minute).Unix()
+ otp := utils.GenerateOTP()
+ otpData, err := g.StorageProvider.UpsertOTP(ctx, &schemas.OTP{
+ Email: refs.StringValue(user.Email),
+ PhoneNumber: refs.StringValue(user.PhoneNumber),
+ Otp: otp,
+ ExpiresAt: expiresAt,
+ })
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to upsert otp")
+ return nil, err
+ }
+ mfaSession := uuid.NewString()
+ err = g.MemoryStoreProvider.SetMfaSession(user.ID, mfaSession, expiresAt)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to set mfa session")
+ return nil, err
+ }
+ cookie.SetMfaSession(gc, mfaSession, g.Config.AppCookieSecure)
+ smsBody := strings.Builder{}
+ smsBody.WriteString("Your verification code is: ")
+ smsBody.WriteString(otpData.Otp)
+ if err := g.SMSProvider.SendSMS(phoneNumber, smsBody.String()); err != nil {
+ log.Debug().Err(err).Msg("Failed to send sms")
+ // continue
+ }
+ return &model.ForgotPasswordResponse{
+ Message: "Please enter the OTP sent to your phone number and change your password.",
+ ShouldShowMobileOtpScreen: refs.NewBoolRef(true),
+ }, nil
+ }
+ return nil, fmt.Errorf(`email or phone number verification needs to be enabled`)
+}
diff --git a/internal/graphql/invite_members.go b/internal/graphql/invite_members.go
new file mode 100644
index 000000000..e8368998c
--- /dev/null
+++ b/internal/graphql/invite_members.go
@@ -0,0 +1,173 @@
+package graphql
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "strings"
+ "time"
+
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/parsers"
+ "github.com/authorizerdev/authorizer/internal/refs"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
+ "github.com/authorizerdev/authorizer/internal/token"
+ "github.com/authorizerdev/authorizer/internal/utils"
+ "github.com/authorizerdev/authorizer/internal/validators"
+)
+
+// InviteMembers is the method to invite members to the organization.
+// Permissions: authorizer:admin
+func (g *graphqlProvider) InviteMembers(ctx context.Context, params *model.InviteMemberRequest) (*model.InviteMembersResponse, error) {
+ log := g.Log.With().Str("func", "InviteMembers").Logger()
+ gc, err := utils.GinContextFromContext(ctx)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get GinContext")
+ return nil, err
+ }
+
+ if !g.TokenProvider.IsSuperAdmin(gc) {
+ log.Debug().Msg("Not logged in as super admin")
+ return nil, fmt.Errorf("unauthorized")
+ }
+
+ // this feature is only allowed if email server is configured
+ if !g.Config.IsEmailServiceEnabled {
+ log.Debug().Msg("Email sending is disabled")
+ return nil, errors.New("email sending is disabled")
+ }
+
+ isBasicAuthEnabled := g.Config.EnableBasicAuthentication
+ isMagicLinkLoginEnabled := g.Config.EnableMagicLinkLogin
+ if !isBasicAuthEnabled && !isMagicLinkLoginEnabled {
+ log.Debug().Msg("Either basic authentication or magic link login is required")
+ return nil, errors.New("either basic authentication or magic link login is required")
+ }
+
+ // filter valid emails
+ emails := []string{}
+ for _, email := range params.Emails {
+ if validators.IsValidEmail(email) {
+ emails = append(emails, email)
+ }
+ }
+
+ if len(emails) == 0 {
+ log.Debug().Msg("No valid emails found")
+ return nil, errors.New("no valid emails found")
+ }
+
+ // TODO: optimise to use like query instead of looping through emails and getting user individually
+ // for each emails check if emails exists in db
+ newEmails := []string{}
+ for _, email := range emails {
+ _, err := g.StorageProvider.GetUserByEmail(ctx, email)
+ if err != nil {
+ log.Debug().Msgf("User with %s email does not exist", email)
+ newEmails = append(newEmails, email)
+ } else {
+ log.Debug().Msgf("User with %s email already exists", email)
+ }
+ }
+
+ if len(newEmails) == 0 {
+ log.Debug().Msg("All emails already exist")
+ return nil, errors.New("all emails already exist")
+ }
+
+ // invite new emails
+ for _, email := range newEmails {
+ user := &schemas.User{
+ Email: refs.NewStringRef(email),
+ Roles: strings.Join(g.Config.DefaultRoles, ","),
+ }
+ hostname := parsers.GetHost(gc)
+ verifyEmailURL := hostname + "/verify_email"
+ appURL := parsers.GetAppURL(gc)
+
+ redirectURL := appURL
+ if params.RedirectURI != nil {
+ redirectURL = *params.RedirectURI
+ }
+
+ _, nonceHash, err := utils.GenerateNonce()
+ if err != nil {
+ return nil, err
+ }
+ // email, constants.VerificationTypeInviteMember, hostname, nonceHash, redirectURL
+
+ verificationToken, err := g.TokenProvider.CreateVerificationToken(&token.AuthTokenConfig{
+ LoginMethod: constants.AuthRecipeMethodBasicAuth,
+ Nonce: nonceHash,
+ HostName: hostname,
+ User: user,
+ }, redirectURL, constants.VerificationTypeInviteMember)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to create verification token")
+ // continue to next email
+ }
+
+ verificationRequest := &schemas.VerificationRequest{
+ Token: verificationToken,
+ ExpiresAt: time.Now().Add(time.Minute * 30).Unix(),
+ Email: email,
+ Nonce: nonceHash,
+ RedirectURI: redirectURL,
+ }
+
+ // use magic link login if that option is on
+ if isMagicLinkLoginEnabled {
+ user.SignupMethods = constants.AuthRecipeMethodMagicLinkLogin
+ verificationRequest.Identifier = constants.VerificationTypeMagicLinkLogin
+ } else {
+ // use basic authentication if that option is on
+ user.SignupMethods = constants.AuthRecipeMethodBasicAuth
+ verificationRequest.Identifier = constants.VerificationTypeInviteMember
+
+ isMFAEnforced := g.Config.EnforceMFA
+ if isMFAEnforced {
+ user.IsMultiFactorAuthEnabled = refs.NewBoolRef(true)
+ }
+ verifyEmailURL = appURL + "/setup-password"
+ }
+
+ user, err = g.StorageProvider.AddUser(ctx, user)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to add user")
+ return nil, err
+ }
+
+ _, err = g.StorageProvider.AddVerificationRequest(ctx, verificationRequest)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to add verification request")
+ return nil, err
+ }
+
+ // exec it as go routine so that we can reduce the api latency
+ go g.EmailProvider.SendEmail([]string{refs.StringValue(user.Email)}, constants.VerificationTypeInviteMember, map[string]interface{}{
+ "user": user.ToMap(),
+ "organization": utils.GetOrganization(g.Config),
+ "verification_url": utils.GetInviteVerificationURL(verifyEmailURL, verificationToken, redirectURL),
+ })
+ }
+
+ InvitedUsers := []*model.User{}
+
+ for _, email := range newEmails {
+ user, err := g.StorageProvider.GetUserByEmail(ctx, email)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get user by email")
+ return nil, err
+ }
+ InvitedUsers = append(InvitedUsers, &model.User{
+ Email: user.Email,
+ ID: user.ID,
+ })
+ }
+
+ return &model.InviteMembersResponse{
+ Message: fmt.Sprintf("%d user(s) invited successfully.", len(newEmails)),
+ Users: InvitedUsers,
+ }, nil
+}
diff --git a/internal/graphql/login.go b/internal/graphql/login.go
new file mode 100644
index 000000000..b9fd20e77
--- /dev/null
+++ b/internal/graphql/login.go
@@ -0,0 +1,388 @@
+package graphql
+
+import (
+ "context"
+ "fmt"
+ "strings"
+ "time"
+
+ "github.com/google/uuid"
+ "golang.org/x/crypto/bcrypt"
+
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/cookie"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/parsers"
+ "github.com/authorizerdev/authorizer/internal/refs"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
+ "github.com/authorizerdev/authorizer/internal/token"
+ "github.com/authorizerdev/authorizer/internal/utils"
+ "github.com/authorizerdev/authorizer/internal/validators"
+)
+
+// Login is the method to login a user.
+// User can login with email or phone number, but not both
+// Permissions: none
+func (g *graphqlProvider) Login(ctx context.Context, params *model.LoginRequest) (*model.AuthResponse, error) {
+ log := g.Log.With().Str("func", "Login").Logger()
+
+ gc, err := utils.GinContextFromContext(ctx)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get GinContext")
+ return nil, err
+ }
+
+ isBasicAuthEnabled := g.Config.EnableBasicAuthentication
+ isMobileBasicAuthEnabled := g.Config.EnableMobileBasicAuthentication
+ email := refs.StringValue(params.Email)
+ phoneNumber := refs.StringValue(params.PhoneNumber)
+ if email == "" && phoneNumber == "" {
+ log.Debug().Msg("Email or phone number is required")
+ return nil, fmt.Errorf(`email or phone number is required`)
+ }
+ log = log.With().Str("email", email).Str("phone_number", phoneNumber).Logger()
+ isEmailLogin := email != ""
+ isMobileLogin := phoneNumber != ""
+ if !isBasicAuthEnabled && isEmailLogin {
+ log.Debug().Msg("Basic authentication is disabled")
+ return nil, fmt.Errorf(`basic authentication is disabled for this instance`)
+ }
+ if !isMobileBasicAuthEnabled && isMobileLogin {
+ log.Debug().Msg("Mobile basic authentication is disabled")
+ return nil, fmt.Errorf(`mobile basic authentication is disabled for this instance`)
+ }
+ var user *schemas.User
+ if isEmailLogin {
+ user, err = g.StorageProvider.GetUserByEmail(ctx, email)
+ log.Debug().Str("email", email).Msg("User found by email")
+ } else {
+ user, err = g.StorageProvider.GetUserByPhoneNumber(ctx, phoneNumber)
+ log.Debug().Str("phone_number", phoneNumber).Msg("User found by phone number")
+ }
+ if err != nil {
+ return nil, fmt.Errorf(`user not found`)
+ }
+ if user.RevokedTimestamp != nil {
+ log.Debug().Msg("User access has been revoked")
+ return nil, fmt.Errorf(`user access has been revoked`)
+ }
+ isEmailServiceEnabled := g.Config.IsEmailServiceEnabled
+ isSMSServiceEnabled := g.Config.IsSMSServiceEnabled
+ // If multi factor authentication is enabled and we need to generate OTP for mail / sms based MFA
+ generateOTP := func(expiresAt int64) (*schemas.OTP, error) {
+ otp := utils.GenerateOTP()
+ otpData, err := g.StorageProvider.UpsertOTP(ctx, &schemas.OTP{
+ Email: refs.StringValue(user.Email),
+ PhoneNumber: refs.StringValue(user.PhoneNumber),
+ Otp: otp,
+ ExpiresAt: expiresAt,
+ })
+ if err != nil {
+ log.Debug().Msg("Failed to upsert otp")
+ return nil, err
+ }
+ return otpData, nil
+ }
+ setOTPMFaSession := func(expiresAt int64) error {
+ mfaSession := uuid.NewString()
+ err = g.MemoryStoreProvider.SetMfaSession(user.ID, mfaSession, expiresAt)
+ if err != nil {
+ log.Debug().Msg("Failed to set mfa session")
+ return err
+ }
+ cookie.SetMfaSession(gc, mfaSession, g.Config.AppCookieSecure)
+ return nil
+ }
+ if isEmailLogin {
+ if !strings.Contains(user.SignupMethods, constants.AuthRecipeMethodBasicAuth) {
+ log.Debug().Msg("User signup method is not email basic auth")
+ return nil, fmt.Errorf(`user has not signed up email & password`)
+ }
+
+ if user.EmailVerifiedAt == nil {
+ // Check if email service is enabled
+ // Send email verification via otp
+ if !isEmailServiceEnabled {
+ log.Debug().Msg("Email service is not enabled")
+ return nil, fmt.Errorf(`email not verified`)
+ } else {
+ if vreq, err := g.StorageProvider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeBasicAuthSignup); err == nil && vreq != nil {
+ // if verification request exists and not expired then return
+ // if verification request exists and expired then delete it and proceed
+ if vreq.ExpiresAt > time.Now().Unix() {
+ if err := g.StorageProvider.DeleteVerificationRequest(ctx, vreq); err != nil {
+ log.Debug().Msg("Failed to delete verification request")
+ // continue with the flow
+ }
+ } else {
+ log.Debug().Msg("Email verification pending")
+ return nil, fmt.Errorf(`email verification pending`)
+ }
+ }
+ expiresAt := time.Now().Add(1 * time.Minute).Unix()
+ otpData, err := generateOTP(expiresAt)
+ if err != nil {
+ log.Debug().Msg("Failed to generate otp")
+ return nil, err
+ }
+ if err := setOTPMFaSession(expiresAt); err != nil {
+ log.Debug().Msg("Failed to set mfa session")
+ return nil, err
+ }
+ go func() {
+ // exec it as go routine so that we can reduce the api latency
+ if err := g.EmailProvider.SendEmail([]string{email}, constants.VerificationTypeOTP, map[string]interface{}{
+ "user": user.ToMap(),
+ "organization": utils.GetOrganization(g.Config),
+ "otp": otpData.Otp,
+ }); err != nil {
+ log.Debug().Msg("Failed to send otp email")
+ }
+ g.EventsProvider.RegisterEvent(ctx, constants.UserLoginWebhookEvent, constants.AuthRecipeMethodBasicAuth, user)
+ }()
+ return &model.AuthResponse{
+ Message: "Please check email inbox for the OTP",
+ ShouldShowEmailOtpScreen: refs.NewBoolRef(isEmailLogin),
+ }, nil
+ }
+ }
+ } else {
+ if !strings.Contains(user.SignupMethods, constants.AuthRecipeMethodMobileBasicAuth) {
+ log.Debug().Msg("User signup method is not phone number basic auth")
+ return nil, fmt.Errorf(`user has not signed up with phone number & password`)
+ }
+
+ if user.PhoneNumberVerifiedAt == nil {
+ if !isSMSServiceEnabled {
+ log.Debug().Msg("SMS service is not enabled")
+ return nil, fmt.Errorf(`phone number is not verified and sms service is not enabled`)
+ } else {
+ expiresAt := time.Now().Add(1 * time.Minute).Unix()
+ otpData, err := generateOTP(expiresAt)
+ if err != nil {
+ log.Debug().Msg("Failed to generate otp")
+ return nil, err
+ }
+ if err := setOTPMFaSession(expiresAt); err != nil {
+ log.Debug().Msg("Failed to set mfa session")
+ return nil, err
+ }
+ go func() {
+ smsBody := strings.Builder{}
+ smsBody.WriteString("Your verification code is: ")
+ smsBody.WriteString(otpData.Otp)
+ g.EventsProvider.RegisterEvent(ctx, constants.UserLoginWebhookEvent, constants.AuthRecipeMethodMobileBasicAuth, user)
+ if err := g.SMSProvider.SendSMS(phoneNumber, smsBody.String()); err != nil {
+ log.Debug().Msg("Failed to send sms")
+ }
+ }()
+ return &model.AuthResponse{
+ Message: "Please check text message for the OTP",
+ ShouldShowMobileOtpScreen: refs.NewBoolRef(isMobileLogin),
+ }, nil
+ }
+ }
+ }
+ err = bcrypt.CompareHashAndPassword([]byte(*user.Password), []byte(params.Password))
+ if err != nil {
+ log.Debug().Msg("Bad user credentials")
+ return nil, fmt.Errorf(`bad user credentials`)
+ }
+ roles := g.Config.DefaultRoles
+ currentRoles := strings.Split(user.Roles, ",")
+ if len(params.Roles) > 0 {
+ if !validators.IsValidRoles(params.Roles, currentRoles) {
+ log.Debug().Msg("Invalid roles")
+ return nil, fmt.Errorf(`invalid roles`)
+ }
+ roles = params.Roles
+ }
+ scope := []string{"openid", "email", "profile"}
+ if params.Scope != nil && len(scope) > 0 {
+ scope = params.Scope
+ }
+
+ isMFAEnabled := g.Config.EnableMFA
+ isTOTPLoginEnabled := g.Config.EnableTOTPLogin
+ isMailOTPEnabled := g.Config.EnableEmailOTP
+ isSMSOTPEnabled := g.Config.EnableSMSOTP
+
+ // If multi factor authentication is enabled and is email based login and email otp is enabled
+ if refs.BoolValue(user.IsMultiFactorAuthEnabled) && isMFAEnabled && isMailOTPEnabled && isEmailServiceEnabled && isEmailLogin {
+ expiresAt := time.Now().Add(1 * time.Minute).Unix()
+ otpData, err := generateOTP(expiresAt)
+ if err != nil {
+ log.Debug().Msg("Failed to generate otp")
+ return nil, err
+ }
+ if err := setOTPMFaSession(expiresAt); err != nil {
+ log.Debug().Msg("Failed to set mfa session")
+ return nil, err
+ }
+ go func() {
+ // exec it as go routine so that we can reduce the api latency
+ if err := g.EmailProvider.SendEmail([]string{email}, constants.VerificationTypeOTP, map[string]interface{}{
+ "user": user.ToMap(),
+ "organization": utils.GetOrganization(g.Config),
+ "otp": otpData.Otp,
+ }); err != nil {
+ log.Debug().Msg("Failed to send otp email")
+ }
+ g.EventsProvider.RegisterEvent(ctx, constants.UserLoginWebhookEvent, constants.AuthRecipeMethodBasicAuth, user)
+ }()
+ return &model.AuthResponse{
+ Message: "Please check email inbox for the OTP",
+ ShouldShowEmailOtpScreen: refs.NewBoolRef(isMobileLogin),
+ }, nil
+ }
+ // If multi factor authentication is enabled and is sms based login and sms otp is enabled
+ if refs.BoolValue(user.IsMultiFactorAuthEnabled) && isMFAEnabled && isSMSOTPEnabled && isSMSServiceEnabled && isMobileLogin {
+ expiresAt := time.Now().Add(1 * time.Minute).Unix()
+ otpData, err := generateOTP(expiresAt)
+ if err != nil {
+ log.Debug().Msg("Failed to generate otp")
+ return nil, err
+ }
+ if err := setOTPMFaSession(expiresAt); err != nil {
+ log.Debug().Msg("Failed to set mfa session")
+ return nil, err
+ }
+ go func() {
+ smsBody := strings.Builder{}
+ smsBody.WriteString("Your verification code is: ")
+ smsBody.WriteString(otpData.Otp)
+ g.EventsProvider.RegisterEvent(ctx, constants.UserLoginWebhookEvent, constants.AuthRecipeMethodMobileBasicAuth, user)
+ if err := g.SMSProvider.SendSMS(phoneNumber, smsBody.String()); err != nil {
+ log.Debug().Msg("Failed to send sms")
+ }
+ }()
+ return &model.AuthResponse{
+ Message: "Please check text message for the OTP",
+ ShouldShowMobileOtpScreen: refs.NewBoolRef(isMobileLogin),
+ }, nil
+ }
+ // If mfa enabled and also totp enabled
+ if refs.BoolValue(user.IsMultiFactorAuthEnabled) && isMFAEnabled && isTOTPLoginEnabled {
+ expiresAt := time.Now().Add(3 * time.Minute).Unix()
+ if err := setOTPMFaSession(expiresAt); err != nil {
+ log.Debug().Msg("Failed to set mfa session")
+ return nil, err
+ }
+ authenticator, err := g.StorageProvider.GetAuthenticatorDetailsByUserId(ctx, user.ID, constants.EnvKeyTOTPAuthenticator)
+ if err != nil || authenticator == nil || authenticator.VerifiedAt == nil {
+ // generate totp
+ // Generate a base64 URL and initiate the registration for TOTP
+ authConfig, err := g.AuthenticatorProvider.Generate(ctx, user.ID)
+ if err != nil {
+ log.Debug().Msg("Failed to generate totp")
+ return nil, err
+ }
+ recoveryCodes := []*string{}
+ for _, code := range authConfig.RecoveryCodes {
+ recoveryCodes = append(recoveryCodes, refs.NewStringRef(code))
+ }
+ // when user is first time registering for totp
+ res := &model.AuthResponse{
+ Message: `Proceed to totp verification screen`,
+ ShouldShowTotpScreen: refs.NewBoolRef(true),
+ AuthenticatorScannerImage: refs.NewStringRef(authConfig.ScannerImage),
+ AuthenticatorSecret: refs.NewStringRef(authConfig.Secret),
+ AuthenticatorRecoveryCodes: recoveryCodes,
+ }
+ return res, nil
+ } else {
+ //when user is already register for totp
+ res := &model.AuthResponse{
+ Message: `Proceed to totp screen`,
+ ShouldShowTotpScreen: refs.NewBoolRef(true),
+ }
+ return res, nil
+ }
+ }
+
+ code := ""
+ codeChallenge := ""
+ nonce := ""
+ if params.State != nil {
+ // Get state from store
+ authorizeState, _ := g.MemoryStoreProvider.GetState(refs.StringValue(params.State))
+ if authorizeState != "" {
+ authorizeStateSplit := strings.Split(authorizeState, "@@")
+ if len(authorizeStateSplit) > 1 {
+ code = authorizeStateSplit[0]
+ codeChallenge = authorizeStateSplit[1]
+ } else {
+ nonce = authorizeState
+ }
+ go g.MemoryStoreProvider.RemoveState(refs.StringValue(params.State))
+ }
+ }
+
+ if nonce == "" {
+ nonce = uuid.New().String()
+ }
+ hostname := parsers.GetHost(gc)
+ // gc, user, roles, scope, constants.AuthRecipeMethodBasicAuth, nonce, code
+ authToken, err := g.TokenProvider.CreateAuthToken(gc, &token.AuthTokenConfig{
+ User: user,
+ Roles: roles,
+ Scope: scope,
+ Nonce: nonce,
+ Code: code,
+ LoginMethod: constants.AuthRecipeMethodBasicAuth,
+ HostName: hostname,
+ })
+ if err != nil {
+ log.Debug().Msg("Failed to create auth token")
+ return nil, err
+ }
+
+ // TODO add to other login options as well
+ // Code challenge could be optional if PKCE flow is not used
+ if code != "" {
+ if err := g.MemoryStoreProvider.SetState(code, codeChallenge+"@@"+authToken.FingerPrintHash); err != nil {
+ log.Debug().Msg("Failed to set state")
+ return nil, err
+ }
+ }
+
+ expiresIn := authToken.AccessToken.ExpiresAt - time.Now().Unix()
+ if expiresIn <= 0 {
+ expiresIn = 1
+ }
+
+ res := &model.AuthResponse{
+ Message: `Logged in successfully`,
+ AccessToken: &authToken.AccessToken.Token,
+ IDToken: &authToken.IDToken.Token,
+ ExpiresIn: &expiresIn,
+ User: user.AsAPIUser(),
+ }
+
+ cookie.SetSession(gc, authToken.FingerPrintHash, g.Config.AppCookieSecure)
+ sessionStoreKey := constants.AuthRecipeMethodBasicAuth + ":" + user.ID
+ g.MemoryStoreProvider.SetUserSession(sessionStoreKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash, authToken.SessionTokenExpiresAt)
+ g.MemoryStoreProvider.SetUserSession(sessionStoreKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token, authToken.AccessToken.ExpiresAt)
+
+ if authToken.RefreshToken != nil {
+ res.RefreshToken = &authToken.RefreshToken.Token
+ g.MemoryStoreProvider.SetUserSession(sessionStoreKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token, authToken.RefreshToken.ExpiresAt)
+ }
+
+ go func() {
+ // Register event
+ if isEmailLogin {
+ g.EventsProvider.RegisterEvent(ctx, constants.UserLoginWebhookEvent, constants.AuthRecipeMethodBasicAuth, user)
+ } else {
+ g.EventsProvider.RegisterEvent(ctx, constants.UserLoginWebhookEvent, constants.AuthRecipeMethodMobileBasicAuth, user)
+ }
+ // Record session
+ g.StorageProvider.AddSession(ctx, &schemas.Session{
+ UserID: user.ID,
+ UserAgent: utils.GetUserAgent(gc.Request),
+ IP: utils.GetIP(gc.Request),
+ })
+ }()
+
+ return res, nil
+}
diff --git a/internal/graphql/logout.go b/internal/graphql/logout.go
new file mode 100644
index 000000000..31408550a
--- /dev/null
+++ b/internal/graphql/logout.go
@@ -0,0 +1,43 @@
+package graphql
+
+import (
+ "context"
+
+ "github.com/authorizerdev/authorizer/internal/cookie"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/utils"
+)
+
+// Logout is the method to logout a user.
+// Permissions: authenticated:*
+func (g *graphqlProvider) Logout(ctx context.Context) (*model.Response, error) {
+ log := g.Log.With().Str("func", "Logout").Logger()
+ gc, err := utils.GinContextFromContext(ctx)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get GinContext")
+ return nil, err
+ }
+
+ tokenData, err := g.TokenProvider.GetUserIDFromSessionOrAccessToken(gc)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get user id from session or access token")
+ return nil, err
+ }
+
+ sessionKey := tokenData.UserID
+ if tokenData.LoginMethod != "" {
+ sessionKey = tokenData.LoginMethod + ":" + tokenData.UserID
+ }
+
+ if err = g.MemoryStoreProvider.DeleteUserSession(sessionKey, tokenData.Nonce); err != nil {
+ log.Debug().Err(err).Msg("Failed to delete user session")
+ return nil, err
+ }
+ cookie.DeleteSession(gc, g.Config.AppCookieSecure)
+
+ res := &model.Response{
+ Message: "Logged out successfully",
+ }
+
+ return res, nil
+}
diff --git a/internal/graphql/magic_link_login.go b/internal/graphql/magic_link_login.go
new file mode 100644
index 000000000..71b3989ce
--- /dev/null
+++ b/internal/graphql/magic_link_login.go
@@ -0,0 +1,196 @@
+package graphql
+
+import (
+ "context"
+ "fmt"
+ "strings"
+ "time"
+
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/parsers"
+ "github.com/authorizerdev/authorizer/internal/refs"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
+ "github.com/authorizerdev/authorizer/internal/token"
+ "github.com/authorizerdev/authorizer/internal/utils"
+ "github.com/authorizerdev/authorizer/internal/validators"
+)
+
+// MagicLinkLogin is the method to login a user using magic link.
+// Permissions: none
+func (g *graphqlProvider) MagicLinkLogin(ctx context.Context, params *model.MagicLinkLoginRequest) (*model.Response, error) {
+ log := g.Log.With().Str("func", "MagicLinkLogin").Logger()
+ gc, err := utils.GinContextFromContext(ctx)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get GinContext")
+ return nil, err
+ }
+
+ isMagicLinkLoginEnabled := g.Config.EnableMagicLinkLogin
+ if !isMagicLinkLoginEnabled {
+ log.Debug().Msg("Magic link login is disabled")
+ return nil, fmt.Errorf(`magic link login is disabled for this instance`)
+ }
+
+ params.Email = strings.ToLower(params.Email)
+ log = log.With().Str("email", params.Email).Logger()
+
+ if !validators.IsValidEmail(params.Email) {
+ log.Debug().Msg("Invalid email address")
+ return nil, fmt.Errorf(`invalid email address`)
+ }
+
+ inputRoles := []string{}
+ user := &schemas.User{
+ Email: refs.NewStringRef(params.Email),
+ }
+
+ // find user with email
+ existingUser, err := g.StorageProvider.GetUserByEmail(ctx, params.Email)
+ if err != nil {
+ isSignupEnabled := g.Config.EnableSignup
+ if !isSignupEnabled {
+ log.Debug().Msg("Signup is disabled")
+ return nil, fmt.Errorf(`signup is disabled for this instance`)
+ }
+
+ user.SignupMethods = constants.AuthRecipeMethodMagicLinkLogin
+ // define roles for new user
+ if len(params.Roles) > 0 {
+ // check if roles exists
+ roles := g.Config.Roles
+ if !validators.IsValidRoles(params.Roles, roles) {
+ log.Debug().Msg("Invalid roles")
+ return nil, fmt.Errorf(`invalid roles`)
+ } else {
+ inputRoles = params.Roles
+ }
+ } else {
+ inputRoles = g.Config.DefaultRoles
+ }
+
+ user.Roles = strings.Join(inputRoles, ",")
+ user, _ = g.StorageProvider.AddUser(ctx, user)
+ go g.EventsProvider.RegisterEvent(ctx, constants.UserCreatedWebhookEvent, constants.AuthRecipeMethodMagicLinkLogin, user)
+ } else {
+ user = existingUser
+ // There multiple scenarios with roles here in magic link login
+ // 1. user has access to protected roles + roles and trying to login
+ // 2. user has not signed up for one of the available role but trying to signup.
+ // Need to modify roles in this case
+
+ if user.RevokedTimestamp != nil {
+ log.Debug().Msg("User access has been revoked")
+ return nil, fmt.Errorf(`user access has been revoked`)
+ }
+
+ // find the unassigned roles
+ if len(params.Roles) <= 0 {
+ inputRolesString := g.Config.DefaultRoles
+ inputRoles = inputRolesString
+ }
+ existingRoles := strings.Split(existingUser.Roles, ",")
+ unasignedRoles := []string{}
+ for _, ir := range inputRoles {
+ if !utils.StringSliceContains(existingRoles, ir) {
+ unasignedRoles = append(unasignedRoles, ir)
+ }
+ }
+
+ if len(unasignedRoles) > 0 {
+ // check if it contains protected unassigned role
+ hasProtectedRole := false
+ protectedRoles := g.Config.ProtectedRoles
+ for _, ur := range unasignedRoles {
+ if utils.StringSliceContains(protectedRoles, ur) {
+ hasProtectedRole = true
+ }
+ }
+
+ if hasProtectedRole {
+ log.Debug().Msg("Protected roles cannot be assigned")
+ return nil, fmt.Errorf(`invalid roles`)
+ } else {
+ user.Roles = existingUser.Roles + "," + strings.Join(unasignedRoles, ",")
+ }
+ } else {
+ user.Roles = existingUser.Roles
+ }
+
+ signupMethod := existingUser.SignupMethods
+ if !strings.Contains(signupMethod, constants.AuthRecipeMethodMagicLinkLogin) {
+ signupMethod = signupMethod + "," + constants.AuthRecipeMethodMagicLinkLogin
+ }
+
+ user.SignupMethods = signupMethod
+ user, err = g.StorageProvider.UpdateUser(ctx, user)
+ if err != nil {
+ log.Debug().Msg("Failed to update user")
+ return nil, fmt.Errorf(`failed to update user`)
+ }
+ }
+
+ hostname := parsers.GetHost(gc)
+ isEmailVerificationEnabled := g.Config.EnableEmailVerification
+ if isEmailVerificationEnabled {
+ // insert verification request
+ _, nonceHash, err := utils.GenerateNonce()
+ if err != nil {
+ log.Debug().Msg("Failed to generate nonce")
+ return nil, err
+ }
+ redirectURLParams := "&roles=" + strings.Join(inputRoles, ",")
+ if params.State != nil {
+ redirectURLParams = redirectURLParams + "&state=" + refs.StringValue(params.State)
+ }
+ if len(params.Scope) > 0 {
+ redirectURLParams = redirectURLParams + "&scope=" + strings.Join(params.Scope, " ")
+ }
+ redirectURL := parsers.GetAppURL(gc)
+ if params.RedirectURI != nil {
+ redirectURL = *params.RedirectURI
+ }
+
+ if strings.Contains(redirectURL, "?") {
+ redirectURL = redirectURL + "&" + redirectURLParams
+ } else {
+ redirectURL = redirectURL + "?" + strings.TrimPrefix(redirectURLParams, "&")
+ }
+
+ verificationType := constants.VerificationTypeMagicLinkLogin
+ // params.Email, verificationType, hostname, nonceHash, redirectURL
+ verificationToken, err := g.TokenProvider.CreateVerificationToken(&token.AuthTokenConfig{
+ User: user,
+ HostName: hostname,
+ Nonce: nonceHash,
+ LoginMethod: constants.AuthRecipeMethodMagicLinkLogin,
+ }, redirectURL, verificationType)
+ if err != nil {
+ log.Debug().Msg("Failed to create verification token")
+ return nil, err
+ }
+ _, err = g.StorageProvider.AddVerificationRequest(ctx, &schemas.VerificationRequest{
+ Token: verificationToken,
+ Identifier: verificationType,
+ ExpiresAt: time.Now().Add(time.Minute * 30).Unix(),
+ Email: params.Email,
+ Nonce: nonceHash,
+ RedirectURI: redirectURL,
+ })
+ if err != nil {
+ log.Debug().Msg("Failed to add verification request")
+ return nil, err
+ }
+
+ // exec it as go routine so that we can reduce the api latency
+ go g.EmailProvider.SendEmail([]string{params.Email}, constants.VerificationTypeMagicLinkLogin, map[string]interface{}{
+ "user": user.ToMap(),
+ "organization": utils.GetOrganization(g.Config),
+ "verification_url": utils.GetEmailVerificationURL(verificationToken, hostname, redirectURL),
+ })
+ }
+
+ return &model.Response{
+ Message: `Magic Link has been sent to your email. Please check your inbox!`,
+ }, nil
+}
diff --git a/internal/graphql/meta.go b/internal/graphql/meta.go
new file mode 100644
index 000000000..17d60eda8
--- /dev/null
+++ b/internal/graphql/meta.go
@@ -0,0 +1,75 @@
+package graphql
+
+import (
+ "context"
+
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+)
+
+// Meta returns the meta information about the server.
+// Permissions: none
+func (g *graphqlProvider) Meta(ctx context.Context) (*model.Meta, error) {
+ clientID := g.Config.ClientID
+
+ googleClientID := g.Config.GoogleClientID
+ googleClientSecret := g.Config.GoogleClientSecret
+
+ facebookClientID := g.Config.FacebookClientID
+ facebookClientSecret := g.Config.FacebookClientSecret
+
+ linkedClientID := g.Config.LinkedinClientID
+ linkedInClientSecret := g.Config.LinkedinClientSecret
+
+ appleClientID := g.Config.AppleClientID
+ appleClientSecret := g.Config.AppleClientSecret
+
+ githubClientID := g.Config.GithubClientID
+ githubClientSecret := g.Config.GithubClientSecret
+
+ twitterClientID := g.Config.TwitterClientID
+ twitterClientSecret := g.Config.TwitterClientSecret
+
+ microsoftClientID := g.Config.MicrosoftClientID
+ microsoftClientSecret := g.Config.MicrosoftClientSecret
+
+ twitchClientID := g.Config.TwitchClientID
+ twitchClientSecret := g.Config.TwitchClientSecret
+
+ robloxClientID := g.Config.RobloxClientID
+ robloxClientSecret := g.Config.RobloxClientSecret
+
+ g.Log.Info().Interface("config", g.Config).Msg("Config")
+
+ isBasicAuthEnabled := g.Config.EnableBasicAuthentication
+ isMobileBasicAuthEnabled := g.Config.EnableMobileBasicAuthentication
+ isMobileVerificationEnabled := g.Config.EnablePhoneVerification
+ isMagicLinkLoginEnabled := g.Config.EnableMagicLinkLogin
+ isEmailVerificationEnabled := g.Config.EnableEmailVerification
+ isMultiFactorAuthenticationEnabled := g.Config.EnableMFA
+ isStrongPasswordEnabled := g.Config.EnableStrongPassword
+ isSignUpEnabled := g.Config.EnableSignup
+
+ metaInfo := model.Meta{
+ Version: constants.VERSION,
+ ClientID: clientID,
+ IsGoogleLoginEnabled: googleClientID != "" && googleClientSecret != "",
+ IsGithubLoginEnabled: githubClientID != "" && githubClientSecret != "",
+ IsFacebookLoginEnabled: facebookClientID != "" && facebookClientSecret != "",
+ IsLinkedinLoginEnabled: linkedClientID != "" && linkedInClientSecret != "",
+ IsAppleLoginEnabled: appleClientID != "" && appleClientSecret != "",
+ IsTwitterLoginEnabled: twitterClientID != "" && twitterClientSecret != "",
+ IsMicrosoftLoginEnabled: microsoftClientID != "" && microsoftClientSecret != "",
+ IsBasicAuthenticationEnabled: isBasicAuthEnabled,
+ IsEmailVerificationEnabled: isEmailVerificationEnabled,
+ IsMagicLinkLoginEnabled: isMagicLinkLoginEnabled,
+ IsSignUpEnabled: isSignUpEnabled,
+ IsStrongPasswordEnabled: isStrongPasswordEnabled,
+ IsMultiFactorAuthEnabled: isMultiFactorAuthenticationEnabled,
+ IsMobileBasicAuthenticationEnabled: isMobileBasicAuthEnabled,
+ IsPhoneVerificationEnabled: isMobileVerificationEnabled,
+ IsTwitchLoginEnabled: twitchClientID != "" && twitchClientSecret != "",
+ IsRobloxLoginEnabled: robloxClientID != "" && robloxClientSecret != "",
+ }
+ return &metaInfo, nil
+}
diff --git a/internal/graphql/profile.go b/internal/graphql/profile.go
new file mode 100644
index 000000000..ebcb4926f
--- /dev/null
+++ b/internal/graphql/profile.go
@@ -0,0 +1,32 @@
+package graphql
+
+import (
+ "context"
+
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/utils"
+)
+
+// Profile is the method to get the profile of a user.
+func (g *graphqlProvider) Profile(ctx context.Context) (*model.User, error) {
+ log := g.Log.With().Str("func", "Profile").Logger()
+
+ gc, err := utils.GinContextFromContext(ctx)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get GinContext")
+ return nil, err
+ }
+ tokenData, err := g.TokenProvider.GetUserIDFromSessionOrAccessToken(gc)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get user id from session or access token")
+ return nil, err
+ }
+ log = log.With().Str("user_id", tokenData.UserID).Logger()
+ user, err := g.StorageProvider.GetUserByID(ctx, tokenData.UserID)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get user by id")
+ return nil, err
+ }
+
+ return user.AsAPIUser(), nil
+}
diff --git a/internal/graphql/provider.go b/internal/graphql/provider.go
new file mode 100644
index 000000000..c537437e9
--- /dev/null
+++ b/internal/graphql/provider.go
@@ -0,0 +1,181 @@
+package graphql
+
+import (
+ "context"
+
+ "github.com/rs/zerolog"
+
+ "github.com/authorizerdev/authorizer/internal/authenticators"
+ "github.com/authorizerdev/authorizer/internal/config"
+ "github.com/authorizerdev/authorizer/internal/email"
+ "github.com/authorizerdev/authorizer/internal/events"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/memory_store"
+ "github.com/authorizerdev/authorizer/internal/sms"
+ "github.com/authorizerdev/authorizer/internal/storage"
+ "github.com/authorizerdev/authorizer/internal/token"
+)
+
+// Dependencies for a graphql provider
+type Dependencies struct {
+ Log *zerolog.Logger
+
+ // Providers for various services
+ // AuthenticatorProvider is used to register authenticators like totp (Google Authenticator)
+ AuthenticatorProvider authenticators.Provider
+ // EmailProvider is used to send emails
+ EmailProvider email.Provider
+ // EventsProvider is used to register events
+ EventsProvider events.Provider
+ // MemoryStoreProvider is used to store data in memory
+ MemoryStoreProvider memory_store.Provider
+ // SMSProvider is used to send SMS
+ SMSProvider sms.Provider
+ // StorageProvider is used to register storage like database
+ StorageProvider storage.Provider
+ // TokenProvider is used to generate tokens
+ TokenProvider token.Provider
+}
+
+// New constructs a new graphql provider with given arguments
+func New(cfg *config.Config, deps *Dependencies) (Provider, error) {
+ // TODO - Add any validation here for config and dependencies
+ g := &graphqlProvider{
+ Config: cfg,
+ Dependencies: *deps,
+ }
+ return g, nil
+}
+
+// graphqlProvider is the struct that provides resolver functions.
+type graphqlProvider struct {
+ *config.Config
+ Dependencies
+}
+
+// Ensure that graphqlProvider implements the Provider interface
+var _ Provider = &graphqlProvider{}
+
+// Provider is the interface that provides the methods to interact with the graphql mutations and queries.
+type Provider interface {
+ // AddEmailTemplate is the method to add email template.
+ // Permissions: authorizer:admin
+ AddEmailTemplate(ctx context.Context, params *model.AddEmailTemplateRequest) (*model.Response, error)
+ // AddWebhook is the method to add webhook.
+ // Permissions: authorizer:admin
+ AddWebhook(ctx context.Context, params *model.AddWebhookRequest) (*model.Response, error)
+ // AdminLogin is the method to login as admin.
+ // Permissions: none
+ AdminLogin(ctx context.Context, params *model.AdminLoginRequest) (*model.Response, error)
+ // AdminLogout is the method to logout as admin.
+ // Permissions: authorizer:admin
+ AdminLogout(ctx context.Context) (*model.Response, error)
+ // AdminSession is the method to get admin session.
+ // Permissions: authorizer:admin
+ AdminSession(ctx context.Context) (*model.Response, error)
+ // DeactivateAccount is the method to deactivate account.
+ // Permissions: authorized user
+ DeactivateAccount(ctx context.Context) (*model.Response, error)
+ // DeleteEmailTemplate is the method to delete email template.
+ // Permissions: authorizer:admin
+ DeleteEmailTemplate(ctx context.Context, params *model.DeleteEmailTemplateRequest) (*model.Response, error)
+ // DeleteUser is the method to delete user.
+ // Permissions: authorizer:admin
+ DeleteUser(ctx context.Context, params *model.DeleteUserRequest) (*model.Response, error)
+ // DeleteWebhook is the method to delete webhook.
+ // Permissions: authorizer:admin
+ DeleteWebhook(ctx context.Context, params *model.WebhookRequest) (*model.Response, error)
+ // EmailTemplates is the method to list email templates.
+ // Permissions: authorizer:admin
+ EmailTemplates(ctx context.Context, in *model.PaginatedRequest) (*model.EmailTemplates, error)
+ // EnableAccess is the method to enable access.
+ // Permissions: authorizer:admin
+ EnableAccess(ctx context.Context, params *model.UpdateAccessRequest) (*model.Response, error)
+ // ForgotPassword is the method to forgot password.
+ // Permissions: none
+ ForgotPassword(ctx context.Context, params *model.ForgotPasswordRequest) (*model.ForgotPasswordResponse, error)
+ // InviteMembers is the method to invite members.
+ // Permissions: authorizer:admin
+ InviteMembers(ctx context.Context, params *model.InviteMemberRequest) (*model.InviteMembersResponse, error)
+ // Login is the method to login.
+ // Permissions: none
+ Login(ctx context.Context, params *model.LoginRequest) (*model.AuthResponse, error)
+ // Logout is the method to logout.
+ // Permissions: authorized user
+ Logout(ctx context.Context) (*model.Response, error)
+ // MagicLinkLogin is the method to login using magic link.
+ // Permissions: none
+ MagicLinkLogin(ctx context.Context, params *model.MagicLinkLoginRequest) (*model.Response, error)
+ // Meta is the method to get meta.
+ // Permissions: none
+ Meta(ctx context.Context) (*model.Meta, error)
+ // Profile is the method to get profile.
+ // Permissions: authorized user
+ Profile(ctx context.Context) (*model.User, error)
+ // ResendOTP is the method to resend OTP.
+ // Permissions: none
+ ResendOTP(ctx context.Context, params *model.ResendOTPRequest) (*model.Response, error)
+ // ResendVerifyEmail is the method to resend verification email.
+ // Permissions: none
+ ResendVerifyEmail(ctx context.Context, params *model.ResendVerifyEmailRequest) (*model.Response, error)
+ // ResetPassword is the method to reset password.
+ // Permissions: none
+ ResetPassword(ctx context.Context, params *model.ResetPasswordRequest) (*model.Response, error)
+ // RevokeAccess is the method to revoke access.
+ // Permissions: authorizer:admin
+ RevokeAccess(ctx context.Context, params *model.UpdateAccessRequest) (*model.Response, error)
+ // Revoke is the method to revoke refresh token.
+ // Permissions: none
+ Revoke(ctx context.Context, params *model.OAuthRevokeRequest) (*model.Response, error)
+ // Session is the method to get session.
+ // Permissions: authorized user
+ Session(ctx context.Context, params *model.SessionQueryRequest) (*model.AuthResponse, error)
+ // SignUp is the method to SignUp.
+ // Permissions: none
+ SignUp(ctx context.Context, params *model.SignUpRequest) (*model.AuthResponse, error)
+ // TestEndpoint is the method to test endpoint.
+ // Permissions: authorizer:admin
+ TestEndpoint(ctx context.Context, params *model.TestEndpointRequest) (*model.TestEndpointResponse, error)
+ // UpdateEmailTemplate is the method to update email template.
+ // Permissions: authorizer:admin
+ UpdateEmailTemplate(ctx context.Context, params *model.UpdateEmailTemplateRequest) (*model.Response, error)
+ // UpdateProfile is the method to update profile.
+ // Permissions: authorized user
+ UpdateProfile(ctx context.Context, params *model.UpdateProfileRequest) (*model.Response, error)
+ // UpdateUser is the method to update user.
+ // Permissions: authorizer:admin
+ UpdateUser(ctx context.Context, params *model.UpdateUserRequest) (*model.User, error)
+ // UpdateWebhook is the method to update webhook.
+ // Permissions: authorizer:admin
+ UpdateWebhook(ctx context.Context, params *model.UpdateWebhookRequest) (*model.Response, error)
+ // User is the method to get user.
+ // Permissions: authorizer:admin
+ User(ctx context.Context, params *model.GetUserRequest) (*model.User, error)
+ // Users is the method to list users.
+ // Permissions: authorizer:admin
+ Users(ctx context.Context, in *model.PaginatedRequest) (*model.Users, error)
+ // ValidateJWTToken is the method to validate JWT token.
+ // Permissions: none
+ ValidateJWTToken(ctx context.Context, params *model.ValidateJWTTokenRequest) (*model.ValidateJWTTokenResponse, error)
+ // ValidateSession is the method to validate browser session.
+ // Permissions: authorized user
+ ValidateSession(ctx context.Context, params *model.ValidateSessionRequest) (*model.ValidateSessionResponse, error)
+ // VerificationRequests is the method to list verification requests.
+ // Permissions: authorizer:admin
+ VerificationRequests(ctx context.Context, in *model.PaginatedRequest) (*model.VerificationRequests, error)
+ // VerifyEmail is the method to verify email.
+ // Permissions: none
+ VerifyEmail(ctx context.Context, params *model.VerifyEmailRequest) (*model.AuthResponse, error)
+ // VerifyOTP is the method to verify OTP.
+ // Permissions: authorized otp request
+ VerifyOTP(ctx context.Context, params *model.VerifyOTPRequest) (*model.AuthResponse, error)
+ // WebhookLogs is the method to list webhook logs.
+ // Permissions: authorizer:admin
+ WebhookLogs(ctx context.Context, in *model.ListWebhookLogRequest) (*model.WebhookLogs, error)
+ // Webhook is the method to get webhook.
+ // Permissions: authorizer:admin
+ Webhook(ctx context.Context, params *model.WebhookRequest) (*model.Webhook, error)
+ // Webhooks is the method to list webhooks.
+ // Permissions: authorizer:admin
+ Webhooks(ctx context.Context, in *model.PaginatedRequest) (*model.Webhooks, error)
+}
diff --git a/internal/graphql/resend_otp.go b/internal/graphql/resend_otp.go
new file mode 100644
index 000000000..4a7f962b4
--- /dev/null
+++ b/internal/graphql/resend_otp.go
@@ -0,0 +1,156 @@
+package graphql
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "strings"
+ "time"
+
+ "github.com/google/uuid"
+
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/cookie"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/refs"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
+ "github.com/authorizerdev/authorizer/internal/utils"
+)
+
+// ResendOTP is the method to resend OTP.
+// Permissions: none
+func (g *graphqlProvider) ResendOTP(ctx context.Context, params *model.ResendOTPRequest) (*model.Response, error) {
+ email := strings.ToLower(strings.Trim(refs.StringValue(params.Email), " "))
+ phoneNumber := strings.Trim(refs.StringValue(params.PhoneNumber), " ")
+ log := g.Log.With().Str("func", "ResendOTP").Str("email", email).Str("phone_number", phoneNumber).Logger()
+ if email == "" && phoneNumber == "" {
+ log.Debug().Msg("Email or phone number is required")
+ return nil, errors.New("email or phone number is required")
+ }
+ gc, err := utils.GinContextFromContext(ctx)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get GinContext")
+ return nil, err
+ }
+ var user *schemas.User
+ var isEmailServiceEnabled, isSMSServiceEnabled bool
+ if email != "" {
+ isEmailServiceEnabled = g.Config.IsEmailServiceEnabled
+ if !isEmailServiceEnabled {
+ log.Debug().Msg("Email service not enabled")
+ return nil, errors.New("email service not enabled")
+ }
+ user, err = g.StorageProvider.GetUserByEmail(ctx, email)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get user by email")
+ return nil, fmt.Errorf(`user with this email/phone not found`)
+ }
+ } else {
+ isSMSServiceEnabled = g.Config.IsSMSServiceEnabled
+ if !isSMSServiceEnabled {
+ log.Debug().Msg("SMS service not enabled")
+ return nil, errors.New("email service not enabled")
+ }
+ user, err = g.StorageProvider.GetUserByPhoneNumber(ctx, phoneNumber)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get user by phone number")
+ return nil, fmt.Errorf(`user with this email/phone not found`)
+ }
+ }
+ if user.RevokedTimestamp != nil {
+ log.Debug().Msg("User access has been revoked")
+ return nil, fmt.Errorf(`user access has been revoked`)
+ }
+
+ if !refs.BoolValue(user.IsMultiFactorAuthEnabled) && user.EmailVerifiedAt != nil && user.PhoneNumberVerifiedAt != nil {
+ log.Debug().Msg("Multi factor authentication not enabled")
+ return nil, fmt.Errorf(`multi factor authentication not enabled`)
+ }
+
+ isMFAEnabled := g.Config.EnableMFA
+ if !isMFAEnabled {
+ log.Debug().Msg("Multi factor authentication is disabled for this instance")
+ return nil, errors.New("multi factor authentication is disabled for this instance")
+ }
+
+ // get otp by email or phone number
+ var otpData *schemas.OTP
+ if email != "" {
+ otpData, err = g.StorageProvider.GetOTPByEmail(ctx, refs.StringValue(params.Email))
+ log.Debug().Msg("Failed to get otp for given email")
+ } else {
+ otpData, err = g.StorageProvider.GetOTPByPhoneNumber(ctx, refs.StringValue(params.PhoneNumber))
+ log.Debug().Msg("Failed to get otp for given phone number")
+ }
+ if err != nil {
+ return nil, err
+ }
+ if otpData == nil {
+ log.Debug().Msg("Failed to get otp for given email")
+ return &model.Response{
+ Message: "Failed to get for given email",
+ }, errors.New("failed to get otp for given email")
+ }
+ // If multi factor authentication is enabled and we need to generate OTP for mail / sms based MFA
+ generateOTP := func(expiresAt int64) (*schemas.OTP, error) {
+ otp := utils.GenerateOTP()
+ otpData, err := g.StorageProvider.UpsertOTP(ctx, &schemas.OTP{
+ Email: refs.StringValue(user.Email),
+ PhoneNumber: refs.StringValue(user.PhoneNumber),
+ Otp: otp,
+ ExpiresAt: expiresAt,
+ })
+ if err != nil {
+ log.Debug().Msg("Failed to upsert otp")
+ return nil, err
+ }
+ return otpData, nil
+ }
+ setOTPMFaSession := func(expiresAt int64) error {
+ mfaSession := uuid.NewString()
+ err = g.MemoryStoreProvider.SetMfaSession(user.ID, mfaSession, expiresAt)
+ if err != nil {
+ log.Debug().Msg("Failed to set mfa session")
+ return err
+ }
+ cookie.SetMfaSession(gc, mfaSession, g.Config.AppCookieSecure)
+ return nil
+ }
+ expiresAt := time.Now().Add(1 * time.Minute).Unix()
+ otpData, err = generateOTP(expiresAt)
+ if err != nil {
+ log.Debug().Msg("Failed to generate otp")
+ return nil, err
+ }
+ if err := setOTPMFaSession(expiresAt); err != nil {
+ log.Debug().Err(err).Msg("Failed to set mfa session")
+ return nil, err
+ }
+ if email != "" {
+ go func() {
+ // exec it as go routine so that we can reduce the api latency
+ if err := g.EmailProvider.SendEmail([]string{email}, constants.VerificationTypeOTP, map[string]interface{}{
+ "user": user.ToMap(),
+ "organization": utils.GetOrganization(g.Config),
+ "otp": otpData.Otp,
+ }); err != nil {
+ log.Debug().Err(err).Msg("Failed to send email")
+ }
+ g.EventsProvider.RegisterEvent(ctx, constants.UserLoginWebhookEvent, constants.AuthRecipeMethodBasicAuth, user)
+ }()
+ } else {
+ go func() {
+ smsBody := strings.Builder{}
+ smsBody.WriteString("Your verification code is: ")
+ smsBody.WriteString(otpData.Otp)
+ g.EventsProvider.RegisterEvent(ctx, constants.UserLoginWebhookEvent, constants.AuthRecipeMethodMobileBasicAuth, user)
+ if err := g.SMSProvider.SendSMS(phoneNumber, smsBody.String()); err != nil {
+ log.Debug().Err(err).Msg("Failed to send sms")
+ }
+ }()
+ }
+ log.Info().Msg("OTP has been sent")
+ return &model.Response{
+ Message: `OTP has been sent. Please check your inbox`,
+ }, nil
+}
diff --git a/internal/graphql/resend_verify_email.go b/internal/graphql/resend_verify_email.go
new file mode 100644
index 000000000..1ea0a8ba9
--- /dev/null
+++ b/internal/graphql/resend_verify_email.go
@@ -0,0 +1,97 @@
+package graphql
+
+import (
+ "context"
+ "fmt"
+ "strings"
+ "time"
+
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/parsers"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
+ "github.com/authorizerdev/authorizer/internal/token"
+ "github.com/authorizerdev/authorizer/internal/utils"
+ "github.com/authorizerdev/authorizer/internal/validators"
+)
+
+// ResendVerifyEmail is the method to resend verification email.
+// Permissions: none
+func (g *graphqlProvider) ResendVerifyEmail(ctx context.Context, params *model.ResendVerifyEmailRequest) (*model.Response, error) {
+ log := g.Log.With().Str("func", "ResendVerifyEmail").Logger()
+ gc, err := utils.GinContextFromContext(ctx)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get GinContext")
+ return nil, err
+ }
+
+ params.Email = strings.ToLower(params.Email)
+
+ log = log.With().Str("email", params.Email).Str("identifier", params.Identifier).Logger()
+ if !validators.IsValidEmail(params.Email) {
+ log.Debug().Msg("Invalid email")
+ return nil, fmt.Errorf("invalid email")
+ }
+
+ if !validators.IsValidVerificationIdentifier(params.Identifier) {
+ log.Debug().Msg("Invalid verification identifier")
+ return nil, fmt.Errorf("invalid identifier")
+ }
+
+ user, err := g.StorageProvider.GetUserByEmail(ctx, params.Email)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get user by email")
+ return nil, fmt.Errorf("invalid user")
+ }
+
+ verificationRequest, err := g.StorageProvider.GetVerificationRequestByEmail(ctx, params.Email, params.Identifier)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get verification request")
+ return nil, fmt.Errorf(`verification request not found`)
+ }
+
+ // delete current verification and create new one
+ err = g.StorageProvider.DeleteVerificationRequest(ctx, verificationRequest)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to delete verification request")
+ }
+
+ hostname := parsers.GetHost(gc)
+ _, nonceHash, err := utils.GenerateNonce()
+ if err != nil {
+ log.Debug().Msg("Failed to generate nonce")
+ return nil, err
+ }
+ // params.Email, params.Identifier, hostname, nonceHash, verificationRequest.RedirectURI
+ verificationToken, err := g.TokenProvider.CreateVerificationToken(&token.AuthTokenConfig{
+ User: user,
+ Nonce: nonceHash,
+ HostName: hostname,
+ LoginMethod: constants.AuthRecipeMethodBasicAuth,
+ }, verificationRequest.RedirectURI, params.Identifier)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to create verification token")
+ }
+ _, err = g.StorageProvider.AddVerificationRequest(ctx, &schemas.VerificationRequest{
+ Token: verificationToken,
+ Identifier: params.Identifier,
+ ExpiresAt: time.Now().Add(time.Minute * 30).Unix(),
+ Email: params.Email,
+ Nonce: nonceHash,
+ RedirectURI: verificationRequest.RedirectURI,
+ })
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to add verification request")
+ }
+
+ // exec it as go routine so that we can reduce the api latency
+ go g.EmailProvider.SendEmail([]string{params.Email}, params.Identifier, map[string]interface{}{
+ "user": user.ToMap(),
+ "organization": utils.GetOrganization(g.Config),
+ "verification_url": utils.GetEmailVerificationURL(verificationToken, hostname, verificationRequest.RedirectURI),
+ })
+
+ return &model.Response{
+ Message: `Verification email has been sent. Please check your inbox`,
+ }, nil
+}
diff --git a/internal/graphql/reset_password.go b/internal/graphql/reset_password.go
new file mode 100644
index 000000000..1047b5a2e
--- /dev/null
+++ b/internal/graphql/reset_password.go
@@ -0,0 +1,173 @@
+package graphql
+
+import (
+ "context"
+ "fmt"
+ "strings"
+ "time"
+
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/cookie"
+ "github.com/authorizerdev/authorizer/internal/crypto"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/parsers"
+ "github.com/authorizerdev/authorizer/internal/refs"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
+ "github.com/authorizerdev/authorizer/internal/token"
+ "github.com/authorizerdev/authorizer/internal/utils"
+ "github.com/authorizerdev/authorizer/internal/validators"
+)
+
+// ResetPassword is the method to reset password.
+// Permissions: none
+func (g *graphqlProvider) ResetPassword(ctx context.Context, params *model.ResetPasswordRequest) (*model.Response, error) {
+ log := g.Log.With().Str("func", "ResetPassword").Logger()
+ gc, err := utils.GinContextFromContext(ctx)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get GinContext")
+ return nil, err
+ }
+
+ verifyingToken := refs.StringValue(params.Token)
+ otp := refs.StringValue(params.Otp)
+ if verifyingToken == "" && otp == "" {
+ log.Debug().Msg("Token or otp is required")
+ return nil, fmt.Errorf(`token or otp is required`)
+ }
+ isTokenVerification := verifyingToken != ""
+ isOtpVerification := otp != ""
+ if isOtpVerification && refs.StringValue(params.PhoneNumber) == "" {
+ log.Debug().Msg("Phone number is required")
+ return nil, fmt.Errorf(`phone number is required`)
+ }
+ isBasicAuthEnabled := g.Config.EnableBasicAuthentication
+ isMobileBasicAuthEnabled := g.Config.EnableMobileBasicAuthentication
+ if isTokenVerification && !isBasicAuthEnabled {
+ log.Debug().Msg("Basic authentication is disabled")
+ return nil, fmt.Errorf(`basic authentication is disabled for this instance`)
+ }
+ if isOtpVerification && !isMobileBasicAuthEnabled {
+ log.Debug().Msg("Mobile basic authentication is disabled")
+ return nil, fmt.Errorf(`mobile basic authentication is disabled for this instance`)
+ }
+ email := ""
+ phoneNumber := refs.StringValue(params.PhoneNumber)
+ var user *schemas.User
+ var verificationRequest *schemas.VerificationRequest
+ var otpRequest *schemas.OTP
+ if isTokenVerification {
+ verificationRequest, err = g.StorageProvider.GetVerificationRequestByToken(ctx, verifyingToken)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get verification request")
+ return nil, fmt.Errorf(`invalid token`)
+ }
+ // verify if token exists in db
+ hostname := parsers.GetHost(gc)
+ claim, err := g.TokenProvider.ParseJWTToken(verifyingToken)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to parse token")
+ return nil, fmt.Errorf(`invalid token`)
+ }
+
+ if ok, err := g.TokenProvider.ValidateJWTClaims(claim, &token.AuthTokenConfig{
+ HostName: hostname,
+ Nonce: verificationRequest.Nonce,
+ User: &schemas.User{
+ ID: "",
+ Email: refs.NewStringRef(verificationRequest.Email),
+ },
+ }); !ok || err != nil {
+ log.Debug().Err(err).Msg("Failed to validate jwt claims")
+ return nil, fmt.Errorf(`invalid token`)
+ }
+ email = claim["sub"].(string)
+ user, err = g.StorageProvider.GetUserByEmail(ctx, email)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get user")
+ return nil, err
+ }
+ }
+ if isOtpVerification {
+ mfaSession, err := cookie.GetMfaSession(gc)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get otp request by email")
+ return nil, fmt.Errorf(`invalid session: %s`, err.Error())
+ }
+ // Get user by phone number
+ user, err = g.StorageProvider.GetUserByPhoneNumber(ctx, phoneNumber)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get user by phone number")
+ return nil, fmt.Errorf(`user not found`)
+ }
+ if _, err := g.MemoryStoreProvider.GetMfaSession(user.ID, mfaSession); err != nil {
+ log.Debug().Err(err).Msg("Failed to get mfa session")
+ return nil, fmt.Errorf(`invalid session: %s`, err.Error())
+ }
+ otpRequest, err = g.StorageProvider.GetOTPByPhoneNumber(ctx, phoneNumber)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get otp request by phone number")
+ return nil, fmt.Errorf(`invalid otp`)
+ }
+ if otpRequest.Otp != otp {
+ log.Debug().Msg("Failed to verify otp request: Incorrect value")
+ return nil, fmt.Errorf(`invalid otp`)
+ }
+ }
+ if params.Password != params.ConfirmPassword {
+ log.Debug().Msg("Passwords do not match")
+ return nil, fmt.Errorf(`passwords don't match`)
+ }
+ if err := validators.IsValidPassword(params.Password, !g.Config.EnableStrongPassword); err != nil {
+ log.Debug().Msg("Invalid password")
+ return nil, err
+ }
+ log = log.With().Str("email", email).Str("phone_number", phoneNumber).Logger()
+ password, _ := crypto.EncryptPassword(params.Password)
+ user.Password = &password
+ signupMethod := user.SignupMethods
+ if !strings.Contains(signupMethod, constants.AuthRecipeMethodBasicAuth) && isTokenVerification {
+ signupMethod = signupMethod + "," + constants.AuthRecipeMethodBasicAuth
+ // helpful if user has not signed up with basic auth
+ if user.EmailVerifiedAt == nil {
+ now := time.Now().Unix()
+ user.EmailVerifiedAt = &now
+ }
+ }
+ if !strings.Contains(signupMethod, constants.AuthRecipeMethodMobileOTP) && isOtpVerification {
+ signupMethod = signupMethod + "," + constants.AuthRecipeMethodMobileOTP
+ // helpful if user has not signed up with basic auth
+ if user.PhoneNumberVerifiedAt == nil {
+ now := time.Now().Unix()
+ user.PhoneNumberVerifiedAt = &now
+ }
+ }
+ user.SignupMethods = signupMethod
+ isMFAEnforced := g.Config.EnforceMFA
+ if isMFAEnforced {
+ user.IsMultiFactorAuthEnabled = refs.NewBoolRef(true)
+ }
+ _, err = g.StorageProvider.UpdateUser(ctx, user)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to update user")
+ return nil, err
+ }
+ if isTokenVerification {
+ // delete from verification table
+ err = g.StorageProvider.DeleteVerificationRequest(ctx, verificationRequest)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to delete verification request")
+ return nil, err
+ }
+ }
+ if isOtpVerification {
+ // delete from otp table
+ err = g.StorageProvider.DeleteOTP(ctx, otpRequest)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to delete otp request")
+ return nil, err
+ }
+ }
+ return &model.Response{
+ Message: `Password updated successfully.`,
+ }, nil
+}
diff --git a/internal/graphql/revoke.go b/internal/graphql/revoke.go
new file mode 100644
index 000000000..616cb2813
--- /dev/null
+++ b/internal/graphql/revoke.go
@@ -0,0 +1,57 @@
+package graphql
+
+import (
+ "context"
+ "errors"
+ "strings"
+
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+)
+
+// Revoke is the method to revoke refresh token
+func (g *graphqlProvider) Revoke(ctx context.Context, params *model.OAuthRevokeRequest) (*model.Response, error) {
+ log := g.Log.With().Str("func", "Revoke").Logger()
+ token := strings.TrimSpace(params.RefreshToken)
+ if token == "" {
+ log.Error().Msg("Refresh token is empty")
+ return nil, errors.New("missing refresh token")
+ }
+ claims, err := g.TokenProvider.ParseJWTToken(token)
+ if err != nil {
+ log.Debug().Err(err).Msg("failed to parse jwt")
+ return nil, err
+ }
+
+ userID := claims["sub"].(string)
+ loginMethod := claims["login_method"]
+ sessionToken := userID
+ if loginMethod != nil && loginMethod != "" {
+ sessionToken = loginMethod.(string) + ":" + userID
+ }
+
+ existingToken, err := g.MemoryStoreProvider.GetUserSession(sessionToken, constants.TokenTypeRefreshToken+"_"+claims["nonce"].(string))
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get refresh token")
+ return nil, err
+ }
+
+ if existingToken == "" {
+ log.Debug().Msg("Token not found")
+ return nil, errors.New("token not found")
+ }
+
+ if existingToken != token {
+ log.Debug().Msg("Token does not match")
+ return nil, errors.New("token does not match")
+ }
+
+ // Remove the token from the memory store
+ if err := g.MemoryStoreProvider.DeleteUserSession(sessionToken, claims["nonce"].(string)); err != nil {
+ log.Debug().Err(err).Msg("failed to delete user session")
+ return nil, err
+ }
+ return &model.Response{
+ Message: "Token revoked",
+ }, nil
+}
diff --git a/internal/graphql/revoke_access.go b/internal/graphql/revoke_access.go
new file mode 100644
index 000000000..9dafc0ed8
--- /dev/null
+++ b/internal/graphql/revoke_access.go
@@ -0,0 +1,50 @@
+package graphql
+
+import (
+ "context"
+ "fmt"
+ "time"
+
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/utils"
+)
+
+// RevokeAccess is the method to revoke access of a user.
+// Permission: authorizer:admin
+func (g *graphqlProvider) RevokeAccess(ctx context.Context, params *model.UpdateAccessRequest) (*model.Response, error) {
+ log := g.Log.With().Str("func", "RevokeAccess").Logger()
+ gc, err := utils.GinContextFromContext(ctx)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get GinContext")
+ return nil, err
+ }
+ if !g.TokenProvider.IsSuperAdmin(gc) {
+ log.Debug().Msg("Not logged in as super admin")
+ return nil, fmt.Errorf("unauthorized")
+ }
+ log = log.With().Str("user_id", params.UserID).Logger()
+ user, err := g.StorageProvider.GetUserByID(ctx, params.UserID)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get user by id")
+ return nil, err
+ }
+
+ now := time.Now().Unix()
+ user.RevokedTimestamp = &now
+
+ user, err = g.StorageProvider.UpdateUser(ctx, user)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to update user")
+ return nil, err
+ }
+
+ go func() {
+ g.MemoryStoreProvider.DeleteAllUserSessions(user.ID)
+ g.EventsProvider.RegisterEvent(ctx, constants.UserAccessRevokedWebhookEvent, "", user)
+ }()
+
+ return &model.Response{
+ Message: `user access revoked successfully`,
+ }, nil
+}
diff --git a/internal/graphql/session.go b/internal/graphql/session.go
new file mode 100644
index 000000000..61ee6baab
--- /dev/null
+++ b/internal/graphql/session.go
@@ -0,0 +1,114 @@
+package graphql
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "time"
+
+ "github.com/google/uuid"
+
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/cookie"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/parsers"
+ "github.com/authorizerdev/authorizer/internal/token"
+ "github.com/authorizerdev/authorizer/internal/utils"
+)
+
+// Session is the method to get session.
+// It also refreshes the session token.
+// TODO allow validating with code and code verifier instead of cookie (PKCE flow)
+func (g *graphqlProvider) Session(ctx context.Context, params *model.SessionQueryRequest) (*model.AuthResponse, error) {
+ log := g.Log.With().Str("func", "Session").Logger()
+ gc, err := utils.GinContextFromContext(ctx)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get GinContext")
+ return nil, err
+ }
+
+ sessionToken, err := cookie.GetSession(gc)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get session token")
+ return nil, errors.New("unauthorized")
+ }
+
+ // get session from cookie
+ claims, err := g.TokenProvider.ValidateBrowserSession(gc, sessionToken)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to validate session token")
+ return nil, errors.New("unauthorized")
+ }
+ userID := claims.Subject
+ log = log.With().Str("user_id", userID).Logger()
+ user, err := g.StorageProvider.GetUserByID(ctx, userID)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get user")
+ return nil, err
+ }
+
+ // refresh token has "roles" as claim
+ claimRoleInterface := claims.Roles
+ claimRoles := []string{}
+ claimRoles = append(claimRoles, claimRoleInterface...)
+
+ if params != nil && params.Roles != nil && len(params.Roles) > 0 {
+ for _, v := range params.Roles {
+ if !utils.StringSliceContains(claimRoles, v) {
+ log.Debug().Msg("User does not have required role")
+ return nil, fmt.Errorf(`unauthorized`)
+ }
+ }
+ }
+
+ scope := []string{"openid", "email", "profile"}
+ if params != nil && params.Scope != nil && len(scope) > 0 {
+ scope = params.Scope
+ }
+
+ nonce := uuid.New().String()
+ hostname := parsers.GetHost(gc)
+ // user, claimRoles, scope, claimg.LoginMethod, nonce, ""
+ authToken, err := g.TokenProvider.CreateAuthToken(gc, &token.AuthTokenConfig{
+ User: user,
+ Nonce: nonce,
+ Roles: claimRoles,
+ Scope: scope,
+ LoginMethod: claims.LoginMethod,
+ HostName: hostname,
+ })
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to CreateAuthToken")
+ return nil, err
+ }
+
+ // rollover the session for security
+ sessionKey := userID
+ if claims.LoginMethod != "" {
+ sessionKey = claims.LoginMethod + ":" + userID
+ }
+ go g.MemoryStoreProvider.DeleteUserSession(sessionKey, claims.Nonce)
+
+ expiresIn := authToken.AccessToken.ExpiresAt - time.Now().Unix()
+ if expiresIn <= 0 {
+ expiresIn = 1
+ }
+
+ res := &model.AuthResponse{
+ Message: `Session token refreshed`,
+ AccessToken: &authToken.AccessToken.Token,
+ ExpiresIn: &expiresIn,
+ IDToken: &authToken.IDToken.Token,
+ User: user.AsAPIUser(),
+ }
+
+ cookie.SetSession(gc, authToken.FingerPrintHash, g.Config.AppCookieSecure)
+ g.MemoryStoreProvider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash, authToken.SessionTokenExpiresAt)
+ g.MemoryStoreProvider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token, authToken.AccessToken.ExpiresAt)
+
+ if authToken.RefreshToken != nil {
+ res.RefreshToken = &authToken.RefreshToken.Token
+ g.MemoryStoreProvider.SetUserSession(sessionKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token, authToken.RefreshToken.ExpiresAt)
+ }
+ return res, nil
+}
diff --git a/internal/graphql/signup.go b/internal/graphql/signup.go
new file mode 100644
index 000000000..0453ae30c
--- /dev/null
+++ b/internal/graphql/signup.go
@@ -0,0 +1,372 @@
+package graphql
+
+import (
+ "context"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "strings"
+ "time"
+
+ "github.com/google/uuid"
+
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/cookie"
+ "github.com/authorizerdev/authorizer/internal/crypto"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/parsers"
+ "github.com/authorizerdev/authorizer/internal/refs"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
+ "github.com/authorizerdev/authorizer/internal/token"
+ "github.com/authorizerdev/authorizer/internal/utils"
+ "github.com/authorizerdev/authorizer/internal/validators"
+)
+
+// SignUp is the method to singup user
+// Permission: none
+func (g *graphqlProvider) SignUp(ctx context.Context, params *model.SignUpRequest) (*model.AuthResponse, error) {
+ log := g.Log.With().Str("func", "SignUp").Logger()
+ gc, err := utils.GinContextFromContext(ctx)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get GinContext")
+ return nil, err
+ }
+
+ email := strings.TrimSpace(refs.StringValue(params.Email))
+ phoneNumber := strings.TrimSpace(refs.StringValue(params.PhoneNumber))
+ if email == "" && phoneNumber == "" {
+ log.Debug().Msg("Email or phone number is required")
+ return nil, fmt.Errorf(`email or phone number is required`)
+ }
+
+ isSignupEnabled := g.Config.EnableSignup
+ if !isSignupEnabled {
+ log.Debug().Msg("Signup is disabled")
+ return nil, fmt.Errorf(`signup is disabled for this instance`)
+ }
+
+ isBasicAuthEnabled := g.Config.EnableBasicAuthentication
+ isMobileBasicAuthEnabled := g.Config.EnableMobileBasicAuthentication
+ if params.ConfirmPassword != params.Password {
+ log.Debug().Msg("Passwords do not match")
+ return nil, fmt.Errorf(`password and confirm password does not match`)
+ }
+ if err := validators.IsValidPassword(params.Password, !g.Config.EnableStrongPassword); err != nil {
+ log.Debug().Msg("Invalid password")
+ return nil, err
+ }
+
+ log = log.With().Str("email", email).Str("phone_number", phoneNumber).Logger()
+ isEmailSignup := email != ""
+ isMobileSignup := phoneNumber != ""
+ if !isBasicAuthEnabled && isEmailSignup {
+ log.Debug().Msg("Basic authentication is disabled")
+ return nil, fmt.Errorf(`basic authentication is disabled for this instance`)
+ }
+ if !isMobileBasicAuthEnabled && isMobileSignup {
+ log.Debug().Msg("Mobile basic authentication is disabled")
+ return nil, fmt.Errorf(`mobile basic authentication is disabled for this instance`)
+ }
+ if isEmailSignup && !validators.IsValidEmail(email) {
+ log.Debug().Msg("Invalid email")
+ return nil, fmt.Errorf(`invalid email address`)
+ }
+ if isMobileSignup && (phoneNumber == "" || len(phoneNumber) < 10) {
+ log.Debug().Msg("Invalid phone number")
+ return nil, fmt.Errorf(`invalid phone number`)
+ }
+ // find user with email / phone number
+ if isEmailSignup {
+ existingUser, err := g.StorageProvider.GetUserByEmail(ctx, email)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get user by email")
+ }
+ if existingUser != nil {
+ if existingUser.EmailVerifiedAt != nil {
+ // email is verified
+ log.Debug().Msg("Email is already verified and signed up.")
+ return nil, fmt.Errorf(`%s has already signed up`, email)
+ } else if existingUser.ID != "" && existingUser.EmailVerifiedAt == nil {
+ log.Debug().Msg("Email is already signed up. Verification pending...")
+ return nil, fmt.Errorf("%s has already signed up. please complete the email verification process or reset the password", email)
+ }
+ }
+ } else {
+ existingUser, err := g.StorageProvider.GetUserByPhoneNumber(ctx, phoneNumber)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get user by phone number")
+ }
+ if existingUser != nil {
+ if existingUser.PhoneNumberVerifiedAt != nil {
+ // email is verified
+ log.Debug().Msg("Phone number is already verified and signed up.")
+ return nil, fmt.Errorf(`%s has already signed up`, phoneNumber)
+ } else if existingUser.ID != "" && existingUser.PhoneNumberVerifiedAt == nil {
+ log.Debug().Msg("Phone number is already signed up. Verification pending...")
+ return nil, fmt.Errorf("%s has already signed up. please complete the phone number verification process or reset the password", phoneNumber)
+ }
+ }
+ }
+
+ inputRoles := params.Roles
+ if len(inputRoles) > 0 {
+ // check if roles exists
+ roles := g.Config.Roles
+ if !validators.IsValidRoles(inputRoles, roles) {
+ log.Debug().Err(err).Strs("roles", params.Roles).Msg("Invalid roles")
+ return nil, fmt.Errorf(`invalid roles`)
+ }
+ } else {
+ inputRoles = g.Config.DefaultRoles
+ }
+ user := &schemas.User{}
+ user.Roles = strings.Join(inputRoles, ",")
+ password, _ := crypto.EncryptPassword(params.Password)
+ user.Password = &password
+ if email != "" {
+ user.SignupMethods = constants.AuthRecipeMethodBasicAuth
+ user.Email = &email
+ }
+ if params.GivenName != nil {
+ user.GivenName = params.GivenName
+ }
+
+ if params.FamilyName != nil {
+ user.FamilyName = params.FamilyName
+ }
+
+ if params.MiddleName != nil {
+ user.MiddleName = params.MiddleName
+ }
+
+ if params.Nickname != nil {
+ user.Nickname = params.Nickname
+ }
+
+ if params.Gender != nil {
+ user.Gender = params.Gender
+ }
+
+ if params.Birthdate != nil {
+ user.Birthdate = params.Birthdate
+ }
+
+ if phoneNumber != "" {
+ user.SignupMethods = constants.AuthRecipeMethodMobileBasicAuth
+ user.PhoneNumber = refs.NewStringRef(phoneNumber)
+ }
+
+ if params.Picture != nil {
+ user.Picture = params.Picture
+ }
+
+ if params.IsMultiFactorAuthEnabled != nil {
+ user.IsMultiFactorAuthEnabled = params.IsMultiFactorAuthEnabled
+ }
+
+ isMFAEnforced := g.Config.EnforceMFA
+ if isMFAEnforced {
+ user.IsMultiFactorAuthEnabled = refs.NewBoolRef(true)
+ }
+
+ if params.AppData != nil {
+ appDataString := ""
+ appDataBytes, err := json.Marshal(params.AppData)
+ if err != nil {
+ log.Debug().Msg("failed to marshall source app_data")
+ return nil, errors.New("malformed app_data")
+ }
+ appDataString = string(appDataBytes)
+ user.AppData = &appDataString
+ }
+ isEmailServiceEnabled := g.Config.IsEmailServiceEnabled
+ isEmailVerificationEnabled := g.Config.EnableEmailVerification && isEmailServiceEnabled
+ if !isEmailVerificationEnabled && isEmailSignup {
+ now := time.Now().Unix()
+ user.EmailVerifiedAt = &now
+ }
+ isSMSServiceEnabled := g.Config.IsSMSServiceEnabled
+ isPhoneVerificationEnabled := g.Config.EnablePhoneVerification && isSMSServiceEnabled
+ if !isPhoneVerificationEnabled && isMobileSignup {
+ now := time.Now().Unix()
+ user.PhoneNumberVerifiedAt = &now
+ }
+ user, err = g.StorageProvider.AddUser(ctx, user)
+ if err != nil {
+ log.Debug().Err(err).Msg("failed to add user")
+ return nil, err
+ }
+ roles := strings.Split(user.Roles, ",")
+ userToReturn := user.AsAPIUser()
+ hostname := parsers.GetHost(gc)
+ if isEmailVerificationEnabled && isEmailSignup {
+ // insert verification request
+ _, nonceHash, err := utils.GenerateNonce()
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to generate nonce")
+ return nil, err
+ }
+ verificationType := constants.VerificationTypeBasicAuthSignup
+ redirectURL := parsers.GetAppURL(gc)
+ if params.RedirectURI != nil {
+ redirectURL = *params.RedirectURI
+ }
+ verificationToken, err := g.TokenProvider.CreateVerificationToken(&token.AuthTokenConfig{
+ Nonce: nonceHash,
+ HostName: hostname,
+ User: user,
+ LoginMethod: constants.AuthRecipeMethodBasicAuth,
+ }, redirectURL, verificationType)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to create verification token")
+ return nil, err
+ }
+ _, err = g.StorageProvider.AddVerificationRequest(ctx, &schemas.VerificationRequest{
+ Token: verificationToken,
+ Identifier: verificationType,
+ ExpiresAt: time.Now().Add(time.Minute * 30).Unix(),
+ Email: email,
+ Nonce: nonceHash,
+ RedirectURI: redirectURL,
+ })
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to add verification request")
+ return nil, err
+ }
+ // exec it as go routine so that we can reduce the api latency
+ go func() {
+ // exec it as go routine so that we can reduce the api latency
+ g.EmailProvider.SendEmail([]string{email}, constants.VerificationTypeBasicAuthSignup, map[string]interface{}{
+ "user": user.ToMap(),
+ "organization": utils.GetOrganization(g.Config),
+ "verification_url": utils.GetEmailVerificationURL(verificationToken, hostname, redirectURL),
+ })
+ g.EventsProvider.RegisterEvent(ctx, constants.UserCreatedWebhookEvent, constants.AuthRecipeMethodBasicAuth, user)
+ }()
+
+ return &model.AuthResponse{
+ Message: `Verification email has been sent. Please check your inbox`,
+ }, nil
+ } else if isPhoneVerificationEnabled && isMobileSignup {
+ duration, _ := time.ParseDuration("10m")
+ smsCode := utils.GenerateOTP()
+ smsBody := strings.Builder{}
+ smsBody.WriteString("Your verification code is: ")
+ smsBody.WriteString(smsCode)
+ expiresAt := time.Now().Add(duration).Unix()
+ _, err = g.StorageProvider.UpsertOTP(ctx, &schemas.OTP{
+ PhoneNumber: phoneNumber,
+ Otp: smsCode,
+ ExpiresAt: expiresAt,
+ })
+ if err != nil {
+ log.Debug().Err(err).Msg("error while upserting OTP")
+ return nil, err
+ }
+ mfaSession := uuid.NewString()
+ err = g.MemoryStoreProvider.SetMfaSession(user.ID, mfaSession, expiresAt)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to add mfasession")
+ return nil, err
+ }
+ cookie.SetMfaSession(gc, mfaSession, g.Config.AppCookieSecure)
+ go func() {
+ g.SMSProvider.SendSMS(phoneNumber, smsBody.String())
+ g.EventsProvider.RegisterEvent(ctx, constants.UserCreatedWebhookEvent, constants.AuthRecipeMethodMobileBasicAuth, user)
+ }()
+ return &model.AuthResponse{
+ Message: "Please check the OTP in your inbox",
+ ShouldShowMobileOtpScreen: refs.NewBoolRef(true),
+ }, nil
+ }
+ scope := []string{"openid", "email", "profile"}
+ if params.Scope != nil && len(scope) > 0 {
+ scope = params.Scope
+ }
+
+ code := ""
+ codeChallenge := ""
+ nonce := ""
+ if params.State != nil {
+ // Get state from store
+ authorizeState, _ := g.MemoryStoreProvider.GetState(refs.StringValue(params.State))
+ if authorizeState != "" {
+ authorizeStateSplit := strings.Split(authorizeState, "@@")
+ if len(authorizeStateSplit) > 1 {
+ code = authorizeStateSplit[0]
+ codeChallenge = authorizeStateSplit[1]
+ } else {
+ nonce = authorizeState
+ }
+ go g.MemoryStoreProvider.RemoveState(refs.StringValue(params.State))
+ }
+ }
+
+ if nonce == "" {
+ nonce = uuid.New().String()
+ }
+ authToken, err := g.TokenProvider.CreateAuthToken(gc, &token.AuthTokenConfig{
+ User: user,
+ Roles: roles,
+ Scope: scope,
+ Nonce: nonce,
+ Code: code,
+ LoginMethod: constants.AuthRecipeMethodBasicAuth,
+ HostName: hostname,
+ })
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to create auth token")
+ return nil, err
+ }
+
+ // Code challenge could be optional if PKCE flow is not used
+ if code != "" {
+ if err := g.MemoryStoreProvider.SetState(code, codeChallenge+"@@"+authToken.FingerPrintHash); err != nil {
+ log.Debug().Err(err).Msg("SetState failed")
+ return nil, err
+ }
+ }
+
+ expiresIn := authToken.AccessToken.ExpiresAt - time.Now().Unix()
+ if expiresIn <= 0 {
+ expiresIn = 1
+ }
+
+ res := &model.AuthResponse{
+ Message: `Signed up successfully.`,
+ AccessToken: &authToken.AccessToken.Token,
+ ExpiresIn: &expiresIn,
+ User: userToReturn,
+ }
+
+ sessionKey := constants.AuthRecipeMethodBasicAuth + ":" + user.ID
+ cookie.SetSession(gc, authToken.FingerPrintHash, g.Config.AppCookieSecure)
+ g.MemoryStoreProvider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash, authToken.SessionTokenExpiresAt)
+ g.MemoryStoreProvider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token, authToken.AccessToken.ExpiresAt)
+
+ if authToken.RefreshToken != nil {
+ res.RefreshToken = &authToken.RefreshToken.Token
+ g.MemoryStoreProvider.SetUserSession(sessionKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token, authToken.RefreshToken.ExpiresAt)
+ }
+
+ go func() {
+ g.EventsProvider.RegisterEvent(ctx, constants.UserCreatedWebhookEvent, constants.AuthRecipeMethodBasicAuth, user)
+ if isEmailSignup {
+ g.EventsProvider.RegisterEvent(ctx, constants.UserSignUpWebhookEvent, constants.AuthRecipeMethodBasicAuth, user)
+ g.EventsProvider.RegisterEvent(ctx, constants.UserLoginWebhookEvent, constants.AuthRecipeMethodBasicAuth, user)
+ } else {
+ g.EventsProvider.RegisterEvent(ctx, constants.UserSignUpWebhookEvent, constants.AuthRecipeMethodMobileBasicAuth, user)
+ g.EventsProvider.RegisterEvent(ctx, constants.UserLoginWebhookEvent, constants.AuthRecipeMethodMobileBasicAuth, user)
+ }
+
+ if err := g.StorageProvider.AddSession(ctx, &schemas.Session{
+ UserID: user.ID,
+ UserAgent: utils.GetUserAgent(gc.Request),
+ IP: utils.GetIP(gc.Request),
+ }); err != nil {
+ log.Debug().Err(err).Msg("Failed to add session")
+ }
+ }()
+
+ return res, nil
+}
diff --git a/server/resolvers/test_endpoint.go b/internal/graphql/test_endpoint.go
similarity index 61%
rename from server/resolvers/test_endpoint.go
rename to internal/graphql/test_endpoint.go
index c0cdb230a..d9c10b8e5 100644
--- a/server/resolvers/test_endpoint.go
+++ b/internal/graphql/test_endpoint.go
@@ -1,4 +1,4 @@
-package resolvers
+package graphql
import (
"bytes"
@@ -9,31 +9,30 @@ import (
"net/http"
"time"
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/refs"
- "github.com/authorizerdev/authorizer/server/token"
- "github.com/authorizerdev/authorizer/server/utils"
- "github.com/authorizerdev/authorizer/server/validators"
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/refs"
+ "github.com/authorizerdev/authorizer/internal/utils"
+ "github.com/authorizerdev/authorizer/internal/validators"
"github.com/google/uuid"
- log "github.com/sirupsen/logrus"
)
-// TestEndpointResolver resolver to test webhook endpoints
-func TestEndpointResolver(ctx context.Context, params model.TestEndpointRequest) (*model.TestEndpointResponse, error) {
+// TestEndpoint is a service to test a webhook endpoint
+// Permission: authorizer:admin
+func (g *graphqlProvider) TestEndpoint(ctx context.Context, params *model.TestEndpointRequest) (*model.TestEndpointResponse, error) {
+ log := g.Log.With().Str("func", "TestEndpoint").Logger()
gc, err := utils.GinContextFromContext(ctx)
if err != nil {
- log.Debug("Failed to get GinContext: ", err)
+ log.Debug().Err(err).Msg("Failed to get GinContext")
return nil, err
}
-
- if !token.IsSuperAdmin(gc) {
- log.Debug("Not logged in as super admin")
+ if !g.TokenProvider.IsSuperAdmin(gc) {
+ log.Debug().Msg("Not logged in as super admin")
return nil, fmt.Errorf("unauthorized")
}
if !validators.IsValidWebhookEventName(params.EventName) {
- log.Debug("Invalid event name: ", params.EventName)
+ log.Debug().Str("event_name", params.EventName).Msg("Invalid event name")
return nil, fmt.Errorf("invalid event_name %s", params.EventName)
}
@@ -48,13 +47,13 @@ func TestEndpointResolver(ctx context.Context, params model.TestEndpointRequest)
userBytes, err := json.Marshal(user)
if err != nil {
- log.Debug("error marshalling user obj: ", err)
+ log.Debug().Err(err).Msg("error marshalling user obj")
return nil, err
}
userMap := map[string]interface{}{}
err = json.Unmarshal(userBytes, &userMap)
if err != nil {
- log.Debug("error un-marshalling user obj: ", err)
+ log.Debug().Err(err).Msg("error un-marshalling user obj")
return nil, err
}
@@ -69,13 +68,13 @@ func TestEndpointResolver(ctx context.Context, params model.TestEndpointRequest)
requestBody, err := json.Marshal(reqBody)
if err != nil {
- log.Debug("error marshalling requestBody obj: ", err)
+ log.Debug().Err(err).Msg("error marshalling requestBody obj")
return nil, err
}
req, err := http.NewRequest("POST", params.Endpoint, bytes.NewBuffer(requestBody))
if err != nil {
- log.Debug("error creating post request: ", err)
+ log.Debug().Err(err).Msg("error creating post request")
return nil, err
}
req.Header.Set("Content-Type", "application/json")
@@ -85,14 +84,14 @@ func TestEndpointResolver(ctx context.Context, params model.TestEndpointRequest)
client := &http.Client{Timeout: time.Second * 30}
resp, err := client.Do(req)
if err != nil {
- log.Debug("error making request: ", err)
+ log.Debug().Err(err).Msg("error making request")
return nil, err
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
- log.Debug("error reading response: ", err)
+ log.Debug().Err(err).Msg("error reading response")
return nil, err
}
diff --git a/server/resolvers/update_email_template.go b/internal/graphql/update_email_template.go
similarity index 55%
rename from server/resolvers/update_email_template.go
rename to internal/graphql/update_email_template.go
index c08a49f6d..e9e18e430 100644
--- a/server/resolvers/update_email_template.go
+++ b/internal/graphql/update_email_template.go
@@ -1,49 +1,47 @@
-package resolvers
+package graphql
import (
"context"
"fmt"
"strings"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/db/models"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/refs"
- "github.com/authorizerdev/authorizer/server/token"
- "github.com/authorizerdev/authorizer/server/utils"
- "github.com/authorizerdev/authorizer/server/validators"
- log "github.com/sirupsen/logrus"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/refs"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
+ "github.com/authorizerdev/authorizer/internal/utils"
+ "github.com/authorizerdev/authorizer/internal/validators"
)
-// UpdateEmailTemplateResolver resolver for update email template mutation
-func UpdateEmailTemplateResolver(ctx context.Context, params model.UpdateEmailTemplateRequest) (*model.Response, error) {
+// UpdateEmailTemplate for update email template mutation
+// Permission: authorizer:admin
+func (g *graphqlProvider) UpdateEmailTemplate(ctx context.Context, params *model.UpdateEmailTemplateRequest) (*model.Response, error) {
+ log := g.Log.With().Str("func", "UpdateEmailTemplate").Logger()
gc, err := utils.GinContextFromContext(ctx)
if err != nil {
- log.Debug("Failed to get GinContext: ", err)
+ log.Debug().Err(err).Msg("Failed to get GinContext")
return nil, err
}
-
- if !token.IsSuperAdmin(gc) {
- log.Debug("Not logged in as super admin")
+ if !g.TokenProvider.IsSuperAdmin(gc) {
+ log.Debug().Msg("Not logged in as super admin")
return nil, fmt.Errorf("unauthorized")
}
- emailTemplate, err := db.Provider.GetEmailTemplateByID(ctx, params.ID)
+ emailTemplate, err := g.StorageProvider.GetEmailTemplateByID(ctx, params.ID)
if err != nil {
- log.Debug("failed to get email template: ", err)
+ log.Debug().Err(err).Msg("failed GetEmailTemplateByID")
return nil, err
}
- emailTemplateDetails := &models.EmailTemplate{
+ emailTemplateDetails := &schemas.EmailTemplate{
ID: emailTemplate.ID,
Key: emailTemplate.ID,
EventName: emailTemplate.EventName,
- CreatedAt: refs.Int64Value(emailTemplate.CreatedAt),
+ CreatedAt: emailTemplate.CreatedAt,
}
if params.EventName != nil && emailTemplateDetails.EventName != refs.StringValue(params.EventName) {
if isValid := validators.IsValidEmailTemplateEventName(refs.StringValue(params.EventName)); !isValid {
- log.Debug("invalid event name: ", refs.StringValue(params.EventName))
+ log.Debug().Str("event_name", refs.StringValue(params.EventName)).Msg("invalid event name")
return nil, fmt.Errorf("invalid event name %s", refs.StringValue(params.EventName))
}
emailTemplateDetails.EventName = refs.StringValue(params.EventName)
@@ -51,7 +49,7 @@ func UpdateEmailTemplateResolver(ctx context.Context, params model.UpdateEmailTe
if params.Subject != nil && emailTemplateDetails.Subject != refs.StringValue(params.Subject) {
if strings.TrimSpace(refs.StringValue(params.Subject)) == "" {
- log.Debug("empty subject not allowed")
+ log.Debug().Msg("empty subject not allowed")
return nil, fmt.Errorf("empty subject not allowed")
}
emailTemplateDetails.Subject = refs.StringValue(params.Subject)
@@ -59,7 +57,7 @@ func UpdateEmailTemplateResolver(ctx context.Context, params model.UpdateEmailTe
if params.Template != nil && emailTemplateDetails.Template != refs.StringValue(params.Template) {
if strings.TrimSpace(refs.StringValue(params.Template)) == "" {
- log.Debug("empty template not allowed")
+ log.Debug().Msg("empty template not allowed")
return nil, fmt.Errorf("empty template not allowed")
}
emailTemplateDetails.Template = refs.StringValue(params.Template)
@@ -67,14 +65,15 @@ func UpdateEmailTemplateResolver(ctx context.Context, params model.UpdateEmailTe
if params.Design != nil && emailTemplateDetails.Design != refs.StringValue(params.Design) {
if strings.TrimSpace(refs.StringValue(params.Design)) == "" {
- log.Debug("empty design not allowed")
+ log.Debug().Msg("empty design not allowed")
return nil, fmt.Errorf("empty design not allowed")
}
emailTemplateDetails.Design = refs.StringValue(params.Design)
}
- _, err = db.Provider.UpdateEmailTemplate(ctx, emailTemplateDetails)
+ _, err = g.StorageProvider.UpdateEmailTemplate(ctx, emailTemplateDetails)
if err != nil {
+ log.Debug().Err(err).Msg("failed UpdateEmailTemplate")
return nil, err
}
diff --git a/server/resolvers/update_profile.go b/internal/graphql/update_profile.go
similarity index 50%
rename from server/resolvers/update_profile.go
rename to internal/graphql/update_profile.go
index 3b9af37dd..6a7a89d61 100644
--- a/server/resolvers/update_profile.go
+++ b/internal/graphql/update_profile.go
@@ -1,4 +1,4 @@
-package resolvers
+package graphql
import (
"context"
@@ -10,50 +10,44 @@ import (
"golang.org/x/crypto/bcrypt"
- log "github.com/sirupsen/logrus"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/cookie"
- "github.com/authorizerdev/authorizer/server/crypto"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/db/models"
- "github.com/authorizerdev/authorizer/server/email"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/parsers"
- "github.com/authorizerdev/authorizer/server/refs"
- "github.com/authorizerdev/authorizer/server/token"
- "github.com/authorizerdev/authorizer/server/utils"
- "github.com/authorizerdev/authorizer/server/validators"
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/cookie"
+ "github.com/authorizerdev/authorizer/internal/crypto"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/parsers"
+ "github.com/authorizerdev/authorizer/internal/refs"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
+ "github.com/authorizerdev/authorizer/internal/token"
+ "github.com/authorizerdev/authorizer/internal/utils"
+ "github.com/authorizerdev/authorizer/internal/validators"
)
-// UpdateProfileResolver is resolver for update profile mutation
-func UpdateProfileResolver(ctx context.Context, params model.UpdateProfileInput) (*model.Response, error) {
- var res *model.Response
-
+// UpdateProfile is the method to update profile
+// Permissions: authenticated:user
+func (g *graphqlProvider) UpdateProfile(ctx context.Context, params *model.UpdateProfileRequest) (*model.Response, error) {
+ log := g.Log.With().Str("func", "UpdateProfile").Logger()
gc, err := utils.GinContextFromContext(ctx)
if err != nil {
- log.Debug("Failed to get GinContext: ", err)
- return res, err
+ log.Debug().Err(err).Msg("Failed to get GinContext")
+ return nil, err
}
- tokenData, err := token.GetUserIDFromSessionOrAccessToken(gc)
+
+ tokenData, err := g.TokenProvider.GetUserIDFromSessionOrAccessToken(gc)
if err != nil {
- log.Debug("Failed GetUserIDFromSessionOrAccessToken: ", err)
- return res, err
+ log.Debug().Err(err).Msg("Failed GetUserIDFromSessionOrAccessToken")
+ return nil, err
}
// validate if all params are not empty
if params.GivenName == nil && params.FamilyName == nil && params.Picture == nil && params.MiddleName == nil && params.Nickname == nil && params.OldPassword == nil && params.Email == nil && params.Birthdate == nil && params.Gender == nil && params.PhoneNumber == nil && params.NewPassword == nil && params.ConfirmNewPassword == nil && params.IsMultiFactorAuthEnabled == nil && params.AppData == nil {
- log.Debug("All params are empty")
- return res, fmt.Errorf("please enter at least one param to update")
+ log.Debug().Msg("All params are empty")
+ return nil, fmt.Errorf("please enter at least one param to update")
}
- log := log.WithFields(log.Fields{
- "user_id": tokenData.UserID,
- })
- user, err := db.Provider.GetUserByID(ctx, tokenData.UserID)
+ log = log.With().Str("user_id", tokenData.UserID).Logger()
+ user, err := g.StorageProvider.GetUserByID(ctx, tokenData.UserID)
if err != nil {
- log.Debug("Failed to get user by id: ", err)
- return res, err
+ log.Debug().Err(err).Msg("Failed to get user by id")
+ return nil, err
}
if params.GivenName != nil && refs.StringValue(user.GivenName) != refs.StringValue(params.GivenName) {
@@ -82,8 +76,8 @@ func UpdateProfileResolver(ctx context.Context, params model.UpdateProfileInput)
if params.PhoneNumber != nil && refs.StringValue(user.PhoneNumber) != refs.StringValue(params.PhoneNumber) {
// verify if phone number is unique
- if _, err := db.Provider.GetUserByPhoneNumber(ctx, strings.TrimSpace(refs.StringValue(params.PhoneNumber))); err == nil {
- log.Debug("user with given phone number already exists")
+ if _, err := g.StorageProvider.GetUserByPhoneNumber(ctx, strings.TrimSpace(refs.StringValue(params.PhoneNumber))); err == nil {
+ log.Debug().Msg("user with given phone number already exists")
return nil, errors.New("user with given phone number already exists")
}
user.PhoneNumber = params.PhoneNumber
@@ -96,7 +90,7 @@ func UpdateProfileResolver(ctx context.Context, params model.UpdateProfileInput)
appDataString := ""
appDataBytes, err := json.Marshal(params.AppData)
if err != nil {
- log.Debug("failed to marshall source app_data: ", err)
+ log.Debug().Err(err).Msg("failed to marshall source app_data")
return nil, errors.New("malformed app_data")
}
appDataString = string(appDataBytes)
@@ -105,35 +99,18 @@ func UpdateProfileResolver(ctx context.Context, params model.UpdateProfileInput)
// Check if the user is trying to enable or disable multi-factor authentication (MFA)
if params.IsMultiFactorAuthEnabled != nil && refs.BoolValue(user.IsMultiFactorAuthEnabled) != refs.BoolValue(params.IsMultiFactorAuthEnabled) {
// Check if totp, email or sms is enabled
- isMailOTPEnvServiceDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableMailOTPLogin)
- if err != nil {
- log.Debug("Error getting mail otp disabled: ", err)
- isMailOTPEnvServiceDisabled = false
- }
- isTOTPEnvServiceDisabled, _ := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableTOTPLogin)
- if err != nil {
- log.Debug("Error getting totp disabled: ", err)
- isTOTPEnvServiceDisabled = false
- }
- isSMSOTPEnvServiceDisabled, _ := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisablePhoneVerification)
- if err != nil {
- log.Debug("Error getting sms otp disabled: ", err)
- isSMSOTPEnvServiceDisabled = false
- }
+ isMailOTPEnvServiceEnabled := g.Config.EnableEmailOTP
+ isTOTPEnvServiceEnabled := g.Config.EnableTOTPLogin
+ isSMSOTPEnvServiceEnabled := g.Config.EnableSMSOTP
// Initialize a flag to check if enabling Mail OTP is required
- if isMailOTPEnvServiceDisabled && isTOTPEnvServiceDisabled && isSMSOTPEnvServiceDisabled {
- log.Debug("Cannot enable mfa service as all mfa services are disabled")
+ if !isMailOTPEnvServiceEnabled && !isTOTPEnvServiceEnabled && !isSMSOTPEnvServiceEnabled {
+ log.Debug().Msg("Cannot enable mfa service as all mfa services are disabled")
return nil, errors.New("cannot enable multi factor authentication as all mfa services are disabled")
}
- isMFAEnforced, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyEnforceMultiFactorAuthentication)
- if err != nil {
- log.Debug("MFA service not enabled: ", err)
- isMFAEnforced = false
- }
-
+ isMFAEnforced := g.Config.EnforceMFA
if isMFAEnforced && !refs.BoolValue(params.IsMultiFactorAuthEnabled) {
- log.Debug("Cannot disable mfa service as it is enforced:")
+ log.Debug().Msg("Cannot disable mfa service as it is enforced.")
return nil, errors.New("cannot disable multi factor authentication as it is enforced by organization")
}
@@ -143,14 +120,14 @@ func UpdateProfileResolver(ctx context.Context, params model.UpdateProfileInput)
isPasswordChanging := false
if params.NewPassword != nil && params.ConfirmNewPassword == nil {
isPasswordChanging = true
- log.Debug("confirm password is empty")
- return res, fmt.Errorf("confirm password is required")
+ log.Debug().Msg("confirm password is empty")
+ return nil, fmt.Errorf("confirm password is required")
}
if params.ConfirmNewPassword != nil && params.NewPassword == nil {
isPasswordChanging = true
- log.Debug("new password is empty")
- return res, fmt.Errorf("new password is required")
+ log.Debug().Msg("new password is empty")
+ return nil, fmt.Errorf("new password is required")
}
if params.NewPassword != nil && params.ConfirmNewPassword != nil {
@@ -158,48 +135,39 @@ func UpdateProfileResolver(ctx context.Context, params model.UpdateProfileInput)
}
if isPasswordChanging && user.Password != nil && params.OldPassword == nil {
- log.Debug("old password is empty")
- return res, fmt.Errorf("old password is required")
+ log.Debug().Msg("old password is empty")
+ return nil, fmt.Errorf("old password is required")
}
if isPasswordChanging && user.Password != nil && params.OldPassword != nil {
if err = bcrypt.CompareHashAndPassword([]byte(refs.StringValue(user.Password)), []byte(refs.StringValue(params.OldPassword))); err != nil {
- log.Debug("Failed to compare hash and old password: ", err)
- return res, fmt.Errorf("incorrect old password")
+ log.Debug().Err(err).Msg("Failed to compare hash and old password")
+ return nil, fmt.Errorf("incorrect old password")
}
}
shouldAddBasicSignUpMethod := false
- isBasicAuthDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableBasicAuthentication)
- if err != nil {
- log.Debug("Error getting basic auth disabled: ", err)
- isBasicAuthDisabled = true
- }
-
- isMobileBasicAuthDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableMobileBasicAuthentication)
- if err != nil {
- log.Debug("Error getting mobile basic auth disabled: ", err)
- isBasicAuthDisabled = true
- }
+ isBasicAuthEnabled := g.Config.EnableBasicAuthentication
+ isMobileBasicAuthEnabled := g.Config.EnableMobileBasicAuthentication
if params.NewPassword != nil && params.ConfirmNewPassword != nil {
- if isBasicAuthDisabled || isMobileBasicAuthDisabled {
- log.Debug("Cannot update password as basic authentication is disabled")
- return res, fmt.Errorf(`basic authentication is disabled for this instance`)
+ if !isBasicAuthEnabled || !isMobileBasicAuthEnabled {
+ log.Debug().Msg("Cannot update password as basic authentication is disabled")
+ return nil, fmt.Errorf(`basic authentication is disabled for this instance`)
}
if refs.StringValue(params.ConfirmNewPassword) != refs.StringValue(params.NewPassword) {
- log.Debug("Failed to compare new password and confirm new password")
- return res, fmt.Errorf(`password and confirm password does not match`)
+ log.Debug().Msg("Failed to compare new password and confirm new password")
+ return nil, fmt.Errorf(`password and confirm password does not match`)
}
if user.Password == nil || refs.StringValue(user.Password) == "" {
shouldAddBasicSignUpMethod = true
}
- if err := validators.IsValidPassword(refs.StringValue(params.NewPassword)); err != nil {
- log.Debug("Invalid password")
- return res, err
+ if err := validators.IsValidPassword(refs.StringValue(params.NewPassword), !g.Config.EnableStrongPassword); err != nil {
+ log.Debug().Msg("Invalid password")
+ return nil, err
}
password, _ := crypto.EncryptPassword(refs.StringValue(params.NewPassword))
@@ -215,51 +183,53 @@ func UpdateProfileResolver(ctx context.Context, params model.UpdateProfileInput)
if params.Email != nil && refs.StringValue(user.Email) != refs.StringValue(params.Email) {
// check if valid email
if !validators.IsValidEmail(*params.Email) {
- log.Debug("Failed to validate email: ", refs.StringValue(params.Email))
- return res, fmt.Errorf("invalid email address")
+ log.Debug().Str("email", refs.StringValue(params.Email)).Msg("Failed to validate email")
+ return nil, fmt.Errorf("invalid email address")
}
newEmail := strings.ToLower(*params.Email)
// check if valid email
if !validators.IsValidEmail(newEmail) {
- log.Debug("Failed to validate new email: ", newEmail)
- return res, fmt.Errorf("invalid new email address")
+ log.Debug().Str("new_email", newEmail).Msg("Failed to validate new email: ")
+ return nil, fmt.Errorf("invalid new email address")
}
// check if user with new email exists
- _, err := db.Provider.GetUserByEmail(ctx, newEmail)
+ _, err := g.StorageProvider.GetUserByEmail(ctx, newEmail)
// err = nil means user exists
if err == nil {
- log.Debug("Failed to get user by email: ", newEmail)
- return res, fmt.Errorf("user with this email address already exists")
+ log.Debug().Str("new_email", newEmail).Msg("User with new email already exists")
+ return nil, fmt.Errorf("user with this email address already exists")
}
- go memorystore.Provider.DeleteAllUserSessions(user.ID)
- go cookie.DeleteSession(gc)
+ go g.MemoryStoreProvider.DeleteAllUserSessions(user.ID)
+ go cookie.DeleteSession(gc, g.Config.AppCookieSecure)
user.Email = &newEmail
- isEmailVerificationDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableEmailVerification)
- if err != nil {
- log.Debug("Failed to get disable email verification env variable: ", err)
- return res, err
- }
- if !isEmailVerificationDisabled {
+ isEmailVerificationEnabled := g.Config.EnableEmailVerification
+ if isEmailVerificationEnabled {
hostname := parsers.GetHost(gc)
user.EmailVerifiedAt = nil
hasEmailChanged = true
// insert verification request
_, nonceHash, err := utils.GenerateNonce()
if err != nil {
- log.Debug("Failed to generate nonce: ", err)
- return res, err
+ log.Debug().Err(err).Msg("Failed to generate nonce")
+ return nil, err
}
verificationType := constants.VerificationTypeUpdateEmail
redirectURL := parsers.GetAppURL(gc)
- verificationToken, err := token.CreateVerificationToken(newEmail, verificationType, hostname, nonceHash, redirectURL)
+
+ verificationToken, err := g.TokenProvider.CreateVerificationToken(&token.AuthTokenConfig{
+ User: user,
+ HostName: hostname,
+ Nonce: nonceHash,
+ LoginMethod: constants.AuthRecipeMethodBasicAuth,
+ }, redirectURL, verificationType)
if err != nil {
- log.Debug("Failed to create verification token: ", err)
- return res, err
+ log.Debug().Err(err).Msg("Failed to create verification token")
+ return nil, err
}
- _, err = db.Provider.AddVerificationRequest(ctx, &models.VerificationRequest{
+ _, err = g.StorageProvider.AddVerificationRequest(ctx, &schemas.VerificationRequest{
Token: verificationToken,
Identifier: verificationType,
ExpiresAt: time.Now().Add(time.Minute * 30).Unix(),
@@ -268,31 +238,30 @@ func UpdateProfileResolver(ctx context.Context, params model.UpdateProfileInput)
RedirectURI: redirectURL,
})
if err != nil {
- log.Debug("Failed to add verification request: ", err)
- return res, err
+ log.Debug().Err(err).Msg("Failed to add verification request")
+ return nil, err
}
// exec it as go routine so that we can reduce the api latency
- go email.SendEmail([]string{refs.StringValue(user.Email)}, verificationType, map[string]interface{}{
+ go g.EmailProvider.SendEmail([]string{refs.StringValue(user.Email)}, verificationType, map[string]interface{}{
"user": user.ToMap(),
- "organization": utils.GetOrganization(),
+ "organization": utils.GetOrganization(g.Config),
"verification_url": utils.GetEmailVerificationURL(verificationToken, hostname, redirectURL),
})
}
}
- _, err = db.Provider.UpdateUser(ctx, user)
+ _, err = g.StorageProvider.UpdateUser(ctx, user)
if err != nil {
- log.Debug("Failed to update user: ", err)
- return res, err
+ log.Debug().Err(err).Msg("Failed to update user")
+ return nil, err
}
message := `Profile details updated successfully.`
if hasEmailChanged {
message += `For the email change we have sent new verification email, please verify and continue`
}
- res = &model.Response{
- Message: message,
- }
- return res, nil
+ return &model.Response{
+ Message: message,
+ }, nil
}
diff --git a/internal/graphql/update_user.go b/internal/graphql/update_user.go
new file mode 100644
index 000000000..f47ba757b
--- /dev/null
+++ b/internal/graphql/update_user.go
@@ -0,0 +1,257 @@
+package graphql
+
+import (
+ "context"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "strings"
+ "time"
+
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/parsers"
+ "github.com/authorizerdev/authorizer/internal/refs"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
+ "github.com/authorizerdev/authorizer/internal/token"
+ "github.com/authorizerdev/authorizer/internal/utils"
+ "github.com/authorizerdev/authorizer/internal/validators"
+)
+
+// UpdateUser is the method to update user details
+// Permission: authorizer:admin
+func (g *graphqlProvider) UpdateUser(ctx context.Context, params *model.UpdateUserRequest) (*model.User, error) {
+ log := g.Log.With().Str("func", "UpdateUser").Logger()
+ gc, err := utils.GinContextFromContext(ctx)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get GinContext")
+ return nil, err
+ }
+ if !g.TokenProvider.IsSuperAdmin(gc) {
+ log.Debug().Msg("Not logged in as super admin")
+ return nil, fmt.Errorf("unauthorized")
+ }
+
+ if params.ID == "" {
+ log.Debug().Msg("user id is missing")
+ return nil, fmt.Errorf("user_id is missing")
+ }
+
+ log = log.With().Str("user_id", params.ID).Logger()
+
+ if params.GivenName == nil &&
+ params.FamilyName == nil &&
+ params.Picture == nil &&
+ params.MiddleName == nil &&
+ params.Nickname == nil &&
+ params.Email == nil &&
+ params.Birthdate == nil &&
+ params.Gender == nil &&
+ params.PhoneNumber == nil &&
+ params.Roles == nil &&
+ params.IsMultiFactorAuthEnabled == nil &&
+ params.AppData == nil {
+ log.Debug().Msg("please enter atleast one param to update")
+ return nil, fmt.Errorf("please enter atleast one param to update")
+ }
+
+ user, err := g.StorageProvider.GetUserByID(ctx, params.ID)
+ if err != nil {
+ log.Debug().Err(err).Msg("failed GetUserByID")
+ return nil, fmt.Errorf(`User not found`)
+ }
+
+ if params.GivenName != nil && refs.StringValue(user.GivenName) != refs.StringValue(params.GivenName) {
+ user.GivenName = params.GivenName
+ }
+
+ if params.FamilyName != nil && refs.StringValue(user.FamilyName) != refs.StringValue(params.FamilyName) {
+ user.FamilyName = params.FamilyName
+ }
+
+ if params.MiddleName != nil && refs.StringValue(user.MiddleName) != refs.StringValue(params.MiddleName) {
+ user.MiddleName = params.MiddleName
+ }
+
+ if params.Nickname != nil && refs.StringValue(user.Nickname) != refs.StringValue(params.Nickname) {
+ user.Nickname = params.Nickname
+ }
+
+ if params.Birthdate != nil && refs.StringValue(user.Birthdate) != refs.StringValue(params.Birthdate) {
+ user.Birthdate = params.Birthdate
+ }
+
+ if params.Gender != nil && refs.StringValue(user.Gender) != refs.StringValue(params.Gender) {
+ user.Gender = params.Gender
+ }
+ // TODO
+ // if params.PhoneNumber != nil && refs.StringValue(user.PhoneNumber) != refs.StringValue(params.PhoneNumber) {
+ // // verify if phone number is unique
+ // if _, err := g.StorageProvider.GetUserByPhoneNumber(ctx, strings.TrimSpace(refs.StringValue(params.PhoneNumber))); err == nil {
+ // log.Debug().Msg("user with given phone number already exists")
+ // return nil, errors.New("user with given phone number already exists")
+ // }
+ // user.PhoneNumber = params.PhoneNumber
+ // }
+
+ if params.Picture != nil && refs.StringValue(user.Picture) != refs.StringValue(params.Picture) {
+ user.Picture = params.Picture
+ }
+
+ if params.AppData != nil {
+ appDataString := ""
+ appDataBytes, err := json.Marshal(params.AppData)
+ if err != nil {
+ log.Debug().Err(err).Msg("failed to marshal app_data")
+ return nil, errors.New("malformed app_data")
+ }
+ appDataString = string(appDataBytes)
+ user.AppData = &appDataString
+ }
+
+ if params.IsMultiFactorAuthEnabled != nil && refs.BoolValue(user.IsMultiFactorAuthEnabled) != refs.BoolValue(params.IsMultiFactorAuthEnabled) {
+ user.IsMultiFactorAuthEnabled = params.IsMultiFactorAuthEnabled
+ if refs.BoolValue(params.IsMultiFactorAuthEnabled) {
+ // Check if totp, email or sms is enabled
+ isMailOTPEnvServiceEnabled := g.Config.EnableEmailOTP
+ isTOTPEnvServiceEnabled := g.Config.EnableTOTPLogin
+ isSMSOTPEnvServiceEnabled := g.Config.EnableSMSOTP
+ // Initialize a flag to check if enabling Mail OTP is required
+ if !isMailOTPEnvServiceEnabled && !isTOTPEnvServiceEnabled && !isSMSOTPEnvServiceEnabled {
+ log.Debug().Msg("cannot enable multi factor authentication as all mfa services are disabled")
+ return nil, errors.New("cannot enable multi factor authentication as all mfa services are disabled")
+ }
+ }
+ }
+
+ if params.EmailVerified != nil {
+ if *params.EmailVerified {
+ now := time.Now().Unix()
+ user.EmailVerifiedAt = &now
+ } else {
+ user.EmailVerifiedAt = nil
+ }
+ }
+ if params.PhoneNumberVerified != nil {
+ if *params.PhoneNumberVerified {
+ now := time.Now().Unix()
+ user.PhoneNumberVerifiedAt = &now
+ } else {
+ user.PhoneNumberVerifiedAt = nil
+ }
+
+ }
+
+ if params.Email != nil && refs.StringValue(user.Email) != refs.StringValue(params.Email) {
+ // check if valid email
+ if !validators.IsValidEmail(*params.Email) {
+ log.Debug().Str("email", *params.Email).Msg("Invalid email address")
+ return nil, fmt.Errorf("invalid email address")
+ }
+ newEmail := strings.ToLower(*params.Email)
+ // check if user with new email exists
+ _, err = g.StorageProvider.GetUserByEmail(ctx, newEmail)
+ // err = nil means user exists
+ if err == nil {
+ log.Debug().Str("email", newEmail).Msg("User with email already exists")
+ return nil, fmt.Errorf("user with this email address already exists")
+ }
+
+ go g.MemoryStoreProvider.DeleteAllUserSessions(user.ID)
+
+ hostname := parsers.GetHost(gc)
+ user.Email = &newEmail
+ user.EmailVerifiedAt = nil
+ // insert verification request
+ _, nonceHash, err := utils.GenerateNonce()
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to generate nonce")
+ return nil, err
+ }
+ verificationType := constants.VerificationTypeUpdateEmail
+ redirectURL := parsers.GetAppURL(gc)
+ // newEmail, verificationType, hostname, nonceHash, redirectURL
+ verificationToken, err := g.TokenProvider.CreateVerificationToken(&token.AuthTokenConfig{
+ User: user,
+ Nonce: nonceHash,
+ HostName: hostname,
+ LoginMethod: constants.AuthRecipeMethodBasicAuth,
+ }, redirectURL, verificationType)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to create verification token")
+ return nil, err
+ }
+ _, err = g.StorageProvider.AddVerificationRequest(ctx, &schemas.VerificationRequest{
+ Token: verificationToken,
+ Identifier: verificationType,
+ ExpiresAt: time.Now().Add(time.Minute * 30).Unix(),
+ Email: newEmail,
+ Nonce: nonceHash,
+ RedirectURI: redirectURL,
+ })
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to add verification request")
+ return nil, err
+ }
+
+ // exec it as go routine so that we can reduce the api latency
+ go g.EmailProvider.SendEmail([]string{refs.StringValue(user.Email)}, constants.VerificationTypeBasicAuthSignup, map[string]interface{}{
+ "user": user.ToMap(),
+ "organization": utils.GetOrganization(g.Config),
+ "verification_url": utils.GetEmailVerificationURL(verificationToken, hostname, redirectURL),
+ })
+
+ }
+
+ if params.PhoneNumber != nil && refs.StringValue(user.PhoneNumber) != refs.StringValue(params.PhoneNumber) {
+ phone := strings.TrimSpace(refs.StringValue(params.PhoneNumber))
+ if len(phone) < 10 || len(phone) > 15 {
+ log.Debug().Str("phone", phone).Msg("Invalid phone number")
+ return nil, fmt.Errorf("invalid phone number")
+ }
+ // check if user with new phone number exists
+ _, err = g.StorageProvider.GetUserByPhoneNumber(ctx, phone)
+ // err = nil means user exists
+ if err == nil {
+ log.Debug().Str("phone", phone).Msg("User with phone number already exists")
+ return nil, fmt.Errorf("user with this phone number already exists")
+ }
+ go g.MemoryStoreProvider.DeleteAllUserSessions(user.ID)
+ user.PhoneNumber = &phone
+ user.PhoneNumberVerifiedAt = nil
+ }
+
+ rolesToSave := ""
+ if len(params.Roles) > 0 {
+ currentRoles := strings.Split(user.Roles, ",")
+ inputRoles := []string{}
+ for _, item := range params.Roles {
+ inputRoles = append(inputRoles, *item)
+ }
+
+ roles := g.Config.Roles
+ protectedRoles := g.Config.ProtectedRoles
+
+ if !validators.IsValidRoles(inputRoles, append([]string{}, append(roles, protectedRoles...)...)) {
+ log.Debug().Msg("Invalid list of roles")
+ return nil, fmt.Errorf("invalid list of roles")
+ }
+
+ if !validators.IsStringArrayEqual(inputRoles, currentRoles) {
+ rolesToSave = strings.Join(inputRoles, ",")
+ }
+
+ go g.MemoryStoreProvider.DeleteAllUserSessions(user.ID)
+ }
+
+ if rolesToSave != "" {
+ user.Roles = rolesToSave
+ }
+ user, err = g.StorageProvider.UpdateUser(ctx, user)
+ if err != nil {
+ log.Debug().Err(err).Msg("failed UpdateUser")
+ return nil, err
+ }
+
+ return user.AsAPIUser(), nil
+}
diff --git a/server/resolvers/update_webhook.go b/internal/graphql/update_webhook.go
similarity index 50%
rename from server/resolvers/update_webhook.go
rename to internal/graphql/update_webhook.go
index 3d0956888..7f4401282 100644
--- a/server/resolvers/update_webhook.go
+++ b/internal/graphql/update_webhook.go
@@ -1,4 +1,4 @@
-package resolvers
+package graphql
import (
"context"
@@ -6,61 +6,65 @@ import (
"fmt"
"strings"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/db/models"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/refs"
- "github.com/authorizerdev/authorizer/server/token"
- "github.com/authorizerdev/authorizer/server/utils"
- "github.com/authorizerdev/authorizer/server/validators"
- log "github.com/sirupsen/logrus"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/refs"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
+ "github.com/authorizerdev/authorizer/internal/utils"
+ "github.com/authorizerdev/authorizer/internal/validators"
)
-// UpdateWebhookResolver resolver for update webhook mutation
-func UpdateWebhookResolver(ctx context.Context, params model.UpdateWebhookRequest) (*model.Response, error) {
+// UpdateWebhook is the method to update webhook details
+// Permission: authorizer:admin
+func (g *graphqlProvider) UpdateWebhook(ctx context.Context, params *model.UpdateWebhookRequest) (*model.Response, error) {
+ log := g.Log.With().Str("func", "UpdateWebhook").Logger()
gc, err := utils.GinContextFromContext(ctx)
if err != nil {
- log.Debug("Failed to get GinContext: ", err)
+ log.Debug().Err(err).Msg("Failed to get GinContext")
return nil, err
}
-
- if !token.IsSuperAdmin(gc) {
- log.Debug("Not logged in as super admin")
+ if !g.TokenProvider.IsSuperAdmin(gc) {
+ log.Debug().Msg("Not logged in as super admin")
return nil, fmt.Errorf("unauthorized")
}
- webhook, err := db.Provider.GetWebhookByID(ctx, params.ID)
+ webhook, err := g.StorageProvider.GetWebhookByID(ctx, params.ID)
if err != nil {
- log.Debug("failed to get webhook: ", err)
+ log.Debug().Err(err).Msg("failed GetWebhookByID")
return nil, err
}
+ var headersMap map[string]interface{}
+ err = json.Unmarshal([]byte(webhook.Headers), &headersMap)
+ if err != nil {
+ log.Debug().Err(err).Msg("error un-marshalling headers")
+ }
headersString := ""
- if webhook.Headers != nil {
+ if headersMap != nil {
headerBytes, err := json.Marshal(webhook.Headers)
if err != nil {
- log.Debug("failed to marshall source headers: ", err)
+ log.Debug().Err(err).Msg("failed to marshall headers")
+ return nil, err
}
headersString = string(headerBytes)
}
- webhookDetails := &models.Webhook{
+ webhookDetails := &schemas.Webhook{
ID: webhook.ID,
Key: webhook.ID,
- EventName: refs.StringValue(webhook.EventName),
- EventDescription: refs.StringValue(webhook.EventDescription),
- EndPoint: refs.StringValue(webhook.Endpoint),
- Enabled: refs.BoolValue(webhook.Enabled),
+ EventName: webhook.EventName,
+ EventDescription: webhook.EventDescription,
+ EndPoint: webhook.EndPoint,
+ Enabled: webhook.Enabled,
Headers: headersString,
- CreatedAt: refs.Int64Value(webhook.CreatedAt),
+ CreatedAt: webhook.CreatedAt,
}
if params.EventName != nil && webhookDetails.EventName != refs.StringValue(params.EventName) {
if isValid := validators.IsValidWebhookEventName(refs.StringValue(params.EventName)); !isValid {
- log.Debug("invalid event name: ", refs.StringValue(params.EventName))
+ log.Debug().Str("event_name", refs.StringValue(params.EventName)).Msg("invalid event name")
return nil, fmt.Errorf("invalid event name %s", refs.StringValue(params.EventName))
}
webhookDetails.EventName = refs.StringValue(params.EventName)
}
if params.Endpoint != nil && webhookDetails.EndPoint != refs.StringValue(params.Endpoint) {
if strings.TrimSpace(refs.StringValue(params.Endpoint)) == "" {
- log.Debug("empty endpoint not allowed")
+ log.Debug().Msg("empty endpoint not allowed")
return nil, fmt.Errorf("empty endpoint not allowed")
}
webhookDetails.EndPoint = refs.StringValue(params.Endpoint)
@@ -74,14 +78,15 @@ func UpdateWebhookResolver(ctx context.Context, params model.UpdateWebhookReques
if params.Headers != nil {
headerBytes, err := json.Marshal(params.Headers)
if err != nil {
- log.Debug("failed to marshall headers: ", err)
+ log.Debug().Err(err).Msg("failed to marshall headers")
return nil, err
}
webhookDetails.Headers = string(headerBytes)
}
- _, err = db.Provider.UpdateWebhook(ctx, webhookDetails)
+ _, err = g.StorageProvider.UpdateWebhook(ctx, webhookDetails)
if err != nil {
+ log.Debug().Err(err).Msg("failed UpdateWebhook")
return nil, err
}
return &model.Response{
diff --git a/internal/graphql/user.go b/internal/graphql/user.go
new file mode 100644
index 000000000..cc568d5f1
--- /dev/null
+++ b/internal/graphql/user.go
@@ -0,0 +1,45 @@
+package graphql
+
+import (
+ "context"
+ "fmt"
+ "strings"
+
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/utils"
+)
+
+// User is the method to get user details
+// Permission: authorizer:admin
+func (g *graphqlProvider) User(ctx context.Context, params *model.GetUserRequest) (*model.User, error) {
+ log := g.Log.With().Str("func", "User").Logger()
+ gc, err := utils.GinContextFromContext(ctx)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get GinContext")
+ return nil, err
+ }
+ if !g.TokenProvider.IsSuperAdmin(gc) {
+ log.Debug().Msg("Not logged in as super admin")
+ return nil, fmt.Errorf("unauthorized")
+ }
+ // Try getting user by ID
+ if params.ID != nil && strings.Trim(*params.ID, " ") != "" {
+ res, err := g.StorageProvider.GetUserByID(ctx, *params.ID)
+ if err != nil {
+ log.Debug().Err(err).Msg("failed GetUserByID")
+ return nil, err
+ }
+ return res.AsAPIUser(), nil
+ }
+ // Try getting user by email
+ if params.Email != nil && strings.Trim(*params.Email, " ") != "" {
+ res, err := g.StorageProvider.GetUserByEmail(ctx, *params.Email)
+ if err != nil {
+ log.Debug().Err(err).Msg("failed GetUserByEmail")
+ return nil, err
+ }
+ return res.AsAPIUser(), nil
+ }
+ // Return error if no params are provided
+ return nil, fmt.Errorf("invalid params, user id or email is required")
+}
diff --git a/internal/graphql/users.go b/internal/graphql/users.go
new file mode 100644
index 000000000..caa4daaf8
--- /dev/null
+++ b/internal/graphql/users.go
@@ -0,0 +1,40 @@
+package graphql
+
+import (
+ "context"
+ "fmt"
+
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/utils"
+)
+
+// Users is the method to get list of users
+// Permission: authorizer:admin
+func (g *graphqlProvider) Users(ctx context.Context, params *model.PaginatedRequest) (*model.Users, error) {
+ log := g.Log.With().Str("func", "Users").Logger()
+ gc, err := utils.GinContextFromContext(ctx)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get GinContext")
+ return nil, err
+ }
+ if !g.TokenProvider.IsSuperAdmin(gc) {
+ log.Debug().Msg("Not logged in as super admin")
+ return nil, fmt.Errorf("unauthorized")
+ }
+
+ pagination := utils.GetPagination(params)
+
+ res, pagination, err := g.StorageProvider.ListUsers(ctx, pagination)
+ if err != nil {
+ log.Debug().Err(err).Msg("failed ListUsers")
+ return nil, err
+ }
+ resItems := make([]*model.User, len(res))
+ for i, user := range res {
+ resItems[i] = user.AsAPIUser()
+ }
+ return &model.Users{
+ Pagination: pagination,
+ Users: resItems,
+ }, nil
+}
diff --git a/server/resolvers/validate_jwt_token.go b/internal/graphql/validate_jwt_token.go
similarity index 50%
rename from server/resolvers/validate_jwt_token.go
rename to internal/graphql/validate_jwt_token.go
index 7dbb32fde..02c3acace 100644
--- a/server/resolvers/validate_jwt_token.go
+++ b/internal/graphql/validate_jwt_token.go
@@ -1,37 +1,38 @@
-package resolvers
+package graphql
import (
"context"
"errors"
"fmt"
- "github.com/golang-jwt/jwt"
- log "github.com/sirupsen/logrus"
+ "github.com/golang-jwt/jwt/v4"
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/parsers"
- "github.com/authorizerdev/authorizer/server/token"
- "github.com/authorizerdev/authorizer/server/utils"
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/parsers"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
+ "github.com/authorizerdev/authorizer/internal/token"
+ "github.com/authorizerdev/authorizer/internal/utils"
)
-// ValidateJwtTokenResolver is used to validate a jwt token without its rotation
+// ValidateJwtToken is used to validate a jwt token without its rotation
// this can be used at API level (backend)
// it can validate:
// access_token
// id_token
// refresh_token
-func ValidateJwtTokenResolver(ctx context.Context, params model.ValidateJWTTokenInput) (*model.ValidateJWTTokenResponse, error) {
+// Permission: none
+func (g *graphqlProvider) ValidateJWTToken(ctx context.Context, params *model.ValidateJWTTokenRequest) (*model.ValidateJWTTokenResponse, error) {
+ log := g.Log.With().Str("func", "ValidateJWTToken").Logger()
gc, err := utils.GinContextFromContext(ctx)
if err != nil {
- log.Debug("Failed to get GinContext: ", err)
+ log.Debug().Err(err).Msg("Failed to get GinContext")
return nil, err
}
tokenType := params.TokenType
if tokenType != constants.TokenTypeAccessToken && tokenType != constants.TokenTypeRefreshToken && tokenType != constants.TokenTypeIdentityToken {
- log.Debug("Invalid token type: ", tokenType)
+ log.Debug().Str("token_type", tokenType).Msg("Invalid token type")
return nil, errors.New("invalid token type")
}
@@ -40,9 +41,9 @@ func ValidateJwtTokenResolver(ctx context.Context, params model.ValidateJWTToken
userID := ""
nonce := ""
- claims, err = token.ParseJWTToken(params.Token)
+ claims, err = g.TokenProvider.ParseJWTToken(params.Token)
if err != nil {
- log.Debug("Failed to parse JWT token: ", err)
+ log.Debug().Err(err).Msg("Failed to parse jwt token")
return nil, err
}
userID = claims["sub"].(string)
@@ -55,9 +56,9 @@ func ValidateJwtTokenResolver(ctx context.Context, params model.ValidateJWTToken
if loginMethod != nil && loginMethod != "" {
sessionKey = loginMethod.(string) + ":" + userID
}
- token, err := memorystore.Provider.GetUserSession(sessionKey, tokenType+"_"+claims["nonce"].(string))
+ token, err := g.MemoryStoreProvider.GetUserSession(sessionKey, tokenType+"_"+claims["nonce"].(string))
if err != nil || token == "" {
- log.Debug("Failed to get user session: ", err)
+ log.Debug().Err(err).Msg("Failed to get token from session store")
return nil, errors.New("invalid token")
}
}
@@ -66,36 +67,39 @@ func ValidateJwtTokenResolver(ctx context.Context, params model.ValidateJWTToken
// we cannot validate nonce in case of id_token as that token is not persisted in session store
if nonce != "" {
- if ok, err := token.ValidateJWTClaims(claims, hostname, nonce, userID); !ok || err != nil {
- log.Debug("Failed to parse jwt token: ", err)
+ if ok, err := g.TokenProvider.ValidateJWTClaims(claims, &token.AuthTokenConfig{
+ HostName: hostname,
+ Nonce: nonce,
+ User: &schemas.User{
+ ID: userID,
+ },
+ }); !ok || err != nil {
+ log.Debug().Err(err).Msg("Failed to validate jwt claims")
return nil, errors.New("invalid claims")
}
} else {
- if ok, err := token.ValidateJWTTokenWithoutNonce(claims, hostname, userID); !ok || err != nil {
- log.Debug("Failed to parse jwt token without nonce: ", err)
+ if ok, err := g.TokenProvider.ValidateJWTTokenWithoutNonce(claims, &token.AuthTokenConfig{
+ HostName: hostname,
+ User: &schemas.User{
+ ID: userID,
+ },
+ }); !ok || err != nil {
+ log.Debug().Err(err).Msg("Failed to validate jwt claims")
return nil, errors.New("invalid claims")
}
}
- claimKey := "roles"
-
- if tokenType == constants.TokenTypeIdentityToken {
- claimKey, err = memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyJwtRoleClaim)
- if err != nil {
- claimKey = "roles"
- }
- }
-
+ claimKey := g.Config.JWTRoleClaim
claimRolesInterface := claims[claimKey]
roleSlice := utils.ConvertInterfaceToSlice(claimRolesInterface)
for _, v := range roleSlice {
claimRoles = append(claimRoles, v.(string))
}
- if params.Roles != nil && len(params.Roles) > 0 {
+ if len(params.Roles) > 0 {
for _, v := range params.Roles {
if !utils.StringSliceContains(claimRoles, v) {
- log.Debug("Token does not have required role: ", v)
+ log.Debug().Str("role", v).Msg("Role not found in claims")
return nil, fmt.Errorf(`unauthorized`)
}
}
diff --git a/server/resolvers/validate_session.go b/internal/graphql/validate_session.go
similarity index 50%
rename from server/resolvers/validate_session.go
rename to internal/graphql/validate_session.go
index e5be53956..b3afe7d4d 100644
--- a/server/resolvers/validate_session.go
+++ b/internal/graphql/validate_session.go
@@ -1,23 +1,22 @@
-package resolvers
+package graphql
import (
"context"
"errors"
"fmt"
- "github.com/authorizerdev/authorizer/server/cookie"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/token"
- "github.com/authorizerdev/authorizer/server/utils"
- log "github.com/sirupsen/logrus"
+ "github.com/authorizerdev/authorizer/internal/cookie"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/utils"
)
-// ValidateSessionResolver is used to validate a cookie session without its rotation
-func ValidateSessionResolver(ctx context.Context, params *model.ValidateSessionInput) (*model.ValidateSessionResponse, error) {
+// ValidateSession is used to validate a cookie session without its rotation
+// Permission: authorized:user
+func (g *graphqlProvider) ValidateSession(ctx context.Context, params *model.ValidateSessionRequest) (*model.ValidateSessionResponse, error) {
+ log := g.Log.With().Str("func", "ValidateSession").Logger()
gc, err := utils.GinContextFromContext(ctx)
if err != nil {
- log.Debug("Failed to get GinContext: ", err)
+ log.Debug().Err(err).Msg("Failed to get GinContext")
return nil, err
}
sessionToken := ""
@@ -26,29 +25,27 @@ func ValidateSessionResolver(ctx context.Context, params *model.ValidateSessionI
} else {
sessionToken, err = cookie.GetSession(gc)
if err != nil {
- log.Debug("Failed to get session token: ", err)
+ log.Debug().Err(err).Msg("Failed to get session token")
return nil, errors.New("unauthorized")
}
}
if sessionToken == "" {
sessionToken, err = cookie.GetSession(gc)
if err != nil {
- log.Debug("Failed to get session token: ", err)
+ log.Debug().Err(err).Msg("Failed to get session token")
return nil, errors.New("unauthorized")
}
}
- claims, err := token.ValidateBrowserSession(gc, sessionToken)
+ claims, err := g.TokenProvider.ValidateBrowserSession(gc, sessionToken)
if err != nil {
- log.Debug("Failed to validate session token", err)
+ log.Debug().Err(err).Msg("Failed to validate session")
return nil, errors.New("unauthorized")
}
userID := claims.Subject
- log := log.WithFields(log.Fields{
- "user_id": userID,
- })
- user, err := db.Provider.GetUserByID(ctx, userID)
+ log.Debug().Str("userID", userID).Msg("Validated session")
+ user, err := g.StorageProvider.GetUserByID(ctx, userID)
if err != nil {
- log.Debug("Failed to get user: ", err)
+ log.Debug().Err(err).Msg("failed GetUserByID")
return nil, err
}
// refresh token has "roles" as claim
@@ -58,7 +55,7 @@ func ValidateSessionResolver(ctx context.Context, params *model.ValidateSessionI
if params != nil && params.Roles != nil && len(params.Roles) > 0 {
for _, v := range params.Roles {
if !utils.StringSliceContains(claimRoles, v) {
- log.Debug("User does not have required role: ", claimRoles, v)
+ log.Debug().Str("role", v).Msg("Role not found in claims")
return nil, fmt.Errorf(`unauthorized`)
}
}
diff --git a/internal/graphql/verification_requests.go b/internal/graphql/verification_requests.go
new file mode 100644
index 000000000..896f2dd8e
--- /dev/null
+++ b/internal/graphql/verification_requests.go
@@ -0,0 +1,41 @@
+package graphql
+
+import (
+ "context"
+ "fmt"
+
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/utils"
+)
+
+// VerificationRequests is used to get all verification requests
+// Permission: authorizer:admin
+func (g *graphqlProvider) VerificationRequests(ctx context.Context, params *model.PaginatedRequest) (*model.VerificationRequests, error) {
+ log := g.Log.With().Str("func", "VerificationRequests").Logger()
+ gc, err := utils.GinContextFromContext(ctx)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get GinContext")
+ return nil, err
+ }
+ if !g.TokenProvider.IsSuperAdmin(gc) {
+ log.Debug().Msg("Not logged in as super admin")
+ return nil, fmt.Errorf("unauthorized")
+ }
+
+ pagination := utils.GetPagination(params)
+ requests, pagination, err := g.StorageProvider.ListVerificationRequests(ctx, pagination)
+ if err != nil {
+ log.Debug().Err(err).Msg("failed ListVerificationRequests")
+ return nil, err
+ }
+
+ res := make([]*model.VerificationRequest, len(requests))
+ for i, request := range requests {
+ res[i] = request.AsAPIVerificationRequest()
+ }
+
+ return &model.VerificationRequests{
+ Pagination: pagination,
+ VerificationRequests: res,
+ }, nil
+}
diff --git a/internal/graphql/verify_email.go b/internal/graphql/verify_email.go
new file mode 100644
index 000000000..23aeff186
--- /dev/null
+++ b/internal/graphql/verify_email.go
@@ -0,0 +1,228 @@
+package graphql
+
+import (
+ "context"
+ "fmt"
+ "strings"
+ "time"
+
+ "github.com/google/uuid"
+
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/cookie"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/parsers"
+ "github.com/authorizerdev/authorizer/internal/refs"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
+ "github.com/authorizerdev/authorizer/internal/token"
+ "github.com/authorizerdev/authorizer/internal/utils"
+)
+
+// VerifyEmail is the method to verify email
+// Permission: none
+func (g *graphqlProvider) VerifyEmail(ctx context.Context, params *model.VerifyEmailRequest) (*model.AuthResponse, error) {
+ log := g.Log.With().Str("func", "VerifyEmail").Logger()
+
+ gc, err := utils.GinContextFromContext(ctx)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get GinContext")
+ return nil, err
+ }
+
+ verificationRequest, err := g.StorageProvider.GetVerificationRequestByToken(ctx, params.Token)
+ if err != nil {
+ log.Debug().Err(err).Msg("failed GetVerificationRequestByToken")
+ return nil, fmt.Errorf(`invalid token: %s`, err.Error())
+ }
+
+ // verify if token exists in db
+ hostname := parsers.GetHost(gc)
+ claim, err := g.TokenProvider.ParseJWTToken(params.Token)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to parse jwt token")
+ return nil, fmt.Errorf(`invalid token: %s`, err.Error())
+ }
+
+ if ok, err := g.TokenProvider.ValidateJWTClaims(claim, &token.AuthTokenConfig{
+ HostName: hostname,
+ Nonce: verificationRequest.Nonce,
+ User: &schemas.User{
+ Email: &verificationRequest.Email,
+ },
+ }); !ok || err != nil {
+ log.Debug().Err(err).Msg("Failed to validate jwt claims")
+ return nil, fmt.Errorf(`invalid token: %s`, err.Error())
+ }
+
+ email := claim["sub"].(string)
+ log.Debug().Str("email", email).Msg("Email verified successfully")
+ user, err := g.StorageProvider.GetUserByEmail(ctx, email)
+ if err != nil {
+ log.Debug().Err(err).Msg("failed GetUserByEmail")
+ return nil, err
+ }
+
+ isMFAEnabled := g.Config.EnableMFA
+ isTOTPLoginEnabled := g.Config.EnableTOTPLogin
+
+ setOTPMFaSession := func(expiresAt int64) error {
+ mfaSession := uuid.NewString()
+ err = g.MemoryStoreProvider.SetMfaSession(user.ID, mfaSession, expiresAt)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to set mfa session")
+ return err
+ }
+ cookie.SetMfaSession(gc, mfaSession, g.Config.AppCookieSecure)
+ return nil
+ }
+
+ // If mfa enabled and also totp enabled
+ if refs.BoolValue(user.IsMultiFactorAuthEnabled) && isMFAEnabled && isTOTPLoginEnabled {
+ expiresAt := time.Now().Add(3 * time.Minute).Unix()
+ if err := setOTPMFaSession(expiresAt); err != nil {
+ log.Debug().Err(err).Msg("Failed to set mfa session")
+ return nil, err
+ }
+ authenticator, err := g.StorageProvider.GetAuthenticatorDetailsByUserId(ctx, user.ID, constants.EnvKeyTOTPAuthenticator)
+ if err != nil || authenticator == nil || authenticator.VerifiedAt == nil {
+ // generate totp
+ // Generate a base64 URL and initiate the registration for TOTP
+ authConfig, err := g.AuthenticatorProvider.Generate(ctx, user.ID)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to generate totp")
+ return nil, err
+ }
+ recoveryCodes := []*string{}
+ for _, code := range authConfig.RecoveryCodes {
+ recoveryCodes = append(recoveryCodes, refs.NewStringRef(code))
+ }
+ // when user is first time registering for totp
+ res := &model.AuthResponse{
+ Message: `Proceed to totp verification screen`,
+ ShouldShowTotpScreen: refs.NewBoolRef(true),
+ AuthenticatorScannerImage: refs.NewStringRef(authConfig.ScannerImage),
+ AuthenticatorSecret: refs.NewStringRef(authConfig.Secret),
+ AuthenticatorRecoveryCodes: recoveryCodes,
+ }
+ return res, nil
+ } else {
+ //when user is already register for totp
+ res := &model.AuthResponse{
+ Message: `Proceed to totp screen`,
+ ShouldShowTotpScreen: refs.NewBoolRef(true),
+ }
+ return res, nil
+ }
+ }
+
+ isSignUp := false
+ if user.EmailVerifiedAt == nil {
+ isSignUp = true
+ // update email_verified_at in users table
+ now := time.Now().Unix()
+ user.EmailVerifiedAt = &now
+ user, err = g.StorageProvider.UpdateUser(ctx, user)
+ if err != nil {
+ log.Debug().Err(err).Msg("failed UpdateUser")
+ return nil, err
+ }
+ }
+ // delete from verification table
+ err = g.StorageProvider.DeleteVerificationRequest(gc, verificationRequest)
+ if err != nil {
+ log.Debug().Err(err).Msg("failed DeleteVerificationRequest")
+ return nil, err
+ }
+
+ loginMethod := constants.AuthRecipeMethodBasicAuth
+ if loginMethod == constants.VerificationTypeMagicLinkLogin {
+ loginMethod = constants.AuthRecipeMethodMagicLinkLogin
+ }
+
+ roles := strings.Split(user.Roles, ",")
+ scope := []string{"openid", "email", "profile"}
+ code := ""
+ // Not required as /oauth/token cannot be resumed from other tab
+ // codeChallenge := ""
+ nonce := ""
+ if params.State != nil {
+ // Get state from store
+ authorizeState, _ := g.MemoryStoreProvider.GetState(refs.StringValue(params.State))
+ if authorizeState != "" {
+ authorizeStateSplit := strings.Split(authorizeState, "@@")
+ if len(authorizeStateSplit) > 1 {
+ code = authorizeStateSplit[0]
+ // Not required as /oauth/token cannot be resumed from other tab
+ // codeChallenge = authorizeStateSplit[1]
+ } else {
+ nonce = authorizeState
+ }
+ go g.MemoryStoreProvider.RemoveState(refs.StringValue(params.State))
+ }
+ }
+ if nonce == "" {
+ nonce = uuid.New().String()
+ }
+ authToken, err := g.TokenProvider.CreateAuthToken(gc, &token.AuthTokenConfig{
+ HostName: hostname,
+ User: user,
+ Roles: roles,
+ Scope: scope,
+ LoginMethod: loginMethod,
+ Nonce: nonce,
+ Code: code,
+ })
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to create auth token")
+ return nil, err
+ }
+
+ // Code challenge could be optional if PKCE flow is not used
+ // Not required as /oauth/token cannot be resumed from other tab
+ // if code != "" {
+ // if err := memorystore.Provider.SetState(code, codeChallenge+"@@"+authToken.FingerPrintHash); err != nil {
+ // log.Debug("SetState failed: ", err)
+ // return nil, err
+ // }
+ // }
+ go func() {
+ if isSignUp {
+ g.EventsProvider.RegisterEvent(ctx, constants.UserSignUpWebhookEvent, loginMethod, user)
+ // User is also logged in with signup
+ g.EventsProvider.RegisterEvent(ctx, constants.UserLoginWebhookEvent, loginMethod, user)
+ } else {
+ g.EventsProvider.RegisterEvent(ctx, constants.UserLoginWebhookEvent, loginMethod, user)
+ }
+
+ if err := g.StorageProvider.AddSession(ctx, &schemas.Session{
+ UserID: user.ID,
+ UserAgent: utils.GetUserAgent(gc.Request),
+ IP: utils.GetIP(gc.Request),
+ }); err != nil {
+ log.Debug().Err(err).Msg("Failed to add session")
+ }
+ }()
+ expiresIn := authToken.AccessToken.ExpiresAt - time.Now().Unix()
+ if expiresIn <= 0 {
+ expiresIn = 1
+ }
+
+ res := &model.AuthResponse{
+ Message: `Email verified successfully.`,
+ AccessToken: &authToken.AccessToken.Token,
+ IDToken: &authToken.IDToken.Token,
+ ExpiresIn: &expiresIn,
+ User: user.AsAPIUser(),
+ }
+
+ sessionKey := loginMethod + ":" + user.ID
+ cookie.SetSession(gc, authToken.FingerPrintHash, g.Config.AppCookieSecure)
+ g.MemoryStoreProvider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash, authToken.SessionTokenExpiresAt)
+ g.MemoryStoreProvider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token, authToken.AccessToken.ExpiresAt)
+
+ if authToken.RefreshToken != nil {
+ res.RefreshToken = &authToken.RefreshToken.Token
+ g.MemoryStoreProvider.SetUserSession(sessionKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token, authToken.RefreshToken.ExpiresAt)
+ }
+ return res, nil
+}
diff --git a/internal/graphql/verify_otp.go b/internal/graphql/verify_otp.go
new file mode 100644
index 000000000..27b8a87aa
--- /dev/null
+++ b/internal/graphql/verify_otp.go
@@ -0,0 +1,229 @@
+package graphql
+
+import (
+ "context"
+ "fmt"
+ "strings"
+ "time"
+
+ "github.com/google/uuid"
+
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/cookie"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/parsers"
+ "github.com/authorizerdev/authorizer/internal/refs"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
+ "github.com/authorizerdev/authorizer/internal/token"
+ "github.com/authorizerdev/authorizer/internal/utils"
+)
+
+// VerifyOtp is the method to verify OTP
+// authorized otp request
+func (g *graphqlProvider) VerifyOTP(ctx context.Context, params *model.VerifyOTPRequest) (*model.AuthResponse, error) {
+ log := g.Log.With().Str("func", "VerifyOTP").Logger()
+ gc, err := utils.GinContextFromContext(ctx)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get GinContext")
+ return nil, err
+ }
+
+ mfaSession, err := cookie.GetMfaSession(gc)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get mfa session")
+ return nil, fmt.Errorf(`invalid session: %s`, err.Error())
+ }
+
+ email := strings.TrimSpace(refs.StringValue(params.Email))
+ phoneNumber := strings.TrimSpace(refs.StringValue(params.PhoneNumber))
+ if email == "" && phoneNumber == "" {
+ log.Debug().Msg("Email or phone number is required")
+ return nil, fmt.Errorf(`email or phone number is required`)
+ }
+ isEmailVerification := email != ""
+ isMobileVerification := phoneNumber != ""
+ log = log.With().Str("email", email).Str("phone_number", phoneNumber).Logger()
+ // Get user by email or phone number
+ var user *schemas.User
+ if isEmailVerification {
+ user, err = g.StorageProvider.GetUserByEmail(ctx, refs.StringValue(params.Email))
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get user by email")
+ }
+ } else {
+ user, err = g.StorageProvider.GetUserByPhoneNumber(ctx, refs.StringValue(params.PhoneNumber))
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get user by phone number")
+ }
+ }
+ if user == nil || err != nil {
+ log.Debug().Err(err).Msg("User not found")
+ return nil, fmt.Errorf(`user not found`)
+ }
+ // Verify OTP based on TOPT or OTP
+ if refs.BoolValue(params.IsTotp) {
+ status, err := g.AuthenticatorProvider.Validate(ctx, params.Otp, user.ID)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to validate passcode")
+ return nil, fmt.Errorf("error while validating passcode")
+ }
+ if !status {
+ log.Debug().Msg("Failed to verify otp request: Incorrect value")
+ log.Info().Msg("Checking if otp is recovery code")
+ // Check if otp is recovery code
+ isValidRecoveryCode, err := g.AuthenticatorProvider.ValidateRecoveryCode(ctx, params.Otp, user.ID)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to validate recovery code")
+ return nil, fmt.Errorf("error while validating recovery code")
+ }
+ if !isValidRecoveryCode {
+ log.Debug().Msg("Failed to verify otp request: Incorrect value")
+ return nil, fmt.Errorf(`invalid otp`)
+ }
+ }
+ } else {
+ var otp *schemas.OTP
+ if isEmailVerification {
+ otp, err = g.StorageProvider.GetOTPByEmail(ctx, refs.StringValue(params.Email))
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get otp request for email")
+ }
+ } else {
+ otp, err = g.StorageProvider.GetOTPByPhoneNumber(ctx, refs.StringValue(params.PhoneNumber))
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get otp request for phone number")
+ }
+ }
+ if otp == nil && err != nil {
+ log.Debug().Msg("OTP not found")
+ return nil, fmt.Errorf(`OTP not found`)
+ }
+ if params.Otp != otp.Otp {
+ log.Debug().Msg("Failed to verify otp request: OTP mismatch")
+ return nil, fmt.Errorf(`invalid otp`)
+ }
+ expiresIn := otp.ExpiresAt - time.Now().Unix()
+ if expiresIn < 0 {
+ log.Debug().Msg("OTP expired")
+ return nil, fmt.Errorf("otp expired")
+ }
+ if err := g.StorageProvider.DeleteOTP(gc, otp); err != nil {
+ log.Debug().Err(err).Msg("Failed to delete otp")
+ }
+ }
+
+ if _, err := g.MemoryStoreProvider.GetMfaSession(user.ID, mfaSession); err != nil {
+ log.Debug().Err(err).Msg("Failed to get mfa session")
+ return nil, fmt.Errorf(`invalid session: %s`, err.Error())
+ }
+
+ isSignUp := false
+ if user.EmailVerifiedAt == nil && isEmailVerification {
+ isSignUp = true
+ now := time.Now().Unix()
+ user.EmailVerifiedAt = &now
+ }
+ if user.PhoneNumberVerifiedAt == nil && isMobileVerification {
+ isSignUp = true
+ now := time.Now().Unix()
+ user.PhoneNumberVerifiedAt = &now
+ }
+ if isSignUp {
+ user, err = g.StorageProvider.UpdateUser(ctx, user)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to update user")
+ return nil, err
+ }
+ }
+ loginMethod := constants.AuthRecipeMethodBasicAuth
+ if isMobileVerification {
+ loginMethod = constants.AuthRecipeMethodMobileOTP
+ }
+ roles := strings.Split(user.Roles, ",")
+ scope := []string{"openid", "email", "profile"}
+ code := ""
+ codeChallenge := ""
+ nonce := ""
+ if params.State != nil {
+ // Get state from store
+ authorizeState, _ := g.MemoryStoreProvider.GetState(refs.StringValue(params.State))
+ if authorizeState != "" {
+ authorizeStateSplit := strings.Split(authorizeState, "@@")
+ if len(authorizeStateSplit) > 1 {
+ code = authorizeStateSplit[0]
+ codeChallenge = authorizeStateSplit[1]
+ } else {
+ nonce = authorizeState
+ }
+ go g.MemoryStoreProvider.RemoveState(refs.StringValue(params.State))
+ }
+ }
+ if nonce == "" {
+ nonce = uuid.New().String()
+ }
+ hostname := parsers.GetHost(gc)
+ // user, roles, scope, loginMethod, nonce, code
+ authToken, err := g.TokenProvider.CreateAuthToken(gc, &token.AuthTokenConfig{
+ User: user,
+ Roles: roles,
+ Scope: scope,
+ LoginMethod: loginMethod,
+ Nonce: nonce,
+ Code: code,
+ HostName: hostname,
+ })
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to create auth token")
+ return nil, err
+ }
+
+ // Code challenge could be optional if PKCE flow is not used
+ if code != "" {
+ if err := g.MemoryStoreProvider.SetState(code, codeChallenge+"@@"+authToken.FingerPrintHash); err != nil {
+ log.Debug().Err(err).Msg("Failed to set state")
+ return nil, err
+ }
+ }
+
+ go func() {
+ if isSignUp {
+ g.EventsProvider.RegisterEvent(ctx, constants.UserSignUpWebhookEvent, loginMethod, user)
+ // User is also logged in with signup
+ g.EventsProvider.RegisterEvent(ctx, constants.UserLoginWebhookEvent, loginMethod, user)
+ } else {
+ g.EventsProvider.RegisterEvent(ctx, constants.UserLoginWebhookEvent, loginMethod, user)
+ }
+
+ if err := g.StorageProvider.AddSession(ctx, &schemas.Session{
+ UserID: user.ID,
+ UserAgent: utils.GetUserAgent(gc.Request),
+ IP: utils.GetIP(gc.Request),
+ }); err != nil {
+ log.Debug().Err(err).Msg("Failed to add session")
+ }
+ }()
+
+ authTokenExpiresIn := authToken.AccessToken.ExpiresAt - time.Now().Unix()
+ if authTokenExpiresIn <= 0 {
+ authTokenExpiresIn = 1
+ }
+
+ res := &model.AuthResponse{
+ Message: `OTP verified successfully.`,
+ AccessToken: &authToken.AccessToken.Token,
+ IDToken: &authToken.IDToken.Token,
+ ExpiresIn: &authTokenExpiresIn,
+ User: user.AsAPIUser(),
+ }
+
+ sessionKey := loginMethod + ":" + user.ID
+ cookie.SetSession(gc, authToken.FingerPrintHash, g.Config.AppCookieSecure)
+ g.MemoryStoreProvider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash, authToken.SessionTokenExpiresAt)
+ g.MemoryStoreProvider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token, authToken.AccessToken.ExpiresAt)
+
+ if authToken.RefreshToken != nil {
+ res.RefreshToken = &authToken.RefreshToken.Token
+ g.MemoryStoreProvider.SetUserSession(sessionKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token, authToken.RefreshToken.ExpiresAt)
+ }
+ return res, nil
+}
diff --git a/internal/graphql/webhook.go b/internal/graphql/webhook.go
new file mode 100644
index 000000000..b3cc65017
--- /dev/null
+++ b/internal/graphql/webhook.go
@@ -0,0 +1,31 @@
+package graphql
+
+import (
+ "context"
+ "fmt"
+
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/utils"
+)
+
+// Webhook is the method to get webhook details
+// Permission: authorizer:admin
+func (g *graphqlProvider) Webhook(ctx context.Context, params *model.WebhookRequest) (*model.Webhook, error) {
+ log := g.Log.With().Str("func", "Webhook").Logger()
+ gc, err := utils.GinContextFromContext(ctx)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get GinContext")
+ return nil, err
+ }
+ if !g.TokenProvider.IsSuperAdmin(gc) {
+ log.Debug().Msg("Not logged in as super admin")
+ return nil, fmt.Errorf("unauthorized")
+ }
+
+ webhook, err := g.StorageProvider.GetWebhookByID(ctx, params.ID)
+ if err != nil {
+ log.Debug().Err(err).Msg("failed GetWebhookByID")
+ return nil, err
+ }
+ return webhook.AsAPIWebhook(), nil
+}
diff --git a/internal/graphql/webhook_logs.go b/internal/graphql/webhook_logs.go
new file mode 100644
index 000000000..d1dce5370
--- /dev/null
+++ b/internal/graphql/webhook_logs.go
@@ -0,0 +1,51 @@
+package graphql
+
+import (
+ "context"
+ "fmt"
+
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/refs"
+ "github.com/authorizerdev/authorizer/internal/utils"
+)
+
+// WebhookLogs is the method to get webhook logs
+// Permission: authorizer:admin
+func (g *graphqlProvider) WebhookLogs(ctx context.Context, params *model.ListWebhookLogRequest) (*model.WebhookLogs, error) {
+ log := g.Log.With().Str("func", "WebhookLogs").Logger()
+ gc, err := utils.GinContextFromContext(ctx)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get GinContext")
+ return nil, err
+ }
+ if !g.TokenProvider.IsSuperAdmin(gc) {
+ log.Debug().Msg("Not logged in as super admin")
+ return nil, fmt.Errorf("unauthorized")
+ }
+
+ var pagination *model.Pagination
+ var webhookID string
+
+ if params != nil {
+ pagination = utils.GetPagination(&model.PaginatedRequest{
+ Pagination: params.Pagination,
+ })
+ webhookID = refs.StringValue(params.WebhookID)
+ } else {
+ pagination = utils.GetPagination(nil)
+ webhookID = ""
+ }
+ webhookLogs, pagination, err := g.StorageProvider.ListWebhookLogs(ctx, pagination, webhookID)
+ if err != nil {
+ log.Debug().Err(err).Msg("failed ListWebhookLogs")
+ return nil, err
+ }
+ resItems := make([]*model.WebhookLog, len(webhookLogs))
+ for i, webhookLog := range webhookLogs {
+ resItems[i] = webhookLog.AsAPIWebhookLog()
+ }
+ return &model.WebhookLogs{
+ Pagination: pagination,
+ WebhookLogs: resItems,
+ }, nil
+}
diff --git a/internal/graphql/webhooks.go b/internal/graphql/webhooks.go
new file mode 100644
index 000000000..1799adf79
--- /dev/null
+++ b/internal/graphql/webhooks.go
@@ -0,0 +1,39 @@
+package graphql
+
+import (
+ "context"
+ "fmt"
+
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/utils"
+)
+
+// Webhooks is the method to list webhooks
+// Permission: authorizer:admin
+func (g *graphqlProvider) Webhooks(ctx context.Context, params *model.PaginatedRequest) (*model.Webhooks, error) {
+ log := g.Log.With().Str("func", "Webhooks").Logger()
+ gc, err := utils.GinContextFromContext(ctx)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get GinContext")
+ return nil, err
+ }
+ if !g.TokenProvider.IsSuperAdmin(gc) {
+ log.Debug().Msg("Not logged in as super admin")
+ return nil, fmt.Errorf("unauthorized")
+ }
+
+ pagination := utils.GetPagination(params)
+ webhooks, pagination, err := g.StorageProvider.ListWebhook(ctx, pagination)
+ if err != nil {
+ log.Debug().Err(err).Msg("failed ListWebhook")
+ return nil, err
+ }
+ res := make([]*model.Webhook, len(webhooks))
+ for i, webhook := range webhooks {
+ res[i] = webhook.AsAPIWebhook()
+ }
+ return &model.Webhooks{
+ Pagination: pagination,
+ Webhooks: res,
+ }, nil
+}
diff --git a/server/handlers/app.go b/internal/http_handlers/app.go
similarity index 57%
rename from server/handlers/app.go
rename to internal/http_handlers/app.go
index 9b30977b8..4362e0fc7 100644
--- a/server/handlers/app.go
+++ b/internal/http_handlers/app.go
@@ -1,16 +1,13 @@
-package handlers
+package http_handlers
import (
"net/http"
"strings"
"github.com/gin-gonic/gin"
- log "github.com/sirupsen/logrus"
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/parsers"
- "github.com/authorizerdev/authorizer/server/validators"
+ "github.com/authorizerdev/authorizer/internal/parsers"
+ "github.com/authorizerdev/authorizer/internal/validators"
)
// State is the struct that holds authorizer url and redirect url
@@ -21,11 +18,12 @@ type State struct {
}
// AppHandler is the handler for the /app route
-func AppHandler() gin.HandlerFunc {
+func (h *httpProvider) AppHandler() gin.HandlerFunc {
+ log := h.Log.With().Str("func", "AppHandler").Logger()
return func(c *gin.Context) {
hostname := parsers.GetHost(c)
- if isLoginPageDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableLoginPage); err != nil || isLoginPageDisabled {
- log.Debug("Login page is disabled")
+ if !h.Config.EnableLoginPage {
+ log.Debug().Msg("Login page is disabled")
c.JSON(400, gin.H{"error": "login page is not enabled"})
return
}
@@ -45,8 +43,8 @@ func AppHandler() gin.HandlerFunc {
redirectURI = hostname + "/app"
} else {
// validate redirect url with allowed origins
- if !validators.IsValidOrigin(redirectURI) {
- log.Debug("Invalid redirect_uri")
+ if !validators.IsValidOrigin(redirectURI, h.Config.AllowedOrigins) {
+ log.Debug().Msg("Invalid redirect url")
c.JSON(400, gin.H{"error": "invalid redirect url"})
return
}
@@ -56,22 +54,12 @@ func AppHandler() gin.HandlerFunc {
if pusher := c.Writer.Pusher(); pusher != nil {
// use pusher.Push() to do server push
if err := pusher.Push("/app/build/bundle.js", nil); err != nil {
- log.Debug("Failed to push file path: ", err)
+ log.Debug().Err(err).Msg("Failed to push bundle.js")
}
}
- orgName, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyOrganizationName)
- if err != nil {
- log.Debug("Failed to get organization name")
- c.JSON(400, gin.H{"error": "failed to get organization name"})
- return
- }
- orgLogo, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyOrganizationLogo)
- if err != nil {
- log.Debug("Failed to get organization logo")
- c.JSON(400, gin.H{"error": "failed to get organization logo"})
- return
- }
+ orgName := h.Config.OrganizationName
+ orgLogo := h.Config.OrganizationLogo
c.HTML(http.StatusOK, "app.tmpl", gin.H{
"data": map[string]interface{}{
"authorizerURL": hostname,
diff --git a/server/handlers/authorize.go b/internal/http_handlers/authorize.go
similarity index 73%
rename from server/handlers/authorize.go
rename to internal/http_handlers/authorize.go
index d9c368656..1e26635e5 100644
--- a/server/handlers/authorize.go
+++ b/internal/http_handlers/authorize.go
@@ -1,4 +1,4 @@
-package handlers
+package http_handlers
/**
LOGIC TO REMEMBER THE AUTHORIZE FLOW
@@ -39,13 +39,11 @@ import (
"github.com/gin-gonic/gin"
"github.com/google/uuid"
- log "github.com/sirupsen/logrus"
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/cookie"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/token"
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/cookie"
+ "github.com/authorizerdev/authorizer/internal/parsers"
+ "github.com/authorizerdev/authorizer/internal/token"
)
// Check the flow for generating and verifying codes: https://developer.okta.com/blog/2019/08/22/okta-authjs-pkce#:~:text=PKCE%20works%20by%20having%20the,is%20called%20the%20Code%20Challenge.
@@ -66,7 +64,8 @@ const (
// state[recommended] = to prevent CSRF attack (for authorizer its compulsory)
// code_challenge = to prevent CSRF attack
// code_challenge_method = to prevent CSRF attack [only sh256 is supported]
-func AuthorizeHandler() gin.HandlerFunc {
+func (h *httpProvider) AuthorizeHandler() gin.HandlerFunc {
+ log := h.Log.With().Str("func", "AuthorizeHandler").Logger()
return func(gc *gin.Context) {
redirectURI := strings.TrimSpace(gc.Query("redirect_uri"))
responseType := strings.TrimSpace(gc.Query("response_type"))
@@ -86,11 +85,7 @@ func AuthorizeHandler() gin.HandlerFunc {
}
if responseMode == "" {
- if val, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyDefaultAuthorizeResponseMode); err == nil {
- responseMode = val
- } else {
- responseMode = constants.ResponseModeQuery
- }
+ responseMode = h.Config.DefaultAuthorizeResponseMode
}
if redirectURI == "" {
@@ -98,15 +93,11 @@ func AuthorizeHandler() gin.HandlerFunc {
}
if responseType == "" {
- if val, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyDefaultAuthorizeResponseType); err == nil {
- responseType = val
- } else {
- responseType = constants.ResponseTypeToken
- }
+ responseType = h.Config.DefaultAuthorizeResponseType
}
- if err := validateAuthorizeRequest(responseType, responseMode, clientID, state, codeChallenge); err != nil {
- log.Debug("invalid authorization request: ", err)
+ if err := h.validateAuthorizeRequest(responseType, responseMode, clientID, state, codeChallenge); err != nil {
+ log.Debug().Err(err).Msg("Invalid request")
gc.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
@@ -116,23 +107,24 @@ func AuthorizeHandler() gin.HandlerFunc {
nonce = uuid.New().String()
}
- log := log.WithFields(log.Fields{
- "response_mode": responseMode,
- "response_type": responseType,
- })
+ log = log.With().Str("response_type", responseType).Str("response_mode", responseMode).Str("state", state).Str("code_challenge", codeChallenge).Str("scope", scopeString).Str("client_id", clientID).Str("nonce", nonce).Logger()
// TODO add state with timeout
// used for response mode query or fragment
authState := "state=" + state + "&scope=" + scopeString + "&redirect_uri=" + redirectURI
if responseType == constants.ResponseTypeCode {
authState += "&code=" + code
- if err := memorystore.Provider.SetState(state, code+"@@"+codeChallenge); err != nil {
- log.Debug("Error setting temp code", err)
+ if err := h.MemoryStoreProvider.SetState(state, code+"@@"+codeChallenge); err != nil {
+ log.Debug().Err(err).Msg("Error setting temp code")
+ gc.JSON(http.StatusInternalServerError, gin.H{"error": "internal server error"})
+ return
}
} else {
authState += "&nonce=" + nonce
- if err := memorystore.Provider.SetState(state, nonce); err != nil {
- log.Debug("Error setting temp code", err)
+ if err := h.MemoryStoreProvider.SetState(state, nonce); err != nil {
+ log.Debug().Err(err).Msg("Error setting temp nonce")
+ gc.JSON(http.StatusInternalServerError, gin.H{"error": "internal server error"})
+ return
}
}
@@ -168,23 +160,23 @@ func AuthorizeHandler() gin.HandlerFunc {
}
sessionToken, err := cookie.GetSession(gc)
if err != nil {
- log.Debug("GetSession failed: ", err)
+ log.Debug().Err(err).Msg("Error getting session token")
handleResponse(gc, responseMode, authURL, redirectURI, loginError, http.StatusOK)
return
}
// get session from cookie
- claims, err := token.ValidateBrowserSession(gc, sessionToken)
+ claims, err := h.TokenProvider.ValidateBrowserSession(gc, sessionToken)
if err != nil {
- log.Debug("ValidateBrowserSession failed: ", err)
+ log.Debug().Err(err).Msg("Error validating session token")
handleResponse(gc, responseMode, authURL, redirectURI, loginError, http.StatusOK)
return
}
userID := claims.Subject
- user, err := db.Provider.GetUserByID(gc, userID)
+ user, err := h.StorageProvider.GetUserByID(gc, userID)
if err != nil {
- log.Debug("GetUserByID failed: ", err)
+ log.Debug().Err(err).Msg("Error getting user")
handleResponse(gc, responseMode, authURL, redirectURI, map[string]interface{}{
"type": "authorization_response",
"response": map[string]interface{}{
@@ -201,11 +193,17 @@ func AuthorizeHandler() gin.HandlerFunc {
}
// rollover the session for security
- go memorystore.Provider.DeleteUserSession(sessionKey, claims.Nonce)
+ go h.MemoryStoreProvider.DeleteUserSession(sessionKey, claims.Nonce)
if responseType == constants.ResponseTypeCode {
- newSessionTokenData, newSessionToken, newSessionExpiresAt, err := token.CreateSessionToken(user, nonce, claims.Roles, scope, claims.LoginMethod)
+ newSessionTokenData, newSessionToken, newSessionExpiresAt, err := h.TokenProvider.CreateSessionToken(&token.AuthTokenConfig{
+ User: user,
+ Nonce: nonce,
+ Roles: claims.Roles,
+ Scope: scope,
+ LoginMethod: claims.LoginMethod,
+ })
if err != nil {
- log.Debug("CreateSessionToken failed: ", err)
+ log.Debug().Err(err).Msg("Error creating session token")
handleResponse(gc, responseMode, authURL, redirectURI, loginError, http.StatusOK)
return
}
@@ -218,19 +216,19 @@ func AuthorizeHandler() gin.HandlerFunc {
// }
// TODO: add state with timeout
- if err := memorystore.Provider.SetState(code, codeChallenge+"@@"+newSessionToken); err != nil {
- log.Debug("SetState failed: ", err)
+ if err := h.MemoryStoreProvider.SetState(code, codeChallenge+"@@"+newSessionToken); err != nil {
+ log.Debug().Err(err).Msg("Error setting temp code")
handleResponse(gc, responseMode, authURL, redirectURI, loginError, http.StatusOK)
return
}
- if err := memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+newSessionTokenData.Nonce, newSessionToken, newSessionExpiresAt); err != nil {
- log.Debug("SetUserSession failed: ", err)
+ if err := h.MemoryStoreProvider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+newSessionTokenData.Nonce, newSessionToken, newSessionExpiresAt); err != nil {
+ log.Debug().Err(err).Msg("Error setting session token")
handleResponse(gc, responseMode, authURL, redirectURI, loginError, http.StatusOK)
return
}
- cookie.SetSession(gc, newSessionToken)
+ cookie.SetSession(gc, newSessionToken, h.Config.AppCookieSecure)
// in case, response type is code and user is already logged in send the code and state
// and cookie session will already be rolled over and set
@@ -272,27 +270,35 @@ func AuthorizeHandler() gin.HandlerFunc {
}
if responseType == constants.ResponseTypeToken || responseType == constants.ResponseTypeIDToken {
+ hostname := parsers.GetHost(gc)
// rollover the session for security
- authToken, err := token.CreateAuthToken(gc, user, claims.Roles, scope, claims.LoginMethod, nonce, "")
+ authToken, err := h.TokenProvider.CreateAuthToken(gc, &token.AuthTokenConfig{
+ User: user,
+ Nonce: nonce,
+ Roles: claims.Roles,
+ Scope: scope,
+ LoginMethod: claims.LoginMethod,
+ HostName: hostname,
+ })
if err != nil {
- log.Debug("CreateAuthToken failed: ", err)
+ log.Debug().Err(err).Msg("Error creating auth token")
handleResponse(gc, responseMode, authURL, redirectURI, loginError, http.StatusOK)
return
}
- if err := memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+nonce, authToken.FingerPrintHash, authToken.SessionTokenExpiresAt); err != nil {
- log.Debug("SetUserSession failed: ", err)
+ if err := h.MemoryStoreProvider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+nonce, authToken.FingerPrintHash, authToken.SessionTokenExpiresAt); err != nil {
+ log.Debug().Err(err).Msg("Error setting session token")
handleResponse(gc, responseMode, authURL, redirectURI, loginError, http.StatusOK)
return
}
- if err := memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+nonce, authToken.AccessToken.Token, authToken.AccessToken.ExpiresAt); err != nil {
- log.Debug("SetUserSession failed: ", err)
+ if err := h.MemoryStoreProvider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+nonce, authToken.AccessToken.Token, authToken.AccessToken.ExpiresAt); err != nil {
+ log.Debug().Err(err).Msg("Error setting access token")
handleResponse(gc, responseMode, authURL, redirectURI, loginError, http.StatusOK)
return
}
- cookie.SetSession(gc, authToken.FingerPrintHash)
+ cookie.SetSession(gc, authToken.FingerPrintHash, h.Config.AppCookieSecure)
// used of query mode
params := "access_token=" + authToken.AccessToken.Token + "&token_type=bearer&expires_in=" + strconv.FormatInt(authToken.IDToken.ExpiresAt, 10) + "&state=" + state + "&id_token=" + authToken.IDToken.Token
@@ -314,7 +320,11 @@ func AuthorizeHandler() gin.HandlerFunc {
if authToken.RefreshToken != nil {
res["refresh_token"] = authToken.RefreshToken.Token
params += "&refresh_token=" + authToken.RefreshToken.Token
- memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token, authToken.RefreshToken.ExpiresAt)
+ if err := h.MemoryStoreProvider.SetUserSession(sessionKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token, authToken.RefreshToken.ExpiresAt); err != nil {
+ log.Debug().Err(err).Msg("Error setting refresh token")
+ handleResponse(gc, responseMode, authURL, redirectURI, loginError, http.StatusOK)
+ return
+ }
}
if responseMode == constants.ResponseModeQuery {
@@ -342,7 +352,7 @@ func AuthorizeHandler() gin.HandlerFunc {
}
}
-func validateAuthorizeRequest(responseType, responseMode, clientID, state, codeChallenge string) error {
+func (h *httpProvider) validateAuthorizeRequest(responseType, responseMode, clientID, state, codeChallenge string) error {
if strings.TrimSpace(state) == "" {
return fmt.Errorf("invalid state. state is required to prevent csrf attack")
}
@@ -354,7 +364,7 @@ func validateAuthorizeRequest(responseType, responseMode, clientID, state, codeC
return fmt.Errorf("invalid response mode %s. 'query', 'fragment', 'form_post' and 'web_message' are valid response_mode", responseMode)
}
- if client, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyClientID); client != clientID || err != nil {
+ if h.Config.ClientID != clientID {
return fmt.Errorf("invalid client_id %s", clientID)
}
diff --git a/server/middlewares/client_check.go b/internal/http_handlers/client_check.go
similarity index 51%
rename from server/middlewares/client_check.go
rename to internal/http_handlers/client_check.go
index 269a07570..2efd50ed9 100644
--- a/server/middlewares/client_check.go
+++ b/internal/http_handlers/client_check.go
@@ -1,22 +1,19 @@
-package middlewares
+package http_handlers
import (
"net/http"
"github.com/gin-gonic/gin"
- log "github.com/sirupsen/logrus"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/memorystore"
)
// ClientCheckMiddleware is a middleware to verify the client ID
// Note: client ID is passed in the header
-func ClientCheckMiddleware() gin.HandlerFunc {
+func (h *httpProvider) ClientCheckMiddleware() gin.HandlerFunc {
+ log := h.Log.With().Str("func", "ClientCheckMiddleware").Logger()
return func(c *gin.Context) {
clientID := c.Request.Header.Get("X-Authorizer-Client-ID")
- if client, _ := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyClientID); clientID != "" && client != "" && client != clientID {
- log.Debug("Client ID is invalid: ", clientID)
+ if clientID != "" && clientID != h.Config.ClientID {
+ log.Debug().Str("client_id", clientID).Msg("Client ID is invalid")
c.JSON(http.StatusBadRequest, gin.H{
"error": "invalid_client_id",
"error_description": "The client id is invalid",
diff --git a/internal/http_handlers/context.go b/internal/http_handlers/context.go
new file mode 100644
index 000000000..3c4ca2635
--- /dev/null
+++ b/internal/http_handlers/context.go
@@ -0,0 +1,21 @@
+package http_handlers
+
+import (
+ "context"
+
+ "github.com/gin-gonic/gin"
+)
+
+// Define a custom type for context key
+type contextKey string
+
+const ginContextKey contextKey = "GinContextKey"
+
+// ContextMiddleware is a middleware to add gin context in context
+func (h *httpProvider) ContextMiddleware() gin.HandlerFunc {
+ return func(c *gin.Context) {
+ ctx := context.WithValue(c.Request.Context(), ginContextKey, c)
+ c.Request = c.Request.WithContext(ctx)
+ c.Next()
+ }
+}
diff --git a/server/middlewares/cors.go b/internal/http_handlers/cors.go
similarity index 78%
rename from server/middlewares/cors.go
rename to internal/http_handlers/cors.go
index 514bf2aa5..00ba280a3 100644
--- a/server/middlewares/cors.go
+++ b/internal/http_handlers/cors.go
@@ -1,15 +1,16 @@
-package middlewares
+package http_handlers
import (
- "github.com/authorizerdev/authorizer/server/validators"
"github.com/gin-gonic/gin"
+
+ "github.com/authorizerdev/authorizer/internal/validators"
)
// CORSMiddleware is a middleware to add cors headers
-func CORSMiddleware() gin.HandlerFunc {
+func (h *httpProvider) CORSMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
origin := c.Request.Header.Get("Origin")
- if validators.IsValidOrigin(origin) {
+ if validators.IsValidOrigin(origin, h.Config.AllowedOrigins) {
c.Writer.Header().Set("Access-Control-Allow-Origin", origin)
}
diff --git a/internal/http_handlers/dashboard.go b/internal/http_handlers/dashboard.go
new file mode 100644
index 000000000..b05cecb5d
--- /dev/null
+++ b/internal/http_handlers/dashboard.go
@@ -0,0 +1,19 @@
+package http_handlers
+
+import (
+ "net/http"
+
+ "github.com/gin-gonic/gin"
+)
+
+// DashboardHandler is the handler for the /dashboard route
+func (h *httpProvider) DashboardHandler() gin.HandlerFunc {
+ return func(c *gin.Context) {
+
+ c.HTML(http.StatusOK, "dashboard.tmpl", gin.H{
+ "data": map[string]interface{}{
+ "isOnboardingCompleted": true,
+ },
+ })
+ }
+}
diff --git a/internal/http_handlers/graphql.go b/internal/http_handlers/graphql.go
new file mode 100644
index 000000000..152388b4c
--- /dev/null
+++ b/internal/http_handlers/graphql.go
@@ -0,0 +1,82 @@
+package http_handlers
+
+import (
+ "context"
+ "net/http"
+
+ gql "github.com/99designs/gqlgen/graphql"
+ "github.com/99designs/gqlgen/graphql/handler"
+ "github.com/99designs/gqlgen/graphql/handler/extension"
+ "github.com/99designs/gqlgen/graphql/handler/lru"
+ "github.com/99designs/gqlgen/graphql/handler/transport"
+ "github.com/gin-gonic/gin"
+ "github.com/vektah/gqlparser/v2/ast"
+
+ "github.com/authorizerdev/authorizer/internal/graph"
+ "github.com/authorizerdev/authorizer/internal/graph/generated"
+ "github.com/authorizerdev/authorizer/internal/graphql"
+)
+
+func (h *httpProvider) gqlLoggingMiddleware() gql.FieldMiddleware {
+ return func(ctx context.Context, next gql.Resolver) (res interface{}, err error) {
+ // Get details of the current operation
+ oc := gql.GetOperationContext(ctx)
+ field := gql.GetFieldContext(ctx)
+
+ // Log operation details
+ h.Dependencies.Log.Info().
+ Str("operation", oc.OperationName).
+ Str("query", field.Field.Name).
+ // Interface("arguments", field.Args). // Enable only for debugging purpose else sensitive data will be logged
+ Msg("GraphQL field resolved")
+
+ // Call the next resolver
+ return next(ctx)
+ }
+}
+
+// GraphqlHandler is the main handler that handels all the graphql requests
+func (h *httpProvider) GraphqlHandler() gin.HandlerFunc {
+ gqlProvider, err := graphql.New(h.Config, &graphql.Dependencies{
+ Log: h.Log,
+ AuthenticatorProvider: h.AuthenticatorProvider,
+ EmailProvider: h.EmailProvider,
+ EventsProvider: h.EventsProvider,
+ MemoryStoreProvider: h.MemoryStoreProvider,
+ SMSProvider: h.SMSProvider,
+ StorageProvider: h.StorageProvider,
+ TokenProvider: h.TokenProvider,
+ })
+ if err != nil {
+ h.Log.Error().Err(err).Msg("Failed to create graphql provider")
+ return nil
+ }
+
+ // NewExecutableSchema and Config are in the generated.go file
+ // Resolver is in the resolver.go file
+ srv := handler.New(generated.NewExecutableSchema(generated.Config{Resolvers: &graph.Resolver{
+ GraphQLProvider: gqlProvider,
+ }}))
+
+ srv.AddTransport(transport.Options{})
+ srv.AddTransport(transport.GET{})
+ srv.AddTransport(transport.POST{})
+
+ srv.SetQueryCache(lru.New[*ast.QueryDocument](1000))
+ srv.AroundFields(h.gqlLoggingMiddleware())
+ srv.Use(extension.Introspection{})
+ srv.Use(extension.AutomaticPersistedQuery{
+ Cache: lru.New[string](100),
+ })
+
+ return func(c *gin.Context) {
+ // Create a custom handler that ensures gin context is available
+ handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ // Ensure the gin context is available in the request context
+ ctx := context.WithValue(r.Context(), "GinContextKey", c)
+ r = r.WithContext(ctx)
+ srv.ServeHTTP(w, r)
+ })
+ handler.ServeHTTP(c.Writer, c.Request)
+ }
+}
diff --git a/server/handlers/health.go b/internal/http_handlers/health.go
similarity index 66%
rename from server/handlers/health.go
rename to internal/http_handlers/health.go
index 2ee314294..63d8a668f 100644
--- a/server/handlers/health.go
+++ b/internal/http_handlers/health.go
@@ -1,4 +1,4 @@
-package handlers
+package http_handlers
import (
"net/http"
@@ -8,7 +8,8 @@ import (
// HealthHandler is the handler for /health route.
// It states if server is in healthy state or not
-func HealthHandler() gin.HandlerFunc {
+func (h *httpProvider) HealthHandler() gin.HandlerFunc {
+ h.Log.Info().Msg("Health check")
return func(c *gin.Context) {
c.String(http.StatusOK, "OK")
}
diff --git a/internal/http_handlers/jwks.go b/internal/http_handlers/jwks.go
new file mode 100644
index 000000000..a82468b43
--- /dev/null
+++ b/internal/http_handlers/jwks.go
@@ -0,0 +1,81 @@
+package http_handlers
+
+import (
+ "encoding/json"
+
+ "github.com/authorizerdev/authorizer/internal/crypto"
+ "github.com/gin-gonic/gin"
+)
+
+// generateJWKBasedOnEnv generates JWK based on root args config
+// make sure clientID, jwtType, jwtSecret / public & private key pair is set
+// this is called while initializing app / when env is updated
+func (h *httpProvider) generateJWKBasedOnEnv() (string, error) {
+ jwk := ""
+ algo := h.JWTType
+ clientID := h.ClientID
+ jwtSecret := h.JWTSecret
+ jwtPublicKey := h.JWTPublicKey
+ var err error
+ // check if jwt secret is provided
+ if crypto.IsHMACA(algo) {
+ jwk, err = crypto.GetPubJWK(algo, clientID, []byte(jwtSecret))
+ if err != nil {
+ return "", err
+ }
+ }
+
+ if crypto.IsRSA(algo) {
+ publicKeyInstance, err := crypto.ParseRsaPublicKeyFromPemStr(jwtPublicKey)
+ if err != nil {
+ return "", err
+ }
+
+ jwk, err = crypto.GetPubJWK(algo, clientID, publicKeyInstance)
+ if err != nil {
+ return "", err
+ }
+ }
+
+ if crypto.IsECDSA(algo) {
+ publicKeyInstance, err := crypto.ParseEcdsaPublicKeyFromPemStr(jwtPublicKey)
+ if err != nil {
+ return "", err
+ }
+
+ jwk, err = crypto.GetPubJWK(algo, clientID, publicKeyInstance)
+ if err != nil {
+ return "", err
+ }
+ }
+
+ return jwk, nil
+}
+
+func (h *httpProvider) JWKsHandler() gin.HandlerFunc {
+ log := h.Log.With().Str("func", "JWKsHandler").Logger()
+ return func(c *gin.Context) {
+ var data map[string]string
+ jwk, err := h.generateJWKBasedOnEnv()
+ if err != nil {
+ log.Debug().Err(err).Msg("Error generating JWK")
+ c.JSON(500, gin.H{
+ "error": err.Error(),
+ })
+ return
+ }
+ err = json.Unmarshal([]byte(jwk), &data)
+ if err != nil {
+ log.Debug().Err(err).Msg("Error unmarshalling JWK")
+ c.JSON(500, gin.H{
+ "error": err.Error(),
+ })
+ return
+ }
+ c.JSON(200, gin.H{
+ "keys": []map[string]string{
+ data,
+ },
+ })
+ }
+}
diff --git a/internal/http_handlers/logger.go b/internal/http_handlers/logger.go
new file mode 100644
index 000000000..eaad9d3d1
--- /dev/null
+++ b/internal/http_handlers/logger.go
@@ -0,0 +1,27 @@
+package http_handlers
+
+import (
+ "time"
+
+ "github.com/gin-gonic/gin"
+)
+
+// LoggerMiddleware adds logging to Gin using rs/zerolog.
+func (h *httpProvider) LoggerMiddleware() gin.HandlerFunc {
+ return func(c *gin.Context) {
+ start := time.Now()
+
+ // Process the request
+ c.Next()
+
+ // Log the request and response details
+ h.Dependencies.Log.Info().
+ Str("method", c.Request.Method).
+ Str("path", c.Request.URL.Path).
+ Int("status", c.Writer.Status()).
+ Int("size", c.Writer.Size()).
+ Str("client_ip", c.ClientIP()).
+ Dur("latency", time.Since(start)).
+ Msg("HTTP request")
+ }
+}
diff --git a/server/handlers/logout.go b/internal/http_handlers/logout.go
similarity index 60%
rename from server/handlers/logout.go
rename to internal/http_handlers/logout.go
index fbac22d49..364702f84 100644
--- a/server/handlers/logout.go
+++ b/internal/http_handlers/logout.go
@@ -1,4 +1,4 @@
-package handlers
+package http_handlers
import (
"encoding/json"
@@ -6,31 +6,30 @@ import (
"strings"
"github.com/gin-gonic/gin"
- log "github.com/sirupsen/logrus"
- "github.com/authorizerdev/authorizer/server/cookie"
- "github.com/authorizerdev/authorizer/server/crypto"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/token"
+ "github.com/authorizerdev/authorizer/internal/cookie"
+ "github.com/authorizerdev/authorizer/internal/crypto"
+ "github.com/authorizerdev/authorizer/internal/token"
)
// Handler to logout user
-func LogoutHandler() gin.HandlerFunc {
+func (h *httpProvider) LogoutHandler() gin.HandlerFunc {
+ log := h.Log.With().Str("func", "LogoutHandler").Logger()
return func(gc *gin.Context) {
redirectURL := strings.TrimSpace(gc.Query("redirect_uri"))
// get fingerprint hash
fingerprintHash, err := cookie.GetSession(gc)
if err != nil {
- log.Debug("Failed to get session: ", err)
+ log.Debug().Err(err).Msg("failed GetSession")
gc.JSON(http.StatusUnauthorized, gin.H{
"error": err.Error(),
})
return
}
- decryptedFingerPrint, err := crypto.DecryptAES(fingerprintHash)
+ decryptedFingerPrint, err := crypto.DecryptAES(h.ClientSecret, fingerprintHash)
if err != nil {
- log.Debug("Failed to decrypt fingerprint: ", err)
+ log.Debug().Err(err).Msg("failed to decrypt fingerprint")
gc.JSON(http.StatusUnauthorized, gin.H{
"error": err.Error(),
})
@@ -40,7 +39,7 @@ func LogoutHandler() gin.HandlerFunc {
var sessionData token.SessionData
err = json.Unmarshal([]byte(decryptedFingerPrint), &sessionData)
if err != nil {
- log.Debug("Failed to decrypt fingerprint: ", err)
+ log.Debug().Err(err).Msg("failed to unmarshal session data")
gc.JSON(http.StatusUnauthorized, gin.H{
"error": err.Error(),
})
@@ -54,8 +53,8 @@ func LogoutHandler() gin.HandlerFunc {
sessionToken = loginMethod + ":" + userID
}
- memorystore.Provider.DeleteUserSession(sessionToken, sessionData.Nonce)
- cookie.DeleteSession(gc)
+ h.MemoryStoreProvider.DeleteUserSession(sessionToken, sessionData.Nonce)
+ cookie.DeleteSession(gc, h.Config.AppCookieSecure)
if redirectURL != "" {
gc.Redirect(http.StatusFound, redirectURL)
diff --git a/server/handlers/oauth_callback.go b/internal/http_handlers/oauth_callback.go
similarity index 59%
rename from server/handlers/oauth_callback.go
rename to internal/http_handlers/oauth_callback.go
index f3610f47c..c04d0ec15 100644
--- a/server/handlers/oauth_callback.go
+++ b/internal/http_handlers/oauth_callback.go
@@ -1,7 +1,6 @@
-package handlers
+package http_handlers
import (
- "context"
"encoding/base64"
"encoding/json"
"fmt"
@@ -16,20 +15,16 @@ import (
"github.com/gin-gonic/gin"
"github.com/google/uuid"
- log "github.com/sirupsen/logrus"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/cookie"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/db/models"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/oauth"
- "github.com/authorizerdev/authorizer/server/refs"
- "github.com/authorizerdev/authorizer/server/token"
- "github.com/authorizerdev/authorizer/server/utils"
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/cookie"
+ "github.com/authorizerdev/authorizer/internal/parsers"
+ "github.com/authorizerdev/authorizer/internal/refs"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
+ "github.com/authorizerdev/authorizer/internal/token"
+ "github.com/authorizerdev/authorizer/internal/utils"
)
-// OAuthCallbackHandler handles the OAuth callback for various oauth providers
+// AppleUserInfo is the struct for apple user info
type AppleUserInfo struct {
Email string `json:"email"`
Name struct {
@@ -38,13 +33,15 @@ type AppleUserInfo struct {
} `json:"name"`
}
-func OAuthCallbackHandler() gin.HandlerFunc {
+// OAuthCallbackHandler handles the OAuth callback for various oauth providers
+func (h *httpProvider) OAuthCallbackHandler() gin.HandlerFunc {
+ log := h.Log.With().Str("func", "OAuthCallbackHandler").Logger()
return func(ctx *gin.Context) {
provider := ctx.Param("oauth_provider")
state := ctx.Request.FormValue("state")
- sessionState, err := memorystore.Provider.GetState(state)
+ sessionState, err := h.MemoryStoreProvider.GetState(state)
if sessionState == "" || err != nil {
- log.Debug("Invalid oauth state: ", state)
+ log.Debug().Err(err).Msg("Failed to get state from store")
ctx.JSON(400, gin.H{"error": "invalid oauth state"})
return
}
@@ -52,12 +49,12 @@ func OAuthCallbackHandler() gin.HandlerFunc {
sessionSplit := strings.Split(state, "___")
if len(sessionSplit) < 3 {
- log.Debug("Unable to get redirect url from state: ", state)
+ log.Debug().Err(err).Msg("Invalid state")
ctx.JSON(400, gin.H{"error": "invalid redirect url"})
return
}
// remove state from store
- go memorystore.Provider.RemoveState(state)
+ go h.MemoryStoreProvider.RemoveState(state)
stateValue := sessionSplit[0]
redirectURL := sessionSplit[1]
inputRoles := strings.Split(sessionSplit[2], ",")
@@ -71,68 +68,68 @@ func OAuthCallbackHandler() gin.HandlerFunc {
scopes = strings.Split(scopeString, " ")
}
}
- var user *models.User
+ var user *schemas.User
oauthCode := ctx.Request.FormValue("code")
if oauthCode == "" {
- log.Debug("Invalid oauth code: ", oauthCode)
+ log.Debug().Err(err).Msg("Invalid oauth code")
ctx.JSON(400, gin.H{"error": "invalid oauth code"})
return
}
switch provider {
case constants.AuthRecipeMethodGoogle:
- user, err = processGoogleUserInfo(ctx, oauthCode)
+ user, err = h.processGoogleUserInfo(ctx, oauthCode)
case constants.AuthRecipeMethodGithub:
- user, err = processGithubUserInfo(ctx, oauthCode)
+ user, err = h.processGithubUserInfo(ctx, oauthCode)
case constants.AuthRecipeMethodFacebook:
- user, err = processFacebookUserInfo(ctx, oauthCode)
+ user, err = h.processFacebookUserInfo(ctx, oauthCode)
case constants.AuthRecipeMethodLinkedIn:
- user, err = processLinkedInUserInfo(ctx, oauthCode)
+ user, err = h.processLinkedInUserInfo(ctx, oauthCode)
case constants.AuthRecipeMethodApple:
user_ := AppleUserInfo{}
userRaw := ctx.Request.FormValue("user")
err = json.Unmarshal([]byte(userRaw), &user_)
- user, err = processAppleUserInfo(ctx, oauthCode, &user_)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to unmarshal apple user info")
+ ctx.JSON(400, gin.H{"error": "invalid apple user info"})
+ return
+ }
+ user, err = h.processAppleUserInfo(ctx, oauthCode, &user_)
case constants.AuthRecipeMethodDiscord:
- user, err = processDiscordUserInfo(ctx, oauthCode)
+ user, err = h.processDiscordUserInfo(ctx, oauthCode)
case constants.AuthRecipeMethodTwitter:
- user, err = processTwitterUserInfo(ctx, oauthCode, sessionState)
+ user, err = h.processTwitterUserInfo(ctx, oauthCode, sessionState)
case constants.AuthRecipeMethodMicrosoft:
- user, err = processMicrosoftUserInfo(ctx, oauthCode)
+ user, err = h.processMicrosoftUserInfo(ctx, oauthCode)
case constants.AuthRecipeMethodTwitch:
- user, err = processTwitchUserInfo(ctx, oauthCode)
+ user, err = h.processTwitchUserInfo(ctx, oauthCode)
case constants.AuthRecipeMethodRoblox:
- user, err = processRobloxUserInfo(ctx, oauthCode, sessionState)
+ user, err = h.processRobloxUserInfo(ctx, oauthCode, sessionState)
default:
- log.Info("Invalid oauth provider")
+ log.Debug().Err(err).Msg("Invalid oauth provider")
err = fmt.Errorf(`invalid oauth provider`)
}
if err != nil {
- log.Debug("Failed to process user info: ", err)
+ log.Debug().Err(err).Msg("Failed to process user info")
ctx.JSON(400, gin.H{"error": err.Error()})
return
}
if user == nil {
- log.Debug("User is nil")
+ log.Debug().Err(err).Msg("Failed to get user")
ctx.JSON(
500,
gin.H{"error": "Something Went Wrong. Please Try Again."},
)
return
}
- existingUser, err := db.Provider.GetUserByEmail(ctx, refs.StringValue(user.Email))
- log := log.WithField("user", user.Email)
+ existingUser, err := h.StorageProvider.GetUserByEmail(ctx, refs.StringValue(user.Email))
+ log := log.With().Str("email", refs.StringValue(user.Email)).Logger()
isSignUp := false
if err != nil {
- isSignupDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableSignUp)
- if err != nil {
- log.Debug("Failed to get signup disabled env variable: ", err)
- ctx.JSON(400, gin.H{"error": err.Error()})
- return
- }
- if isSignupDisabled {
- log.Debug("Failed to signup as disabled")
+ isSignupEnabled := h.Config.EnableSignup
+ if !isSignupEnabled {
+ log.Debug().Err(err).Msg("Signup is disabled")
ctx.JSON(400, gin.H{"error": "signup is disabled for this instance"})
return
}
@@ -141,21 +138,14 @@ func OAuthCallbackHandler() gin.HandlerFunc {
// make sure inputRoles don't include protected roles
hasProtectedRole := false
for _, ir := range inputRoles {
- protectedRolesString, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyProtectedRoles)
- protectedRoles := []string{}
- if err != nil {
- log.Debug("Failed to get protected roles: ", err)
- protectedRolesString = ""
- } else {
- protectedRoles = strings.Split(protectedRolesString, ",")
- }
+ protectedRoles := h.Config.ProtectedRoles
if utils.StringSliceContains(protectedRoles, ir) {
hasProtectedRole = true
}
}
if hasProtectedRole {
- log.Debug("Signup is not allowed with protected roles:", inputRoles)
+ log.Debug().Err(err).Msg("Invalid role. User is using protected role")
ctx.JSON(400, gin.H{"error": "invalid role"})
return
}
@@ -163,12 +153,17 @@ func OAuthCallbackHandler() gin.HandlerFunc {
user.Roles = strings.Join(inputRoles, ",")
now := time.Now().Unix()
user.EmailVerifiedAt = &now
- user, _ = db.Provider.AddUser(ctx, user)
+ user, err = h.StorageProvider.AddUser(ctx, user)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to add user")
+ ctx.JSON(500, gin.H{"error": err.Error()})
+ return
+ }
isSignUp = true
} else {
user = existingUser
if user.RevokedTimestamp != nil {
- log.Debug("User access revoked at: ", user.RevokedTimestamp)
+ log.Debug().Msg("User access has been revoked")
ctx.JSON(400, gin.H{"error": "user access has been revoked"})
return
}
@@ -204,21 +199,14 @@ func OAuthCallbackHandler() gin.HandlerFunc {
// check if it contains protected unassigned role
hasProtectedRole := false
for _, ur := range unasignedRoles {
- protectedRolesString, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyProtectedRoles)
- protectedRoles := []string{}
- if err != nil {
- log.Debug("Failed to get protected roles: ", err)
- protectedRolesString = ""
- } else {
- protectedRoles = strings.Split(protectedRolesString, ",")
- }
+ protectedRoles := h.Config.ProtectedRoles
if utils.StringSliceContains(protectedRoles, ur) {
hasProtectedRole = true
}
}
if hasProtectedRole {
- log.Debug("Invalid role. User is using protected unassigned role")
+ log.Debug().Err(err).Msg("Invalid role. User is using protected role")
ctx.JSON(400, gin.H{"error": "invalid role"})
return
} else {
@@ -228,9 +216,9 @@ func OAuthCallbackHandler() gin.HandlerFunc {
user.Roles = existingUser.Roles
}
- user, err = db.Provider.UpdateUser(ctx, user)
+ user, err = h.StorageProvider.UpdateUser(ctx, user)
if err != nil {
- log.Debug("Failed to update user: ", err)
+ log.Debug().Err(err).Msg("Failed to update user")
ctx.JSON(500, gin.H{"error": err.Error()})
return
}
@@ -244,7 +232,7 @@ func OAuthCallbackHandler() gin.HandlerFunc {
nonce := ""
if stateValue != "" {
// Get state from store
- authorizeState, _ := memorystore.Provider.GetState(stateValue)
+ authorizeState, _ := h.MemoryStoreProvider.GetState(stateValue)
if authorizeState != "" {
authorizeStateSplit := strings.Split(authorizeState, "@@")
if len(authorizeStateSplit) > 1 {
@@ -253,22 +241,31 @@ func OAuthCallbackHandler() gin.HandlerFunc {
} else {
nonce = authorizeState
}
- go memorystore.Provider.RemoveState(stateValue)
+ go h.MemoryStoreProvider.RemoveState(stateValue)
}
}
if nonce == "" {
nonce = uuid.New().String()
}
- authToken, err := token.CreateAuthToken(ctx, user, inputRoles, scopes, provider, nonce, code)
+ hostname := parsers.GetHost(ctx)
+ // user, inputRoles, scopes, provider, nonce, code
+ authToken, err := h.TokenProvider.CreateAuthToken(ctx, &token.AuthTokenConfig{
+ User: user,
+ Roles: inputRoles,
+ Scope: scopes,
+ LoginMethod: provider,
+ Nonce: nonce,
+ HostName: hostname,
+ })
if err != nil {
- log.Debug("Failed to create auth token: ", err)
+ log.Debug().Err(err).Msg("Failed to create auth token")
ctx.JSON(500, gin.H{"error": err.Error()})
}
// Code challenge could be optional if PKCE flow is not used
if code != "" {
- if err := memorystore.Provider.SetState(code, codeChallenge+"@@"+authToken.FingerPrintHash); err != nil {
- log.Debug("SetState failed: ", err)
+ if err := h.MemoryStoreProvider.SetState(code, codeChallenge+"@@"+authToken.FingerPrintHash); err != nil {
+ log.Debug().Err(err).Msg("Failed to set state")
ctx.JSON(500, gin.H{"error": err.Error()})
}
}
@@ -286,28 +283,30 @@ func OAuthCallbackHandler() gin.HandlerFunc {
}
sessionKey := provider + ":" + user.ID
- cookie.SetSession(ctx, authToken.FingerPrintHash)
- memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash, authToken.SessionTokenExpiresAt)
- memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token, authToken.AccessToken.ExpiresAt)
+ cookie.SetSession(ctx, authToken.FingerPrintHash, h.Config.AppCookieSecure)
+ h.MemoryStoreProvider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash, authToken.SessionTokenExpiresAt)
+ h.MemoryStoreProvider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token, authToken.AccessToken.ExpiresAt)
if authToken.RefreshToken != nil {
params += `&refresh_token=` + authToken.RefreshToken.Token
- memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token, authToken.RefreshToken.ExpiresAt)
+ h.MemoryStoreProvider.SetUserSession(sessionKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token, authToken.RefreshToken.ExpiresAt)
}
go func() {
if isSignUp {
- utils.RegisterEvent(ctx, constants.UserSignUpWebhookEvent, provider, user)
+ h.EventsProvider.RegisterEvent(ctx, constants.UserSignUpWebhookEvent, provider, user)
// User is also logged in with signup
- utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, provider, user)
+ h.EventsProvider.RegisterEvent(ctx, constants.UserLoginWebhookEvent, provider, user)
} else {
- utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, provider, user)
+ h.EventsProvider.RegisterEvent(ctx, constants.UserLoginWebhookEvent, provider, user)
}
- db.Provider.AddSession(ctx, &models.Session{
+ if err := h.StorageProvider.AddSession(ctx, &schemas.Session{
UserID: user.ID,
UserAgent: utils.GetUserAgent(ctx.Request),
IP: utils.GetIP(ctx.Request),
- })
+ }); err != nil {
+ log.Debug().Err(err).Msg("Failed to add session")
+ }
}()
if strings.Contains(redirectURL, "?") {
redirectURL = redirectURL + "&" + params
@@ -319,46 +318,63 @@ func OAuthCallbackHandler() gin.HandlerFunc {
}
}
-func processGoogleUserInfo(ctx context.Context, code string) (*models.User, error) {
- oauth2Token, err := oauth.OAuthProviders.GoogleConfig.Exchange(ctx, code)
+func (h *httpProvider) processGoogleUserInfo(ctx *gin.Context, code string) (*schemas.User, error) {
+ log := h.Log.With().Str("func", "processGoogleUserInfo").Logger()
+ cfg, err := h.OAuthProvider.GetOAuthConfig(ctx, constants.AuthRecipeMethodGoogle)
+ if err != nil {
+ log.Debug().Err(err).Msg("Error getting oauth config")
+ return nil, fmt.Errorf("error getting oauth config: %s", err.Error())
+ }
+ oauth2Token, err := cfg.Exchange(ctx, code)
if err != nil {
- log.Debug("Failed to exchange code for token: ", err)
+ log.Debug().Err(err).Msg("Failed to exchange code for token")
return nil, fmt.Errorf("invalid google exchange code: %s", err.Error())
}
- verifier := oauth.OIDCProviders.GoogleOIDC.Verifier(&oidc.Config{ClientID: oauth.OAuthProviders.GoogleConfig.ClientID})
+ oidcProvider, err := oidc.NewProvider(ctx, "https://accounts.google.com")
+ verifier := oidcProvider.Verifier(&oidc.Config{ClientID: h.GoogleClientID})
+ if err != nil {
+ return nil, fmt.Errorf("failed to create oidc provider: %s", err.Error())
+ }
// Extract the ID Token from OAuth2 token.
rawIDToken, ok := oauth2Token.Extra("id_token").(string)
if !ok {
- log.Debug("Failed to extract ID Token from OAuth2 token")
+ log.Debug().Err(err).Msg("Failed to extract ID Token from OAuth2 token")
return nil, fmt.Errorf("unable to extract id_token")
}
// Parse and verify ID Token payload.
idToken, err := verifier.Verify(ctx, rawIDToken)
if err != nil {
- log.Debug("Failed to verify ID Token: ", err)
+ log.Debug().Err(err).Msg("Failed to verify ID Token")
return nil, fmt.Errorf("unable to verify id_token: %s", err.Error())
}
- user := &models.User{}
+ user := &schemas.User{}
if err := idToken.Claims(&user); err != nil {
- log.Debug("Failed to parse ID Token claims: ", err)
+ log.Debug().Err(err).Msg("Failed to parse ID Token claims")
return nil, fmt.Errorf("unable to extract claims")
}
return user, nil
}
-func processGithubUserInfo(ctx context.Context, code string) (*models.User, error) {
- oauth2Token, err := oauth.OAuthProviders.GithubConfig.Exchange(ctx, code)
+func (h *httpProvider) processGithubUserInfo(ctx *gin.Context, code string) (*schemas.User, error) {
+ log := h.Log.With().Str("func", "processGithubUserInfo").Logger()
+ cfg, err := h.OAuthProvider.GetOAuthConfig(ctx, constants.AuthRecipeMethodGithub)
+ if err != nil {
+ log.Debug().Err(err).Msg("Error getting oauth config")
+ return nil, fmt.Errorf("error getting oauth config: %s", err.Error())
+ }
+
+ oauth2Token, err := cfg.Exchange(ctx, code)
if err != nil {
- log.Debug("Failed to exchange code for token: ", err)
+ log.Debug().Err(err).Msg("Failed to exchange code for token")
return nil, fmt.Errorf("invalid github exchange code: %s", err.Error())
}
client := http.Client{}
req, err := http.NewRequest("GET", constants.GithubUserInfoURL, nil)
if err != nil {
- log.Debug("Failed to create github user info request: ", err)
+ log.Debug().Err(err).Msg("Failed to create github user info request")
return nil, fmt.Errorf("error creating github user info request: %s", err.Error())
}
req.Header.Set(
@@ -367,18 +383,18 @@ func processGithubUserInfo(ctx context.Context, code string) (*models.User, erro
response, err := client.Do(req)
if err != nil {
- log.Debug("Failed to request github user info: ", err)
+ log.Debug().Err(err).Msg("Failed to request github user info")
return nil, err
}
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil {
- log.Debug("Failed to read github user info response body: ", err)
+ log.Debug().Err(err).Msg("Failed to read github user info response body")
return nil, fmt.Errorf("failed to read github response body: %s", err.Error())
}
if response.StatusCode >= 400 {
- log.Debug("Failed to request github user info: ", string(body))
+ log.Debug().Err(err).Str("body", string(body)).Msg("Failed to request github user info")
return nil, fmt.Errorf("failed to request github user info: %s", string(body))
}
@@ -407,7 +423,7 @@ func processGithubUserInfo(ctx context.Context, code string) (*models.User, erro
// fetch using /users/email endpoint
req, err := http.NewRequest(http.MethodGet, constants.GithubUserEmails, nil)
if err != nil {
- log.Debug("Failed to create github emails request: ", err)
+ log.Debug().Err(err).Msg("Failed to create github emails request")
return nil, fmt.Errorf("error creating github user info request: %s", err.Error())
}
req.Header.Set(
@@ -416,25 +432,25 @@ func processGithubUserInfo(ctx context.Context, code string) (*models.User, erro
response, err := client.Do(req)
if err != nil {
- log.Debug("Failed to request github user email: ", err)
+ log.Debug().Err(err).Msg("Failed to request github user email")
return nil, err
}
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil {
- log.Debug("Failed to read github user email response body: ", err)
+ log.Debug().Err(err).Msg("Failed to read github user email response body")
return nil, fmt.Errorf("failed to read github response body: %s", err.Error())
}
if response.StatusCode >= 400 {
- log.Debug("Failed to request github user email: ", string(body))
+ log.Debug().Err(err).Str("body", string(body)).Msg("Failed to request github user email")
return nil, fmt.Errorf("failed to request github user info: %s", string(body))
}
emailData := []GithubUserEmails{}
err = json.Unmarshal(body, &emailData)
if err != nil {
- log.Debug("Failed to parse github user email: ", err)
+ log.Debug().Err(err).Msg("Failed to parse github user email")
return nil, fmt.Errorf("failed to parse github user email: %s", err.Error())
}
@@ -446,7 +462,7 @@ func processGithubUserInfo(ctx context.Context, code string) (*models.User, erro
}
}
- user := &models.User{
+ user := &schemas.User{
GivenName: &firstName,
FamilyName: &lastName,
Picture: &picture,
@@ -456,33 +472,39 @@ func processGithubUserInfo(ctx context.Context, code string) (*models.User, erro
return user, nil
}
-func processFacebookUserInfo(ctx context.Context, code string) (*models.User, error) {
- oauth2Token, err := oauth.OAuthProviders.FacebookConfig.Exchange(ctx, code)
+func (h *httpProvider) processFacebookUserInfo(ctx *gin.Context, code string) (*schemas.User, error) {
+ log := h.Log.With().Str("func", "processFacebookUserInfo").Logger()
+ cfg, err := h.OAuthProvider.GetOAuthConfig(ctx, constants.AuthRecipeMethodFacebook)
if err != nil {
- log.Debug("Invalid facebook exchange code: ", err)
+ log.Debug().Err(err).Msg("Error getting oauth config")
+ return nil, fmt.Errorf("error getting oauth config: %s", err.Error())
+ }
+ oauth2Token, err := cfg.Exchange(ctx, code)
+ if err != nil {
+ log.Debug().Err(err).Msg("Invalid facebook exchange code")
return nil, fmt.Errorf("invalid facebook exchange code: %s", err.Error())
}
client := http.Client{}
req, err := http.NewRequest("GET", constants.FacebookUserInfoURL+oauth2Token.AccessToken, nil)
if err != nil {
- log.Debug("Error creating facebook user info request: ", err)
+ log.Debug().Err(err).Msg("Error creating facebook user info request")
return nil, fmt.Errorf("error creating facebook user info request: %s", err.Error())
}
response, err := client.Do(req)
if err != nil {
- log.Debug("Failed to process facebook user: ", err)
+ log.Debug().Err(err).Msg("Failed to process facebook user")
return nil, err
}
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil {
- log.Debug("Failed to read facebook response: ", err)
+ log.Debug().Err(err).Msg("Failed to read facebook response")
return nil, fmt.Errorf("failed to read facebook response body: %s", err.Error())
}
if response.StatusCode >= 400 {
- log.Debug("Failed to request facebook user info: ", string(body))
+ log.Debug().Err(err).Str("body", string(body)).Msg("Failed to request facebook user info")
return nil, fmt.Errorf("failed to request facebook user info: %s", string(body))
}
userRawData := make(map[string]interface{})
@@ -496,7 +518,7 @@ func processFacebookUserInfo(ctx context.Context, code string) (*models.User, er
lastName := fmt.Sprintf("%v", userRawData["last_name"])
picture := fmt.Sprintf("%v", picDataObject["url"])
- user := &models.User{
+ user := &schemas.User{
GivenName: &firstName,
FamilyName: &lastName,
Picture: &picture,
@@ -506,17 +528,24 @@ func processFacebookUserInfo(ctx context.Context, code string) (*models.User, er
return user, nil
}
-func processLinkedInUserInfo(ctx context.Context, code string) (*models.User, error) {
- oauth2Token, err := oauth.OAuthProviders.LinkedInConfig.Exchange(ctx, code)
+func (h *httpProvider) processLinkedInUserInfo(ctx *gin.Context, code string) (*schemas.User, error) {
+ log := h.Log.With().Str("func", "processLinkedInUserInfo").Logger()
+ cfg, err := h.OAuthProvider.GetOAuthConfig(ctx, constants.AuthRecipeMethodLinkedIn)
+ if err != nil {
+ log.Debug().Err(err).Msg("Error getting oauth config")
+ return nil, fmt.Errorf("error getting oauth config: %s", err.Error())
+ }
+
+ oauth2Token, err := cfg.Exchange(ctx, code)
if err != nil {
- log.Debug("Failed to exchange code for token: ", err)
+ log.Debug().Err(err).Msg("Failed to exchange code for token")
return nil, fmt.Errorf("invalid linkedin exchange code: %s", err.Error())
}
client := http.Client{}
req, err := http.NewRequest("GET", constants.LinkedInUserInfoURL, nil)
if err != nil {
- log.Debug("Failed to create linkedin user info request: ", err)
+ log.Debug().Err(err).Msg("Failed to create linkedin user info request")
return nil, fmt.Errorf("error creating linkedin user info request: %s", err.Error())
}
req.Header = http.Header{
@@ -525,19 +554,19 @@ func processLinkedInUserInfo(ctx context.Context, code string) (*models.User, er
response, err := client.Do(req)
if err != nil {
- log.Debug("Failed to request linkedin user info: ", err)
+ log.Debug().Err(err).Msg("Failed to request linkedin user info")
return nil, err
}
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil {
- log.Debug("Failed to read linkedin user info response body: ", err)
+ log.Debug().Err(err).Msg("Failed to read linkedin user info response body")
return nil, fmt.Errorf("failed to read linkedin response body: %s", err.Error())
}
if response.StatusCode >= 400 {
- log.Debug("Failed to request linkedin user info: ", string(body))
+ log.Debug().Err(err).Str("body", string(body)).Msg("Failed to request linkedin user info")
return nil, fmt.Errorf("failed to request linkedin user info: %s", string(body))
}
@@ -546,7 +575,7 @@ func processLinkedInUserInfo(ctx context.Context, code string) (*models.User, er
req, err = http.NewRequest("GET", constants.LinkedInEmailURL, nil)
if err != nil {
- log.Debug("Failed to create linkedin email info request: ", err)
+ log.Debug().Err(err).Msg("Failed to create linkedin email info request")
return nil, fmt.Errorf("error creating linkedin user info request: %s", err.Error())
}
req.Header = http.Header{
@@ -555,18 +584,18 @@ func processLinkedInUserInfo(ctx context.Context, code string) (*models.User, er
response, err = client.Do(req)
if err != nil {
- log.Debug("Failed to request linkedin email info: ", err)
+ log.Debug().Err(err).Msg("Failed to request linkedin email info")
return nil, err
}
defer response.Body.Close()
body, err = io.ReadAll(response.Body)
if err != nil {
- log.Debug("Failed to read linkedin email info response body: ", err)
+ log.Debug().Err(err).Msg("Failed to read linkedin email info response body")
return nil, fmt.Errorf("failed to read linkedin email response body: %s", err.Error())
}
if response.StatusCode >= 400 {
- log.Debug("Failed to request linkedin user info: ", string(body))
+ log.Debug().Err(err).Str("body", string(body)).Msg("Failed to request linkedin user info")
return nil, fmt.Errorf("failed to request linkedin user info: %s", string(body))
}
emailRawData := make(map[string]interface{})
@@ -577,7 +606,7 @@ func processLinkedInUserInfo(ctx context.Context, code string) (*models.User, er
profilePicture := userRawData["profilePicture"].(map[string]interface{})["displayImage~"].(map[string]interface{})["elements"].([]interface{})[0].(map[string]interface{})["identifiers"].([]interface{})[0].(map[string]interface{})["identifier"].(string)
emailAddress := emailRawData["elements"].([]interface{})[0].(map[string]interface{})["handle~"].(map[string]interface{})["emailAddress"].(string)
- user := &models.User{
+ user := &schemas.User{
GivenName: &firstName,
FamilyName: &lastName,
Picture: &profilePicture,
@@ -587,18 +616,25 @@ func processLinkedInUserInfo(ctx context.Context, code string) (*models.User, er
return user, nil
}
-func processAppleUserInfo(ctx context.Context, code string, user_ *AppleUserInfo) (*models.User, error) {
- var user = &models.User{}
- oauth2Token, err := oauth.OAuthProviders.AppleConfig.Exchange(ctx, code)
+func (h *httpProvider) processAppleUserInfo(ctx *gin.Context, code string, user_ *AppleUserInfo) (*schemas.User, error) {
+ log := h.Log.With().Str("func", "processAppleUserInfo").Logger()
+ cfg, err := h.OAuthProvider.GetOAuthConfig(ctx, constants.AuthRecipeMethodApple)
if err != nil {
- log.Debug("Failed to exchange code for token: ", err)
+ log.Debug().Err(err).Msg("Error getting oauth config")
+ return nil, fmt.Errorf("error getting oauth config: %s", err.Error())
+ }
+
+ var user = &schemas.User{}
+ oauth2Token, err := cfg.Exchange(ctx, code)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to exchange code for token")
return user, fmt.Errorf("invalid apple exchange code: %s", err.Error())
}
// Extract the ID Token from OAuth2 token.
rawIDToken, ok := oauth2Token.Extra("id_token").(string)
if !ok {
- log.Debug("Failed to extract ID Token from OAuth2 token")
+ log.Debug().Err(err).Msg("Failed to extract ID Token from OAuth2 token")
return user, fmt.Errorf("unable to extract id_token")
}
@@ -606,18 +642,18 @@ func processAppleUserInfo(ctx context.Context, code string, user_ *AppleUserInfo
claimsData := tokenSplit[1]
decodedClaimsData, err := base64.RawURLEncoding.DecodeString(claimsData)
if err != nil {
- log.Debugf("Failed to decrypt claims %s: %s", claimsData, err.Error())
+ log.Debug().Err(err).Msg("Failed to decode claims data")
return user, fmt.Errorf("failed to decrypt claims data: %s", err.Error())
}
claims := make(map[string]interface{})
err = json.Unmarshal(decodedClaimsData, &claims)
if err != nil {
- log.Debug("Failed to unmarshal claims data: ", err)
+ log.Debug().Err(err).Msg("Failed to unmarshal claims data")
return user, fmt.Errorf("failed to unmarshal claims data: %s", err.Error())
}
if val, ok := claims["email"]; !ok || val == nil {
- log.Debug("Failed to extract email from claims.")
+ log.Debug().Err(err).Msg("Failed to extract email from claims.")
return user, fmt.Errorf("unable to extract email, please check the scopes enabled for your app. It needs `email`, `name` scopes")
} else {
email := val.(string)
@@ -642,17 +678,23 @@ func processAppleUserInfo(ctx context.Context, code string, user_ *AppleUserInfo
return user, err
}
-func processDiscordUserInfo(ctx context.Context, code string) (*models.User, error) {
- oauth2Token, err := oauth.OAuthProviders.DiscordConfig.Exchange(ctx, code)
+func (h *httpProvider) processDiscordUserInfo(ctx *gin.Context, code string) (*schemas.User, error) {
+ log := h.Log.With().Str("func", "processDiscordUserInfo").Logger()
+ cfg, err := h.OAuthProvider.GetOAuthConfig(ctx, constants.AuthRecipeMethodDiscord)
if err != nil {
- log.Debug("Failed to exchange code for token: ", err)
+ log.Debug().Err(err).Msg("Error getting oauth config")
+ return nil, fmt.Errorf("error getting oauth config: %s", err.Error())
+ }
+ oauth2Token, err := cfg.Exchange(ctx, code)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to exchange code for token")
return nil, fmt.Errorf("invalid discord exchange code: %s", err.Error())
}
client := http.Client{}
req, err := http.NewRequest("GET", constants.DiscordUserInfoURL, nil)
if err != nil {
- log.Debug("Failed to create Discord user info request: ", err)
+ log.Debug().Err(err).Msg("Failed to create Discord user info request")
return nil, fmt.Errorf("error creating Discord user info request: %s", err.Error())
}
req.Header = http.Header{
@@ -661,45 +703,45 @@ func processDiscordUserInfo(ctx context.Context, code string) (*models.User, err
response, err := client.Do(req)
if err != nil {
- log.Debug("Failed to request Discord user info: ", err)
+ log.Debug().Err(err).Msg("Failed to request Discord user info")
return nil, err
}
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil {
- log.Debug("Failed to read Discord user info response body: ", err)
+ log.Debug().Err(err).Msg("Failed to read Discord user info response body")
return nil, fmt.Errorf("failed to read Discord response body: %s", err.Error())
}
if response.StatusCode >= 400 {
- log.Debug("Failed to request Discord user info: ", string(body))
+ log.Debug().Err(err).Msg("Failed to request Discord user info")
return nil, fmt.Errorf("failed to request Discord user info: %s", string(body))
}
// Unmarshal the response body into a map
responseRawData := make(map[string]interface{})
if err := json.Unmarshal(body, &responseRawData); err != nil {
- log.Debug("Failed to unmarshal Discord response: ", err)
+ log.Debug().Err(err).Msg("Failed to unmarshal Discord response")
return nil, fmt.Errorf("failed to unmarshal Discord response: %s", err.Error())
}
// Safely extract the user data
userRawData, ok := responseRawData["user"].(map[string]interface{})
if !ok {
- log.Debug("User data is not in expected format or missing in response")
+ log.Debug().Err(err).Msg("User data is not in expected format or missing in response")
return nil, fmt.Errorf("user data is not in expected format or missing in response")
}
// Extract the username
firstName, ok := userRawData["username"].(string)
if !ok {
- log.Debug("Username is not in expected format or missing in user data")
+ log.Debug().Err(err).Msg("Username is not in expected format or missing in user data")
return nil, fmt.Errorf("username is not in expected format or missing in user data")
}
profilePicture := fmt.Sprintf("https://cdn.discordapp.com/avatars/%s/%s.png", userRawData["id"].(string), userRawData["avatar"].(string))
- user := &models.User{
+ user := &schemas.User{
GivenName: &firstName,
Picture: &profilePicture,
}
@@ -707,17 +749,24 @@ func processDiscordUserInfo(ctx context.Context, code string) (*models.User, err
return user, nil
}
-func processTwitterUserInfo(ctx context.Context, code, verifier string) (*models.User, error) {
- oauth2Token, err := oauth.OAuthProviders.TwitterConfig.Exchange(ctx, code, oauth2.SetAuthURLParam("code_verifier", verifier))
+func (h *httpProvider) processTwitterUserInfo(ctx *gin.Context, code, verifier string) (*schemas.User, error) {
+ log := h.Log.With().Str("func", "processTwitterUserInfo").Logger()
+ cfg, err := h.OAuthProvider.GetOAuthConfig(ctx, constants.AuthRecipeMethodTwitter)
+ if err != nil {
+ log.Debug().Err(err).Msg("Error getting oauth config")
+ return nil, fmt.Errorf("error getting oauth config: %s", err.Error())
+ }
+
+ oauth2Token, err := cfg.Exchange(ctx, code, oauth2.SetAuthURLParam("code_verifier", verifier))
if err != nil {
- log.Debug("Failed to exchange code for token: ", err)
+ log.Debug().Err(err).Msg("Failed to exchange code for token")
return nil, fmt.Errorf("invalid twitter exchange code: %s", err.Error())
}
client := http.Client{}
req, err := http.NewRequest("GET", constants.TwitterUserInfoURL, nil)
if err != nil {
- log.Debug("Failed to create Twitter user info request: ", err)
+ log.Debug().Err(err).Msg("Failed to create Twitter user info request")
return nil, fmt.Errorf("error creating Twitter user info request: %s", err.Error())
}
req.Header = http.Header{
@@ -726,19 +775,19 @@ func processTwitterUserInfo(ctx context.Context, code, verifier string) (*models
response, err := client.Do(req)
if err != nil {
- log.Debug("Failed to request Twitter user info: ", err)
+ log.Debug().Err(err).Msg("Failed to request Twitter user info")
return nil, err
}
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil {
- log.Debug("Failed to read Twitter user info response body: ", err)
+ log.Debug().Err(err).Msg("Failed to read Twitter user info response body")
return nil, fmt.Errorf("failed to read Twitter response body: %s", err.Error())
}
if response.StatusCode >= 400 {
- log.Debug("Failed to request Twitter user info: ", string(body))
+ log.Debug().Err(err).Str("body", string(body)).Msg("Failed to request Twitter user info")
return nil, fmt.Errorf("failed to request Twitter user info: %s", string(body))
}
@@ -763,7 +812,7 @@ func processTwitterUserInfo(ctx context.Context, code, verifier string) (*models
nickname := userRawData["username"].(string)
profilePicture := userRawData["profile_image_url"].(string)
- user := &models.User{
+ user := &schemas.User{
GivenName: &firstName,
FamilyName: &lastName,
Picture: &profilePicture,
@@ -774,32 +823,39 @@ func processTwitterUserInfo(ctx context.Context, code, verifier string) (*models
}
// process microsoft user information
-func processMicrosoftUserInfo(ctx context.Context, code string) (*models.User, error) {
- oauth2Token, err := oauth.OAuthProviders.MicrosoftConfig.Exchange(ctx, code)
+func (h *httpProvider) processMicrosoftUserInfo(ctx *gin.Context, code string) (*schemas.User, error) {
+ log := h.Log.With().Str("func", "processMicrosoftUserInfo").Logger()
+ cfg, err := h.OAuthProvider.GetOAuthConfig(ctx, constants.AuthRecipeMethodMicrosoft)
+ if err != nil {
+ log.Debug().Err(err).Msg("Error getting oauth config")
+ return nil, fmt.Errorf("error getting oauth config: %s", err.Error())
+ }
+ oauth2Token, err := cfg.Exchange(ctx, code)
if err != nil {
- log.Debug("Failed to exchange code for token: ", err)
+ log.Debug().Err(err).Msg("Failed to exchange code for token")
return nil, fmt.Errorf("invalid microsoft exchange code: %s", err.Error())
}
+ oidcProvider, err := oidc.NewProvider(ctx, fmt.Sprintf("https://login.microsoftonline.com/%s/v2.0", h.MicrosoftTenantID))
// we need to skip issuer check because for common tenant it will return internal issuer which does not match
- verifier := oauth.OIDCProviders.MicrosoftOIDC.Verifier(&oidc.Config{
- ClientID: oauth.OAuthProviders.MicrosoftConfig.ClientID,
+ verifier := oidcProvider.Verifier(&oidc.Config{
+ ClientID: h.MicrosoftClientID,
SkipIssuerCheck: true,
})
// Extract the ID Token from OAuth2 token.
rawIDToken, ok := oauth2Token.Extra("id_token").(string)
if !ok {
- log.Debug("Failed to extract ID Token from OAuth2 token")
+ log.Debug().Err(err).Msg("Failed to extract ID Token from OAuth2 token")
return nil, fmt.Errorf("unable to extract id_token")
}
// Parse and verify ID Token payload.
idToken, err := verifier.Verify(ctx, rawIDToken)
if err != nil {
- log.Debug("Failed to verify ID Token: ", err)
+ log.Debug().Err(err).Msg("Failed to verify ID Token")
return nil, fmt.Errorf("unable to verify id_token: %s", err.Error())
}
- user := &models.User{}
+ user := &schemas.User{}
if err := idToken.Claims(&user); err != nil {
- log.Debug("Failed to parse ID Token claims: ", err)
+ log.Debug().Err(err).Msg("Failed to parse ID Token claims")
return nil, fmt.Errorf("unable to extract claims")
}
@@ -807,34 +863,46 @@ func processMicrosoftUserInfo(ctx context.Context, code string) (*models.User, e
}
// process twitch user information
-func processTwitchUserInfo(ctx context.Context, code string) (*models.User, error) {
- oauth2Token, err := oauth.OAuthProviders.TwitchConfig.Exchange(ctx, code)
+func (h *httpProvider) processTwitchUserInfo(ctx *gin.Context, code string) (*schemas.User, error) {
+ log := h.Log.With().Str("func", "processTwitchUserInfo").Logger()
+ cfg, err := h.OAuthProvider.GetOAuthConfig(ctx, constants.AuthRecipeMethodTwitch)
if err != nil {
- log.Debug("Failed to exchange code for token: ", err)
+ log.Debug().Err(err).Msg("Error getting oauth config")
+ return nil, fmt.Errorf("error getting oauth config: %s", err.Error())
+ }
+
+ oauth2Token, err := cfg.Exchange(ctx, code)
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to exchange code for token")
return nil, fmt.Errorf("invalid twitch exchange code: %s", err.Error())
}
// Extract the ID Token from OAuth2 token.
rawIDToken, ok := oauth2Token.Extra("id_token").(string)
if !ok {
- log.Debug("Failed to extract ID Token from OAuth2 token")
+ log.Debug().Err(err).Msg("Failed to extract ID Token from OAuth2 token")
return nil, fmt.Errorf("unable to extract id_token")
}
- verifier := oauth.OIDCProviders.TwitchOIDC.Verifier(&oidc.Config{
- ClientID: oauth.OAuthProviders.TwitchConfig.ClientID,
+ oidcProvider, err := oidc.NewProvider(ctx, "https://id.twitch.tv/oauth2")
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to create OIDC provider")
+ return nil, fmt.Errorf("failed to create oidc provider: %s", err.Error())
+ }
+ verifier := oidcProvider.Verifier(&oidc.Config{
+ ClientID: h.TwitchClientID,
SkipIssuerCheck: true,
})
// Parse and verify ID Token payload.
idToken, err := verifier.Verify(ctx, rawIDToken)
if err != nil {
- log.Debug("Failed to verify ID Token: ", err)
+ log.Debug().Err(err).Msg("Failed to verify ID Token")
return nil, fmt.Errorf("unable to verify id_token: %s", err.Error())
}
- user := &models.User{}
+ user := &schemas.User{}
if err := idToken.Claims(&user); err != nil {
- log.Debug("Failed to parse ID Token claims: ", err)
+ log.Debug().Err(err).Msg("Failed to parse ID Token claims")
return nil, fmt.Errorf("unable to extract claims")
}
@@ -842,17 +910,23 @@ func processTwitchUserInfo(ctx context.Context, code string) (*models.User, erro
}
// process roblox user information
-func processRobloxUserInfo(ctx context.Context, code, verifier string) (*models.User, error) {
- oauth2Token, err := oauth.OAuthProviders.RobloxConfig.Exchange(ctx, code, oauth2.SetAuthURLParam("code_verifier", verifier))
+func (h *httpProvider) processRobloxUserInfo(ctx *gin.Context, code, verifier string) (*schemas.User, error) {
+ log := h.Log.With().Str("func", "processRobloxUserInfo").Logger()
+ cfg, err := h.OAuthProvider.GetOAuthConfig(ctx, constants.AuthRecipeMethodRoblox)
+ if err != nil {
+ log.Debug().Err(err).Msg("Error getting oauth config")
+ return nil, fmt.Errorf("error getting oauth config: %s", err.Error())
+ }
+ oauth2Token, err := cfg.Exchange(ctx, code, oauth2.SetAuthURLParam("code_verifier", verifier))
if err != nil {
- log.Debug("Failed to exchange code for token: ", err)
+ log.Debug().Err(err).Msg("Failed to exchange code for token")
return nil, fmt.Errorf("invalid roblox exchange code: %s", err.Error())
}
client := http.Client{}
req, err := http.NewRequest("GET", constants.RobloxUserInfoURL, nil)
if err != nil {
- log.Debug("Failed to create roblox user info request: ", err)
+ log.Debug().Err(err).Msg("Failed to create roblox user info request")
return nil, fmt.Errorf("error creating roblox user info request: %s", err.Error())
}
req.Header = http.Header{
@@ -861,19 +935,19 @@ func processRobloxUserInfo(ctx context.Context, code, verifier string) (*models.
response, err := client.Do(req)
if err != nil {
- log.Debug("Failed to request roblox user info: ", err)
+ log.Debug().Err(err).Msg("Failed to request roblox user info")
return nil, err
}
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil {
- log.Debug("Failed to read roblox user info response body: ", err)
+ log.Debug().Err(err).Msg("Failed to read roblox user info response body")
return nil, fmt.Errorf("failed to read roblox response body: %s", err.Error())
}
if response.StatusCode >= 400 {
- log.Debug("Failed to request roblox user info: ", string(body))
+ log.Debug().Err(err).Str("body", string(body)).Msg("Failed to request roblox user info")
return nil, fmt.Errorf("failed to request roblox user info: %s", string(body))
}
@@ -895,7 +969,7 @@ func processRobloxUserInfo(ctx context.Context, code, verifier string) (*models.
} else {
email = userRawData["sub"].(string)
}
- user := &models.User{
+ user := &schemas.User{
GivenName: &firstName,
FamilyName: &lastName,
Picture: &profilePicture,
diff --git a/internal/http_handlers/oauth_login.go b/internal/http_handlers/oauth_login.go
new file mode 100644
index 000000000..1c872f51d
--- /dev/null
+++ b/internal/http_handlers/oauth_login.go
@@ -0,0 +1,88 @@
+package http_handlers
+
+import (
+ "net/http"
+ "strings"
+
+ "github.com/gin-gonic/gin"
+ "github.com/google/uuid"
+
+ "github.com/authorizerdev/authorizer/internal/validators"
+)
+
+// OAuthLoginHandler set host in the oauth state that is useful for redirecting to oauth_callback
+func (h *httpProvider) OAuthLoginHandler() gin.HandlerFunc {
+ log := h.Log.With().Str("func", "OAuthLoginHandler").Logger()
+ return func(c *gin.Context) {
+ // deprecating redirectURL instead use redirect_uri
+ redirectURI := strings.TrimSpace(c.Query("redirectURL"))
+ if redirectURI == "" {
+ redirectURI = strings.TrimSpace(c.Query("redirect_uri"))
+ }
+ roles := strings.TrimSpace(c.Query("roles"))
+ state := strings.TrimSpace(c.Query("state"))
+ scopeString := strings.TrimSpace(c.Query("scope"))
+
+ if redirectURI == "" {
+ log.Debug().Msg("redirect uri is missing")
+ c.JSON(400, gin.H{
+ "error": "invalid redirect uri",
+ })
+ return
+ }
+
+ if state == "" {
+ log.Debug().Msg("state is missing, creating new state")
+ state = uuid.New().String()
+ }
+
+ var scope []string
+ if scopeString == "" {
+ scope = []string{"openid", "profile", "email"}
+ } else {
+ scope = strings.Split(scopeString, " ")
+ }
+
+ if roles != "" {
+ // validate role
+ rolesSplit := strings.Split(roles, ",")
+
+ // use protected roles verification for admin login only.
+ // though if not associated with user, it will be rejected from oauth_callback
+ allowedRoles := h.Config.Roles
+ protectedRoles := h.Config.ProtectedRoles
+ if !validators.IsValidRoles(rolesSplit, append([]string{}, append(allowedRoles, protectedRoles...)...)) {
+ log.Debug().Msg("invalid role")
+ c.JSON(400, gin.H{
+ "error": "invalid role",
+ })
+ return
+ }
+ } else {
+ roles = strings.Join(h.Config.DefaultRoles, ",")
+ }
+
+ oauthStateString := state + "___" + redirectURI + "___" + roles + "___" + strings.Join(scope, " ")
+
+ provider := c.Param("oauth_provider")
+ log := log.With().Str("provider", provider).Logger()
+ cfg, err := h.OAuthProvider.GetOAuthConfig(c, provider)
+ if err != nil {
+ log.Debug().Err(err).Msg("Error getting oauth config")
+ c.JSON(422, gin.H{
+ "error": err.Error(),
+ })
+ return
+ }
+ if err := h.MemoryStoreProvider.SetState(oauthStateString, provider); err != nil {
+ log.Debug().Err(err).Msg("Error setting state")
+ c.JSON(500, gin.H{
+ "error": "internal server error",
+ })
+ return
+ }
+ url := cfg.AuthCodeURL(oauthStateString)
+ log.Debug().Str("url", url).Msg("redirecting to oauth provider")
+ c.Redirect(http.StatusTemporaryRedirect, url)
+ }
+}
diff --git a/server/handlers/openid_config.go b/internal/http_handlers/openid_config.go
similarity index 80%
rename from server/handlers/openid_config.go
rename to internal/http_handlers/openid_config.go
index 3414e09e5..0c570953e 100644
--- a/server/handlers/openid_config.go
+++ b/internal/http_handlers/openid_config.go
@@ -1,18 +1,16 @@
-package handlers
+package http_handlers
import (
"github.com/gin-gonic/gin"
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/parsers"
+ "github.com/authorizerdev/authorizer/internal/parsers"
)
// OpenIDConfigurationHandler handler for open-id configurations
-func OpenIDConfigurationHandler() gin.HandlerFunc {
+func (h *httpProvider) OpenIDConfigurationHandler() gin.HandlerFunc {
return func(c *gin.Context) {
issuer := parsers.GetHost(c)
- jwtType, _ := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyJwtType)
+ jwtType := h.Config.JWTType
c.JSON(200, gin.H{
"issuer": issuer,
diff --git a/internal/http_handlers/playground.go b/internal/http_handlers/playground.go
new file mode 100644
index 000000000..c476ddd35
--- /dev/null
+++ b/internal/http_handlers/playground.go
@@ -0,0 +1,36 @@
+package http_handlers
+
+import (
+ "net/http"
+
+ "github.com/99designs/gqlgen/graphql/playground"
+ "github.com/gin-gonic/gin"
+ "github.com/rs/zerolog/log"
+)
+
+// PlaygroundHandler is the handler for the /playground route
+func (h *httpProvider) PlaygroundHandler() gin.HandlerFunc {
+ // log := h.Log.With().Str("func", "PlaygroundHandler").Logger()
+ return func(c *gin.Context) {
+ var handlerFunc http.HandlerFunc
+
+ enablePlayground := h.Config.EnablePlayground
+
+ // if env set to true, then check if logged in as super admin, if logged in then return graphql else 401 error
+ // if env set to false, then disabled the playground with 404 error
+ if enablePlayground {
+ if h.TokenProvider.IsSuperAdmin(c) {
+ handlerFunc = playground.Handler("GraphQL", "/graphql")
+ } else {
+ log.Debug().Msg("not logged in as super admin")
+ c.JSON(http.StatusUnauthorized, gin.H{"error": "not logged in as super admin"})
+ return
+ }
+ } else {
+ log.Debug().Msg("playground is disabled")
+ c.JSON(http.StatusNotFound, gin.H{"error": "playground is disabled"})
+ return
+ }
+ handlerFunc.ServeHTTP(c.Writer, c.Request)
+ }
+}
diff --git a/internal/http_handlers/provider.go b/internal/http_handlers/provider.go
new file mode 100644
index 000000000..c11341cca
--- /dev/null
+++ b/internal/http_handlers/provider.go
@@ -0,0 +1,103 @@
+package http_handlers
+
+import (
+ "github.com/gin-gonic/gin"
+ "github.com/rs/zerolog"
+
+ "github.com/authorizerdev/authorizer/internal/authenticators"
+ "github.com/authorizerdev/authorizer/internal/config"
+ "github.com/authorizerdev/authorizer/internal/email"
+ "github.com/authorizerdev/authorizer/internal/events"
+ "github.com/authorizerdev/authorizer/internal/memory_store"
+ "github.com/authorizerdev/authorizer/internal/oauth"
+ "github.com/authorizerdev/authorizer/internal/sms"
+ "github.com/authorizerdev/authorizer/internal/storage"
+ "github.com/authorizerdev/authorizer/internal/token"
+)
+
+// Dependencies for a graphql provider
+type Dependencies struct {
+ Log *zerolog.Logger
+
+ // Providers for various services
+ // AuthenticatorProvider is used to register authenticators like totp (Google Authenticator)
+ AuthenticatorProvider authenticators.Provider
+ // EmailProvider is used to send emails
+ EmailProvider email.Provider
+ // EventsProvider is used to register events
+ EventsProvider events.Provider
+ // MemoryStoreProvider is used to store data in memory
+ MemoryStoreProvider memory_store.Provider
+ // SMSProvider is used to send SMS
+ SMSProvider sms.Provider
+ // StorageProvider is used to register storage like database
+ StorageProvider storage.Provider
+ // TokenProvider is used to generate tokens
+ TokenProvider token.Provider
+ // OAuthProvider is used to register oauth providers
+ OAuthProvider oauth.Provider
+}
+
+// New constructs a new http provider with given arguments
+func New(cfg *config.Config, deps *Dependencies) (Provider, error) {
+ // TODO - Add any validation here for config and dependencies
+ g := &httpProvider{
+ Config: cfg,
+ Dependencies: *deps,
+ }
+ return g, nil
+}
+
+// httpProvider is the struct that provides resolver functions for http routes.
+type httpProvider struct {
+ *config.Config
+ Dependencies
+}
+
+// Ensure interface is implemented
+var _ Provider = &httpProvider{}
+
+// Provider is the interface that provides the methods to interact with the http handlers.
+type Provider interface {
+ // AppHandler is the main handler that handels all the app requests
+ AppHandler() gin.HandlerFunc
+ // AuthorizeHandler is the main handler that handels all the authorize requests
+ AuthorizeHandler() gin.HandlerFunc
+ // DashboardHandler is the main handler that handels all the dashboard requests
+ DashboardHandler() gin.HandlerFunc
+ // GraphqlHandler is the main handler that handels all the graphql requests
+ GraphqlHandler() gin.HandlerFunc
+ // HealthHandler is the main handler that handels all the health requests
+ HealthHandler() gin.HandlerFunc
+ // JWKsHandler is the main handler that handels all the jwks requests
+ JWKsHandler() gin.HandlerFunc
+ // LogoutHandler is the main handler that handels all the logout requests
+ LogoutHandler() gin.HandlerFunc
+ // OAuthCallbackHandler is the main handler that handels all the oauth callback requests
+ OAuthCallbackHandler() gin.HandlerFunc
+ // OAuthLoginHandler is the main handler that handels all the oauth login requests
+ OAuthLoginHandler() gin.HandlerFunc
+ // OpenIDConfigurationHandler is the main handler that handels all the openid configuration requests
+ OpenIDConfigurationHandler() gin.HandlerFunc
+ // PlaygroundHandler is the main handler that handels all the playground requests
+ PlaygroundHandler() gin.HandlerFunc
+ // RevokeRefreshTokenHandler is the main handler that handels all the revoke refresh token requests
+ RevokeRefreshTokenHandler() gin.HandlerFunc
+ // RootHandler is the main handler that handels all the root requests
+ RootHandler() gin.HandlerFunc
+ // TokenHandler is the main handler that handels all the token requests
+ TokenHandler() gin.HandlerFunc
+ // UserInfoHandler is the main handler that handels all the user info requests
+ UserInfoHandler() gin.HandlerFunc
+ // VerifyEmailHandler is the main handler that handels all the verify email requests
+ VerifyEmailHandler() gin.HandlerFunc
+
+ // ClientCheckMiddleware is the middleware that checks if the client is valid
+ ClientCheckMiddleware() gin.HandlerFunc
+ // ContextMiddleware is the middleware that adds the context to the request
+ ContextMiddleware() gin.HandlerFunc
+ // CORSMiddleware is the middleware that adds the cors headers to the response
+ CORSMiddleware() gin.HandlerFunc
+ // LoggerMiddleware is the middleware that logs the request
+ LoggerMiddleware() gin.HandlerFunc
+}
diff --git a/internal/http_handlers/revoke_refresh_token.go b/internal/http_handlers/revoke_refresh_token.go
new file mode 100644
index 000000000..cf08f2d9a
--- /dev/null
+++ b/internal/http_handlers/revoke_refresh_token.go
@@ -0,0 +1,108 @@
+package http_handlers
+
+import (
+ "net/http"
+ "strings"
+
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/gin-gonic/gin"
+)
+
+// RevokeRefreshTokenHandler handler to revoke refresh token
+func (h *httpProvider) RevokeRefreshTokenHandler() gin.HandlerFunc {
+ log := h.Log.With().Str("func", "RevokeRefreshTokenHandler").Logger()
+ return func(gc *gin.Context) {
+ var reqBody map[string]string
+ if err := gc.BindJSON(&reqBody); err != nil {
+ log.Debug().Err(err).Msg("failed to bind json")
+ gc.JSON(http.StatusBadRequest, gin.H{
+ "error": "error_binding_json",
+ "error_description": err.Error(),
+ })
+ return
+ }
+ // get client ID
+ clientID := strings.TrimSpace(reqBody["client_id"]) // kept for backward compatibility // else we expect to be present as header
+ if clientID == "" {
+ clientID = gc.Request.Header.Get("x-authorizer-client-id")
+ }
+ // get fingerprint hash
+ refreshToken := strings.TrimSpace(reqBody["refresh_token"])
+
+ if clientID == "" {
+ log.Debug().Msg("Client ID is mising")
+ gc.JSON(http.StatusBadRequest, gin.H{
+ "error": "client_id_required",
+ "error_description": "The client id is missing",
+ })
+ return
+ }
+
+ if h.Config.ClientID != clientID {
+ log.Debug().Str("client_id", clientID).Msg("Client ID is invalid")
+ gc.JSON(http.StatusBadRequest, gin.H{
+ "error": "invalid_client_id",
+ "error_description": "The client id is invalid",
+ })
+ return
+ }
+
+ claims, err := h.TokenProvider.ParseJWTToken(refreshToken)
+ if err != nil {
+ log.Debug().Err(err).Msg("failed to parse jwt")
+ gc.JSON(http.StatusBadRequest, gin.H{
+ "error": err.Error(),
+ "error_description": "Failed to parse jwt",
+ })
+ return
+ }
+
+ userID := claims["sub"].(string)
+ loginMethod := claims["login_method"]
+ sessionToken := userID
+ if loginMethod != nil && loginMethod != "" {
+ sessionToken = loginMethod.(string) + ":" + userID
+ }
+
+ existingToken, err := h.MemoryStoreProvider.GetUserSession(sessionToken, constants.TokenTypeRefreshToken+"_"+claims["nonce"].(string))
+ if err != nil {
+ log.Debug().Err(err).Msg("Failed to get refresh token")
+ gc.JSON(http.StatusInternalServerError, gin.H{
+ "error": "failed_to_get_refresh_token",
+ "error_description": "Failed to get user refresh token: " + err.Error(),
+ })
+ return
+ }
+
+ if existingToken == "" {
+ log.Debug().Msg("Token not found")
+ gc.JSON(http.StatusBadRequest, gin.H{
+ "error": "token_not_found",
+ "error_description": "Token not found",
+ })
+ return
+ }
+
+ if existingToken != refreshToken {
+ log.Debug().Msg("Token does not match")
+ gc.JSON(http.StatusBadRequest, gin.H{
+ "error": "token_does_not_match",
+ "error_description": "Token does not match",
+ })
+ return
+ }
+
+ if err := h.MemoryStoreProvider.DeleteUserSession(sessionToken, claims["nonce"].(string)); err != nil {
+ log.Debug().Err(err).Msg("failed to delete user session")
+ gc.JSON(http.StatusInternalServerError, gin.H{
+ "error": "failed_to_delete_user_session",
+ "error_description": "Failed to delete user session: " + err.Error(),
+ })
+ return
+ }
+
+ gc.JSON(http.StatusOK, gin.H{
+ "message": "Token revoked successfully",
+ })
+ }
+}
diff --git a/server/handlers/root.go b/internal/http_handlers/root.go
similarity index 71%
rename from server/handlers/root.go
rename to internal/http_handlers/root.go
index 70cfc3065..9c39463f0 100644
--- a/server/handlers/root.go
+++ b/internal/http_handlers/root.go
@@ -1,4 +1,4 @@
-package handlers
+package http_handlers
import (
"net/http"
@@ -7,7 +7,7 @@ import (
)
// RootHandler is the handler for / root route.
-func RootHandler() gin.HandlerFunc {
+func (h *httpProvider) RootHandler() gin.HandlerFunc {
return func(c *gin.Context) {
c.Redirect(http.StatusTemporaryRedirect, "/dashboard")
}
diff --git a/server/handlers/token.go b/internal/http_handlers/token.go
similarity index 70%
rename from server/handlers/token.go
rename to internal/http_handlers/token.go
index 1a6013042..b41fde8c5 100644
--- a/server/handlers/token.go
+++ b/internal/http_handlers/token.go
@@ -1,4 +1,4 @@
-package handlers
+package http_handlers
import (
"crypto/sha256"
@@ -9,13 +9,11 @@ import (
"github.com/gin-gonic/gin"
"github.com/google/uuid"
- log "github.com/sirupsen/logrus"
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/cookie"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/token"
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/cookie"
+ "github.com/authorizerdev/authorizer/internal/parsers"
+ "github.com/authorizerdev/authorizer/internal/token"
)
type RequestBody struct {
@@ -30,11 +28,12 @@ type RequestBody struct {
// TokenHandler to handle /oauth/token requests
// grant type required
-func TokenHandler() gin.HandlerFunc {
+func (h *httpProvider) TokenHandler() gin.HandlerFunc {
+ log := h.Log.With().Str("func", "TokenHandler").Logger()
return func(gc *gin.Context) {
var reqBody RequestBody
if err := gc.Bind(&reqBody); err != nil {
- log.Debug("Error binding JSON: ", err)
+ log.Debug().Err(err).Msg("failed to bind json")
gc.JSON(http.StatusBadRequest, gin.H{
"error": "error_binding_json",
"error_description": err.Error(),
@@ -57,7 +56,7 @@ func TokenHandler() gin.HandlerFunc {
isAuthorizationCodeGrant := grantType == "authorization_code"
if !isRefreshTokenGrant && !isAuthorizationCodeGrant {
- log.Debug("Invalid grant type: ", grantType)
+ log.Debug().Str("grant_type", grantType).Msg("Invalid grant type")
gc.JSON(http.StatusBadRequest, gin.H{
"error": "invalid_grant_type",
"error_description": "grant_type is invalid",
@@ -71,16 +70,16 @@ func TokenHandler() gin.HandlerFunc {
}
if clientID == "" {
- log.Debug("Client ID is empty")
+ log.Debug().Msg("Client ID is missing")
gc.JSON(http.StatusBadRequest, gin.H{
"error": "client_id_required",
- "error_description": "The client id is required",
+ "error_description": "The client id is missing",
})
return
}
- if client, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyClientID); clientID != client || err != nil {
- log.Debug("Client ID is invalid: ", clientID)
+ if h.Config.ClientID != clientID {
+ log.Debug().Str("client_id", clientID).Msg("Client ID is invalid")
gc.JSON(http.StatusBadRequest, gin.H{
"error": "invalid_client_id",
"error_description": "The client id is invalid",
@@ -95,7 +94,7 @@ func TokenHandler() gin.HandlerFunc {
if isAuthorizationCodeGrant {
if code == "" {
- log.Debug("Code is empty")
+ log.Debug().Msg("Code is missing")
gc.JSON(http.StatusBadRequest, gin.H{
"error": "invalid_code",
"error_description": "The code is required",
@@ -111,9 +110,9 @@ func TokenHandler() gin.HandlerFunc {
return
}
// Get state
- sessionData, err := memorystore.Provider.GetState(code)
+ sessionData, err := h.MemoryStoreProvider.GetState(code)
if sessionData == "" || err != nil {
- log.Debug("Session data is empty")
+ log.Debug().Err(err).Msg("Error getting session data")
gc.JSON(http.StatusBadRequest, gin.H{
"error": "invalid_code",
"error_description": "The code is invalid",
@@ -125,7 +124,7 @@ func TokenHandler() gin.HandlerFunc {
// [1] -> session cookie
sessionDataSplit := strings.Split(sessionData, "@@")
- go memorystore.Provider.RemoveState(code)
+ go h.MemoryStoreProvider.RemoveState(code)
if codeVerifier != "" {
hash := sha256.New()
@@ -142,8 +141,8 @@ func TokenHandler() gin.HandlerFunc {
}
} else {
- if clientHash, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyClientSecret); clientSecret != clientHash || err != nil {
- log.Debug("Client Secret is invalid: ", clientID)
+ if clientSecret != h.Config.ClientSecret {
+ log.Debug().Err(err).Msg("Error getting client secret")
gc.JSON(http.StatusBadRequest, gin.H{
"error": "invalid_client_secret",
"error_description": "The client secret is invalid",
@@ -153,9 +152,9 @@ func TokenHandler() gin.HandlerFunc {
}
// validate session
- claims, err := token.ValidateBrowserSession(gc, sessionDataSplit[1])
+ claims, err := h.TokenProvider.ValidateBrowserSession(gc, sessionDataSplit[1])
if err != nil {
- log.Debug("Error validating session: ", err)
+ log.Debug().Err(err).Msg("Error validating session")
gc.JSON(http.StatusUnauthorized, gin.H{
"error": "unauthorized",
"error_description": "Invalid session data",
@@ -174,12 +173,12 @@ func TokenHandler() gin.HandlerFunc {
sessionKey = loginMethod + ":" + userID
}
- go memorystore.Provider.DeleteUserSession(sessionKey, claims.Nonce)
+ go h.MemoryStoreProvider.DeleteUserSession(sessionKey, claims.Nonce)
} else {
// validate refresh token
if refreshToken == "" {
- log.Debug("Refresh token is empty")
+ log.Debug().Msg("Refresh token is missing")
gc.JSON(http.StatusBadRequest, gin.H{
"error": "invalid_refresh_token",
"error_description": "The refresh token is invalid",
@@ -187,9 +186,9 @@ func TokenHandler() gin.HandlerFunc {
return
}
- claims, err := token.ValidateRefreshToken(gc, refreshToken)
+ claims, err := h.TokenProvider.ValidateRefreshToken(gc, refreshToken)
if err != nil {
- log.Debug("Error validating refresh token: ", err)
+ log.Debug().Err(err).Msg("Error validating refresh token")
gc.JSON(http.StatusUnauthorized, gin.H{
"error": "unauthorized",
"error_description": err.Error(),
@@ -214,11 +213,11 @@ func TokenHandler() gin.HandlerFunc {
}
// remove older refresh token and rotate it for security
- go memorystore.Provider.DeleteUserSession(sessionKey, claims["nonce"].(string))
+ go h.MemoryStoreProvider.DeleteUserSession(sessionKey, claims["nonce"].(string))
}
if sessionKey == "" {
- log.Debug("Error getting sessionKey: ", sessionKey, loginMethod)
+ log.Debug().Str("session_key", sessionKey).Str("login_method", loginMethod).Msg("Session key not found")
gc.JSON(http.StatusUnauthorized, gin.H{
"error": "unauthorized",
"error_description": "User not found",
@@ -226,20 +225,27 @@ func TokenHandler() gin.HandlerFunc {
return
}
- user, err := db.Provider.GetUserByID(gc, userID)
+ user, err := h.StorageProvider.GetUserByID(gc, userID)
if err != nil {
- log.Debug("Error getting user: ", err)
+ log.Debug().Err(err).Str("user_id", userID).Msg("Error getting user")
gc.JSON(http.StatusUnauthorized, gin.H{
"error": "unauthorized",
"error_description": "User not found",
})
return
}
-
+ hostname := parsers.GetHost(gc)
nonce := uuid.New().String() + "@@" + code
- authToken, err := token.CreateAuthToken(gc, user, roles, scope, loginMethod, nonce, code)
+ authToken, err := h.TokenProvider.CreateAuthToken(gc, &token.AuthTokenConfig{
+ User: user,
+ Roles: roles,
+ Scope: scope,
+ LoginMethod: loginMethod,
+ Nonce: nonce,
+ HostName: hostname,
+ })
if err != nil {
- log.Debug("Error creating auth token: ", err)
+ log.Debug().Err(err).Msg("Error creating auth token")
gc.JSON(http.StatusUnauthorized, gin.H{
"error": "unauthorized",
"error_description": "User not found",
@@ -247,9 +253,9 @@ func TokenHandler() gin.HandlerFunc {
return
}
- memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash, authToken.SessionTokenExpiresAt)
- memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token, authToken.AccessToken.ExpiresAt)
- cookie.SetSession(gc, authToken.FingerPrintHash)
+ h.MemoryStoreProvider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash, authToken.SessionTokenExpiresAt)
+ h.MemoryStoreProvider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token, authToken.AccessToken.ExpiresAt)
+ cookie.SetSession(gc, authToken.FingerPrintHash, h.Config.AppCookieSecure)
expiresIn := authToken.AccessToken.ExpiresAt - time.Now().Unix()
if expiresIn <= 0 {
@@ -265,7 +271,7 @@ func TokenHandler() gin.HandlerFunc {
}
if authToken.RefreshToken != nil {
res["refresh_token"] = authToken.RefreshToken.Token
- memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token, authToken.RefreshToken.ExpiresAt)
+ h.MemoryStoreProvider.SetUserSession(sessionKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token, authToken.RefreshToken.ExpiresAt)
}
gc.JSON(http.StatusOK, res)
}
diff --git a/server/handlers/userinfo.go b/internal/http_handlers/userinfo.go
similarity index 62%
rename from server/handlers/userinfo.go
rename to internal/http_handlers/userinfo.go
index 1512e41bb..6001d8b9f 100644
--- a/server/handlers/userinfo.go
+++ b/internal/http_handlers/userinfo.go
@@ -1,38 +1,35 @@
-package handlers
+package http_handlers
import (
"encoding/json"
"net/http"
"github.com/gin-gonic/gin"
- log "github.com/sirupsen/logrus"
-
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/token"
)
-func UserInfoHandler() gin.HandlerFunc {
+func (h *httpProvider) UserInfoHandler() gin.HandlerFunc {
+ log := h.Log.With().Str("func", "UserInfoHandler").Logger()
return func(gc *gin.Context) {
- accessToken, err := token.GetAccessToken(gc)
+ accessToken, err := h.TokenProvider.GetAccessToken(gc)
if err != nil {
- log.Debug("Error getting access token: ", err)
+ log.Debug().Msg("Error getting access token")
gc.JSON(http.StatusUnauthorized, gin.H{
"error": err.Error(),
})
return
}
- claims, err := token.ValidateAccessToken(gc, accessToken)
+ claims, err := h.TokenProvider.ValidateAccessToken(gc, accessToken)
if err != nil {
- log.Debug("Error validating access token: ", err)
+ log.Debug().Msg("Error validating access token")
gc.JSON(http.StatusUnauthorized, gin.H{
"error": err.Error(),
})
return
}
userID := claims["sub"].(string)
- user, err := db.Provider.GetUserByID(gc, userID)
+ user, err := h.StorageProvider.GetUserByID(gc, userID)
if err != nil {
- log.Debug("Error getting user: ", err)
+ log.Debug().Msg("Error getting user by ID")
gc.JSON(http.StatusUnauthorized, gin.H{
"error": err.Error(),
})
@@ -41,7 +38,7 @@ func UserInfoHandler() gin.HandlerFunc {
apiUser := user.AsAPIUser()
userBytes, err := json.Marshal(apiUser)
if err != nil {
- log.Debug("Error marshalling user: ", err)
+ log.Debug().Msg("Error marshalling user")
gc.JSON(http.StatusUnauthorized, gin.H{
"error": err.Error(),
})
@@ -50,7 +47,7 @@ func UserInfoHandler() gin.HandlerFunc {
res := map[string]interface{}{}
err = json.Unmarshal(userBytes, &res)
if err != nil {
- log.Debug("Error un-marshalling user: ", err)
+ log.Debug().Msg("Error unmarshalling user")
gc.JSON(http.StatusUnauthorized, gin.H{
"error": err.Error(),
})
diff --git a/server/handlers/verify_email.go b/internal/http_handlers/verify_email.go
similarity index 62%
rename from server/handlers/verify_email.go
rename to internal/http_handlers/verify_email.go
index 34f9d9fed..ffb909fcf 100644
--- a/server/handlers/verify_email.go
+++ b/internal/http_handlers/verify_email.go
@@ -1,4 +1,4 @@
-package handlers
+package http_handlers
import (
"net/http"
@@ -8,21 +8,20 @@ import (
"github.com/gin-gonic/gin"
"github.com/google/uuid"
- log "github.com/sirupsen/logrus"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/cookie"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/db/models"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/parsers"
- "github.com/authorizerdev/authorizer/server/token"
- "github.com/authorizerdev/authorizer/server/utils"
+
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/cookie"
+ "github.com/authorizerdev/authorizer/internal/parsers"
+ "github.com/authorizerdev/authorizer/internal/refs"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
+ "github.com/authorizerdev/authorizer/internal/token"
+ "github.com/authorizerdev/authorizer/internal/utils"
)
// VerifyEmailHandler handles the verify email route.
// It verifies email based on JWT token in query string
-func VerifyEmailHandler() gin.HandlerFunc {
+func (h *httpProvider) VerifyEmailHandler() gin.HandlerFunc {
+ log := h.Log.With().Str("func", "VerifyEmailHandler").Logger()
return func(c *gin.Context) {
redirectURL := strings.TrimSpace(c.Query("redirect_uri"))
errorRes := gin.H{
@@ -30,14 +29,14 @@ func VerifyEmailHandler() gin.HandlerFunc {
}
tokenInQuery := c.Query("token")
if tokenInQuery == "" {
- log.Debug("Token is empty")
+ log.Debug().Msg("Token is missing")
utils.HandleRedirectORJsonResponse(c, http.StatusBadRequest, errorRes, generateRedirectURL(redirectURL, errorRes))
return
}
- verificationRequest, err := db.Provider.GetVerificationRequestByToken(c, tokenInQuery)
+ verificationRequest, err := h.StorageProvider.GetVerificationRequestByToken(c, tokenInQuery)
if err != nil {
- log.Debug("Error getting verification request: ", err)
+ log.Debug().Err(err).Msg("Error getting verification request")
errorRes["error"] = err.Error()
utils.HandleRedirectORJsonResponse(c, http.StatusBadRequest, errorRes, generateRedirectURL(redirectURL, errorRes))
return
@@ -45,24 +44,30 @@ func VerifyEmailHandler() gin.HandlerFunc {
// verify if token exists in db
hostname := parsers.GetHost(c)
- claim, err := token.ParseJWTToken(tokenInQuery)
+ claim, err := h.TokenProvider.ParseJWTToken(tokenInQuery)
if err != nil {
- log.Debug("Error parsing token: ", err)
+ log.Debug().Err(err).Msg("Error parsing jwt token")
errorRes["error"] = err.Error()
utils.HandleRedirectORJsonResponse(c, http.StatusBadRequest, errorRes, generateRedirectURL(redirectURL, errorRes))
return
}
-
- if ok, err := token.ValidateJWTClaims(claim, hostname, verificationRequest.Nonce, verificationRequest.Email); !ok || err != nil {
- log.Debug("Error validating jwt claims: ", err)
+ // // hostname, verificationRequest.Nonce, verificationRequest.Email
+ if ok, err := h.TokenProvider.ValidateJWTClaims(claim, &token.AuthTokenConfig{
+ HostName: hostname,
+ Nonce: verificationRequest.Nonce,
+ User: &schemas.User{
+ Email: refs.NewStringRef(verificationRequest.Email),
+ },
+ }); !ok || err != nil {
+ log.Debug().Err(err).Msg("Error validating jwt token")
errorRes["error"] = err.Error()
utils.HandleRedirectORJsonResponse(c, http.StatusBadRequest, errorRes, generateRedirectURL(redirectURL, errorRes))
return
}
- user, err := db.Provider.GetUserByEmail(c, verificationRequest.Email)
+ user, err := h.StorageProvider.GetUserByEmail(c, verificationRequest.Email)
if err != nil {
- log.Debug("Error getting user: ", err)
+ log.Debug().Err(err).Msg("Error getting user by email")
errorRes["error"] = err.Error()
utils.HandleRedirectORJsonResponse(c, http.StatusBadRequest, errorRes, generateRedirectURL(redirectURL, errorRes))
return
@@ -74,16 +79,18 @@ func VerifyEmailHandler() gin.HandlerFunc {
now := time.Now().Unix()
user.EmailVerifiedAt = &now
isSignUp = true
- user, err = db.Provider.UpdateUser(c, user)
+ user, err = h.StorageProvider.UpdateUser(c, user)
if err != nil {
- log.Debug("Error updating user: ", err)
+ log.Debug().Err(err).Msg("Error updating user")
errorRes["error"] = err.Error()
utils.HandleRedirectORJsonResponse(c, http.StatusBadRequest, errorRes, generateRedirectURL(redirectURL, errorRes))
return
}
}
// delete from verification table
- db.Provider.DeleteVerificationRequest(c, verificationRequest)
+ if err := h.StorageProvider.DeleteVerificationRequest(c, verificationRequest); err != nil {
+ log.Debug().Err(err).Msg("Error deleting verification request")
+ }
state := strings.TrimSpace(c.Query("state"))
rolesString := strings.TrimSpace(c.Query("roles"))
@@ -112,7 +119,7 @@ func VerifyEmailHandler() gin.HandlerFunc {
nonce := ""
if state != "" {
// Get state from store
- authorizeState, _ := memorystore.Provider.GetState(state)
+ authorizeState, _ := h.MemoryStoreProvider.GetState(state)
if authorizeState != "" {
authorizeStateSplit := strings.Split(authorizeState, "@@")
if len(authorizeStateSplit) > 1 {
@@ -122,15 +129,23 @@ func VerifyEmailHandler() gin.HandlerFunc {
} else {
nonce = authorizeState
}
- go memorystore.Provider.RemoveState(state)
+ go h.MemoryStoreProvider.RemoveState(state)
}
}
if nonce == "" {
nonce = uuid.New().String()
}
- authToken, err := token.CreateAuthToken(c, user, roles, scope, loginMethod, nonce, code)
+ authToken, err := h.TokenProvider.CreateAuthToken(c, &token.AuthTokenConfig{
+ User: user,
+ Roles: roles,
+ Scope: scope,
+ LoginMethod: loginMethod,
+ Nonce: nonce,
+ Code: code,
+ HostName: hostname,
+ })
if err != nil {
- log.Debug("Error creating auth token: ", err)
+ log.Debug().Err(err).Msg("Error creating auth token")
errorRes["error"] = err.Error()
utils.HandleRedirectORJsonResponse(c, http.StatusInternalServerError, errorRes, generateRedirectURL(redirectURL, errorRes))
return
@@ -159,13 +174,13 @@ func VerifyEmailHandler() gin.HandlerFunc {
}
sessionKey := loginMethod + ":" + user.ID
- cookie.SetSession(c, authToken.FingerPrintHash)
- memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash, authToken.SessionTokenExpiresAt)
- memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token, authToken.AccessToken.ExpiresAt)
+ cookie.SetSession(c, authToken.FingerPrintHash, h.Config.AppCookieSecure)
+ h.MemoryStoreProvider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash, authToken.SessionTokenExpiresAt)
+ h.MemoryStoreProvider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token, authToken.AccessToken.ExpiresAt)
if authToken.RefreshToken != nil {
params = params + `&refresh_token=` + authToken.RefreshToken.Token
- memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token, authToken.RefreshToken.ExpiresAt)
+ h.MemoryStoreProvider.SetUserSession(sessionKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token, authToken.RefreshToken.ExpiresAt)
}
if redirectURL == "" {
@@ -180,17 +195,19 @@ func VerifyEmailHandler() gin.HandlerFunc {
go func() {
if isSignUp {
- utils.RegisterEvent(c, constants.UserSignUpWebhookEvent, loginMethod, user)
+ h.EventsProvider.RegisterEvent(c, constants.UserSignUpWebhookEvent, loginMethod, user)
// User is also logged in with signup
- utils.RegisterEvent(c, constants.UserLoginWebhookEvent, loginMethod, user)
+ h.EventsProvider.RegisterEvent(c, constants.UserLoginWebhookEvent, loginMethod, user)
} else {
- utils.RegisterEvent(c, constants.UserLoginWebhookEvent, loginMethod, user)
+ h.EventsProvider.RegisterEvent(c, constants.UserLoginWebhookEvent, loginMethod, user)
}
- db.Provider.AddSession(c, &models.Session{
+ if err := h.StorageProvider.AddSession(c, &schemas.Session{
UserID: user.ID,
UserAgent: utils.GetUserAgent(c.Request),
IP: utils.GetIP(c.Request),
- })
+ }); err != nil {
+ log.Debug().Err(err).Msg("Error adding session")
+ }
}()
c.Redirect(http.StatusTemporaryRedirect, redirectURL)
diff --git a/internal/integration_tests/add_email_template_test.go b/internal/integration_tests/add_email_template_test.go
new file mode 100644
index 000000000..76798cb85
--- /dev/null
+++ b/internal/integration_tests/add_email_template_test.go
@@ -0,0 +1,203 @@
+package integration_tests
+
+import (
+ "fmt"
+ "testing"
+
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/crypto"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/refs"
+ "github.com/google/uuid"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+// TestAddEmailTemplate tests the add email template functionality by the admin
+func TestAddEmailTemplate(t *testing.T) {
+ cfg := getTestConfig()
+ ts := initTestSetup(t, cfg)
+ req, ctx := createContext(ts)
+
+ // Create a test user
+ email := "add_email_template_user_test_" + uuid.New().String() + "@authorizer.dev"
+ password := "Password@123"
+
+ // Signup the user
+ signupReq := &model.SignUpRequest{
+ Email: &email,
+ Password: password,
+ ConfirmPassword: password,
+ }
+ signupRes, err := ts.GraphQLProvider.SignUp(ctx, signupReq)
+ require.NoError(t, err)
+ require.NotNil(t, signupRes)
+ require.NotNil(t, signupRes.User)
+
+ t.Run("should fail without admin cookie", func(t *testing.T) {
+ // Attempt to add template without admin authentication
+ params := &model.AddEmailTemplateRequest{
+ EventName: constants.VerificationTypeBasicAuthSignup,
+ Subject: "Verify your email",
+ Template: "Please verify your email by clicking the link: {{.URL}}",
+ }
+
+ resp, err := ts.GraphQLProvider.AddEmailTemplate(ctx, params)
+ require.Error(t, err)
+ require.Nil(t, resp)
+ assert.Contains(t, err.Error(), "unauthorized")
+ })
+
+ // Add admin cookie for the rest of the tests
+ h, err := crypto.EncryptPassword(cfg.AdminSecret)
+ assert.Nil(t, err)
+ req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
+
+ t.Run("should fail with invalid event name", func(t *testing.T) {
+ params := &model.AddEmailTemplateRequest{
+ EventName: "invalid_event_name",
+ Subject: "Test Subject",
+ Template: "Test Template",
+ }
+
+ resp, err := ts.GraphQLProvider.AddEmailTemplate(ctx, params)
+ require.Error(t, err)
+ require.Nil(t, resp)
+ })
+
+ t.Run("should fail with empty subject", func(t *testing.T) {
+ params := &model.AddEmailTemplateRequest{
+ EventName: constants.VerificationTypeBasicAuthSignup,
+ Subject: "",
+ Template: "Test Template",
+ }
+
+ resp, err := ts.GraphQLProvider.AddEmailTemplate(ctx, params)
+ require.Error(t, err)
+ require.Nil(t, resp)
+ })
+
+ t.Run("should fail with whitespace-only subject", func(t *testing.T) {
+ params := &model.AddEmailTemplateRequest{
+ EventName: constants.VerificationTypeBasicAuthSignup,
+ Subject: " ",
+ Template: "Test Template",
+ }
+
+ resp, err := ts.GraphQLProvider.AddEmailTemplate(ctx, params)
+ require.Error(t, err)
+ require.Nil(t, resp)
+ })
+
+ t.Run("should fail with empty template", func(t *testing.T) {
+ params := &model.AddEmailTemplateRequest{
+ EventName: constants.VerificationTypeBasicAuthSignup,
+ Subject: "Test Subject",
+ Template: "",
+ }
+
+ resp, err := ts.GraphQLProvider.AddEmailTemplate(ctx, params)
+ require.Error(t, err)
+ require.Nil(t, resp)
+ })
+
+ t.Run("should fail with whitespace-only template", func(t *testing.T) {
+ params := &model.AddEmailTemplateRequest{
+ EventName: constants.VerificationTypeBasicAuthSignup,
+ Subject: "Test Subject",
+ Template: " ",
+ }
+
+ resp, err := ts.GraphQLProvider.AddEmailTemplate(ctx, params)
+ require.Error(t, err)
+ require.Nil(t, resp)
+ })
+
+ t.Run("should add email template with design", func(t *testing.T) {
+ // First clean up any existing template
+ existingTemplate, err := ts.StorageProvider.GetEmailTemplateByEventName(ctx, constants.VerificationTypeMagicLinkLogin)
+ if err == nil && existingTemplate != nil {
+ err = ts.StorageProvider.DeleteEmailTemplate(ctx, existingTemplate)
+ require.NoError(t, err)
+ }
+
+ params := &model.AddEmailTemplateRequest{
+ EventName: constants.VerificationTypeMagicLinkLogin,
+ Subject: "Login with Magic Link",
+ Template: "Click this link to login: {{.URL}}",
+ Design: refs.NewStringRef("custom design"),
+ }
+
+ resp, err := ts.GraphQLProvider.AddEmailTemplate(ctx, params)
+ require.NoError(t, err)
+ require.NotNil(t, resp)
+ assert.Contains(t, resp.Message, "Email template added successfully")
+
+ // Verify template was saved
+ template, err := ts.StorageProvider.GetEmailTemplateByEventName(ctx, constants.VerificationTypeMagicLinkLogin)
+ require.NoError(t, err)
+ require.NotNil(t, template)
+ assert.Equal(t, params.EventName, template.EventName)
+ assert.Equal(t, params.Subject, template.Subject)
+ assert.Equal(t, params.Template, template.Template)
+ })
+
+ t.Run("should add email template without design", func(t *testing.T) {
+ // First clean up any existing template
+ existingTemplate, err := ts.StorageProvider.GetEmailTemplateByEventName(ctx, constants.VerificationTypeOTP)
+ if err == nil && existingTemplate != nil {
+ err = ts.StorageProvider.DeleteEmailTemplate(ctx, existingTemplate)
+ require.NoError(t, err)
+ }
+
+ params := &model.AddEmailTemplateRequest{
+ EventName: constants.VerificationTypeOTP,
+ Subject: "Your OTP Code",
+ Template: "Your OTP code is: {{.OTP}}",
+ }
+
+ resp, err := ts.GraphQLProvider.AddEmailTemplate(ctx, params)
+ require.NoError(t, err)
+ require.NotNil(t, resp)
+ assert.Contains(t, resp.Message, "Email template added successfully")
+
+ // Verify template was saved
+ template, err := ts.StorageProvider.GetEmailTemplateByEventName(ctx, constants.VerificationTypeOTP)
+ require.NoError(t, err)
+ require.NotNil(t, template)
+ assert.Equal(t, params.EventName, template.EventName)
+ assert.Equal(t, params.Subject, template.Subject)
+ assert.Equal(t, params.Template, template.Template)
+ assert.Equal(t, "", template.Design)
+ })
+
+ t.Run("should add email template with empty design string", func(t *testing.T) {
+ // First clean up any existing template
+ existingTemplate, err := ts.StorageProvider.GetEmailTemplateByEventName(ctx, constants.VerificationTypeForgotPassword)
+ if err == nil && existingTemplate != nil {
+ err = ts.StorageProvider.DeleteEmailTemplate(ctx, existingTemplate)
+ require.NoError(t, err)
+ }
+
+ params := &model.AddEmailTemplateRequest{
+ EventName: constants.VerificationTypeForgotPassword,
+ Subject: "Reset Your Password",
+ Template: "Click here to reset your password: {{.URL}}",
+ Design: refs.NewStringRef(""),
+ }
+
+ resp, err := ts.GraphQLProvider.AddEmailTemplate(ctx, params)
+ require.NoError(t, err)
+ require.NotNil(t, resp)
+ assert.Contains(t, resp.Message, "Email template added successfully")
+
+ // Verify template was saved
+ template, err := ts.StorageProvider.GetEmailTemplateByEventName(ctx, constants.VerificationTypeForgotPassword)
+ require.NoError(t, err)
+ require.NotNil(t, template)
+ assert.Equal(t, params.EventName, template.EventName)
+ assert.Equal(t, params.Subject, template.Subject)
+ assert.Equal(t, params.Template, template.Template)
+ assert.Equal(t, "", template.Design)
+ })
+}
diff --git a/internal/integration_tests/add_webhook_test.go b/internal/integration_tests/add_webhook_test.go
new file mode 100644
index 000000000..c60796aa3
--- /dev/null
+++ b/internal/integration_tests/add_webhook_test.go
@@ -0,0 +1,116 @@
+package integration_tests
+
+import (
+ "fmt"
+ "testing"
+
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/crypto"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/refs"
+ "github.com/google/uuid"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+// TestAddWebhookTest tests the add webhook functionality by the admin
+func TestAddWebhookTest(t *testing.T) {
+ cfg := getTestConfig()
+ ts := initTestSetup(t, cfg)
+ req, ctx := createContext(ts)
+
+ // Create a test user
+ email := "add_webhook_user_test_" + uuid.New().String() + "@authorizer.dev"
+ password := "Password@123"
+ // Signup the user
+ signupReq := &model.SignUpRequest{
+ Email: &email,
+ Password: password,
+ ConfirmPassword: password,
+ }
+ signupRes, err := ts.GraphQLProvider.SignUp(ctx, signupReq)
+ require.NoError(t, err)
+ require.NotNil(t, signupRes)
+ require.NotNil(t, signupRes.User)
+
+ t.Run("should fail without admin cookie", func(t *testing.T) {
+ addedWebhook, err := ts.GraphQLProvider.AddWebhook(ctx, &model.AddWebhookRequest{
+ EventName: "test",
+ EventDescription: refs.NewStringRef("test"),
+ Endpoint: "test",
+ Enabled: false,
+ Headers: map[string]any{
+ "test": "test",
+ },
+ })
+ require.Error(t, err)
+ require.Nil(t, addedWebhook)
+ })
+
+ t.Run("should fail with blank event name", func(t *testing.T) {
+ h, err := crypto.EncryptPassword(cfg.AdminSecret)
+ assert.Nil(t, err)
+
+ req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
+ addedWebhook, err := ts.GraphQLProvider.AddWebhook(ctx, &model.AddWebhookRequest{
+ EventName: "",
+ EventDescription: refs.NewStringRef("test"),
+ Endpoint: "test",
+ Enabled: false,
+ Headers: map[string]any{
+ "test": "test",
+ },
+ })
+ require.Error(t, err)
+ require.Nil(t, addedWebhook)
+ })
+
+ t.Run("should fail with blank endpoint", func(t *testing.T) {
+ h, err := crypto.EncryptPassword(cfg.AdminSecret)
+ assert.Nil(t, err)
+
+ req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
+ addedWebhook, err := ts.GraphQLProvider.AddWebhook(ctx, &model.AddWebhookRequest{
+ EventName: "test",
+ EventDescription: refs.NewStringRef("test"),
+ Endpoint: "",
+ Enabled: false,
+ Headers: map[string]any{
+ "test": "test",
+ },
+ })
+ require.Error(t, err)
+ require.Nil(t, addedWebhook)
+ })
+
+ t.Run("should add webhook", func(t *testing.T) {
+ h, err := crypto.EncryptPassword(cfg.AdminSecret)
+ assert.Nil(t, err)
+
+ req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
+ addedWebhook, err := ts.GraphQLProvider.AddWebhook(ctx, &model.AddWebhookRequest{
+ EventName: constants.UserCreatedWebhookEvent,
+ EventDescription: refs.NewStringRef("test"),
+ Endpoint: "test",
+ Enabled: false,
+ Headers: map[string]any{
+ "test": "test",
+ },
+ })
+ require.NoError(t, err)
+ assert.NotNil(t, addedWebhook)
+
+ res, err := ts.StorageProvider.GetWebhookByEventName(ctx, constants.UserCreatedWebhookEvent)
+ require.NoError(t, err)
+ assert.NotNil(t, res)
+ assert.Equal(t, 1, len(res))
+ assert.Equal(t, "test", res[0].EventDescription)
+ assert.Equal(t, "test", res[0].EndPoint)
+ assert.Equal(t, false, res[0].Enabled)
+ assert.Equal(t, "{\"test\":\"test\"}", res[0].Headers)
+ assert.NotNil(t, res[0].ID)
+ assert.NotNil(t, res[0].CreatedAt)
+ assert.NotNil(t, res[0].UpdatedAt)
+ assert.NotNil(t, res[0].Key)
+ })
+}
diff --git a/internal/integration_tests/admin_login_test.go b/internal/integration_tests/admin_login_test.go
new file mode 100644
index 000000000..5f61beb73
--- /dev/null
+++ b/internal/integration_tests/admin_login_test.go
@@ -0,0 +1,35 @@
+package integration_tests
+
+import (
+ "testing"
+
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+// TestAdminLogin tests the login functionality of the Authorizer application admin.
+func TestAdminLogin(t *testing.T) {
+ // Initialize test setup
+ cfg := getTestConfig()
+ ts := initTestSetup(t, cfg)
+ _, ctx := createContext(ts)
+
+ t.Run("should fail login with invalid admin secret", func(t *testing.T) {
+ adminLoginReq := &model.AdminLoginRequest{
+ AdminSecret: "invalid_secret",
+ }
+ adminLoginRes, err := ts.GraphQLProvider.AdminLogin(ctx, adminLoginReq)
+ require.Error(t, err)
+ assert.Nil(t, adminLoginRes)
+ })
+
+ t.Run("should complete admin login", func(t *testing.T) {
+ adminLoginReq := &model.AdminLoginRequest{
+ AdminSecret: cfg.AdminSecret,
+ }
+ res, err := ts.GraphQLProvider.AdminLogin(ctx, adminLoginReq)
+ require.NoError(t, err)
+ assert.NotNil(t, res)
+ })
+}
diff --git a/internal/integration_tests/admin_logout_test.go b/internal/integration_tests/admin_logout_test.go
new file mode 100644
index 000000000..5321f86f6
--- /dev/null
+++ b/internal/integration_tests/admin_logout_test.go
@@ -0,0 +1,33 @@
+package integration_tests
+
+import (
+ "fmt"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/crypto"
+)
+
+// TestAdminLogout tests the logout functionality of the Authorizer application admin.
+func TestAdminLogout(t *testing.T) {
+ // Initialize test setup
+ cfg := getTestConfig()
+ ts := initTestSetup(t, cfg)
+ req, ctx := createContext(ts)
+
+ t.Run("should complete admin login", func(t *testing.T) {
+ _, err := ts.GraphQLProvider.AdminLogout(ctx)
+ require.NotNil(t, err)
+
+ h, err := crypto.EncryptPassword(cfg.AdminSecret)
+ assert.Nil(t, err)
+
+ req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
+ res, err := ts.GraphQLProvider.AdminLogout(ctx)
+ require.Nil(t, err)
+ assert.NotNil(t, res)
+ })
+}
diff --git a/internal/integration_tests/deactivate_account_test.go b/internal/integration_tests/deactivate_account_test.go
new file mode 100644
index 000000000..12fe511a1
--- /dev/null
+++ b/internal/integration_tests/deactivate_account_test.go
@@ -0,0 +1,76 @@
+package integration_tests
+
+import (
+ "testing"
+
+ "github.com/google/uuid"
+ "github.com/stretchr/testify/assert"
+
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+)
+
+// TestDeactivateAccount tests the account deactivation functionality.
+func TestDeactivateAccount(t *testing.T) {
+ cfg := getTestConfig()
+ ts := initTestSetup(t, cfg)
+ _, ctx := createContext(ts)
+
+ // Create a test user and login to get tokens
+ email := "deactivate_test_" + uuid.New().String() + "@authorizer.dev"
+ password := "Password@123"
+
+ // Signup the user
+ signupReq := &model.SignUpRequest{
+ Email: &email,
+ Password: password,
+ ConfirmPassword: password,
+ }
+ signupRes, err := ts.GraphQLProvider.SignUp(ctx, signupReq)
+ assert.NoError(t, err)
+ assert.NotNil(t, signupRes)
+ assert.Equal(t, email, *signupRes.User.Email)
+ assert.NotEmpty(t, *signupRes.AccessToken)
+
+ // Login to get fresh tokens
+ loginReq := &model.LoginRequest{
+ Email: &email,
+ Password: password,
+ }
+ loginRes, err := ts.GraphQLProvider.Login(ctx, loginReq)
+ assert.NoError(t, err)
+ assert.NotNil(t, loginRes)
+ assert.NotEmpty(t, *loginRes.AccessToken)
+
+ // Test cases
+ t.Run("should fail deactivate account without access token", func(t *testing.T) {
+ // Clear any existing authorization header
+ ts.GinContext.Request.Header.Set("Authorization", "")
+ deactivateRes, err := ts.GraphQLProvider.DeactivateAccount(ctx)
+ assert.Error(t, err)
+ assert.Nil(t, deactivateRes)
+ })
+
+ t.Run("should fail deactivate account with invalid access token", func(t *testing.T) {
+ // Set an invalid token
+ ts.GinContext.Request.Header.Set("Authorization", "Bearer invalid_token")
+ deactivateRes, err := ts.GraphQLProvider.DeactivateAccount(ctx)
+ assert.Error(t, err)
+ assert.Nil(t, deactivateRes)
+ })
+
+ t.Run("should deactivate account successfully", func(t *testing.T) {
+ // Set the valid token
+ ts.GinContext.Request.Header.Set("Authorization", "Bearer "+*loginRes.AccessToken)
+ deactivateRes, err := ts.GraphQLProvider.DeactivateAccount(ctx)
+
+ assert.NoError(t, err)
+ assert.NotNil(t, deactivateRes)
+
+ t.Run("should fail login after deactivation", func(t *testing.T) {
+ // Attempt to login with the deactivated account
+ loginRes, err := ts.GraphQLProvider.Login(ctx, loginReq)
+ assert.Error(t, err)
+ assert.Nil(t, loginRes)
+ })
+ })
+}
diff --git a/internal/integration_tests/delete_email_template_test.go b/internal/integration_tests/delete_email_template_test.go
new file mode 100644
index 000000000..70120cbd9
--- /dev/null
+++ b/internal/integration_tests/delete_email_template_test.go
@@ -0,0 +1,230 @@
+package integration_tests
+
+import (
+ "fmt"
+ "testing"
+
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/crypto"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/google/uuid"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+// TestDeleteEmailTemplate tests the delete email template functionality
+func TestDeleteEmailTemplate(t *testing.T) {
+ cfg := getTestConfig()
+ ts := initTestSetup(t, cfg)
+ req, ctx := createContext(ts)
+
+ // Create a test user
+ email := "delete_email_template_test_" + uuid.New().String() + "@authorizer.dev"
+ password := "Password@123"
+
+ // Signup the user
+ signupReq := &model.SignUpRequest{
+ Email: &email,
+ Password: password,
+ ConfirmPassword: password,
+ }
+ signupRes, err := ts.GraphQLProvider.SignUp(ctx, signupReq)
+ require.NoError(t, err)
+ require.NotNil(t, signupRes)
+
+ // Test without admin cookie first
+ t.Run("should fail without admin cookie", func(t *testing.T) {
+ deleteParams := &model.DeleteEmailTemplateRequest{
+ ID: "some-id",
+ }
+
+ resp, err := ts.GraphQLProvider.DeleteEmailTemplate(ctx, deleteParams)
+ require.Error(t, err)
+ require.Nil(t, resp)
+ assert.Contains(t, err.Error(), "unauthorized")
+ })
+
+ // Add admin cookie for the rest of the tests
+ h, err := crypto.EncryptPassword(cfg.AdminSecret)
+ assert.Nil(t, err)
+ req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
+
+ t.Run("should fail with empty ID", func(t *testing.T) {
+ deleteParams := &model.DeleteEmailTemplateRequest{
+ ID: "",
+ }
+
+ resp, err := ts.GraphQLProvider.DeleteEmailTemplate(ctx, deleteParams)
+ require.Error(t, err)
+ require.Nil(t, resp)
+ assert.Contains(t, err.Error(), "email template ID required")
+ })
+
+ t.Run("should fail with whitespace-only ID", func(t *testing.T) {
+ deleteParams := &model.DeleteEmailTemplateRequest{
+ ID: " ",
+ }
+
+ resp, err := ts.GraphQLProvider.DeleteEmailTemplate(ctx, deleteParams)
+ require.Error(t, err)
+ require.Nil(t, resp)
+ assert.Contains(t, err.Error(), "email template ID required")
+ })
+
+ t.Run("should fail for non-existent template", func(t *testing.T) {
+ nonExistentID := uuid.New().String()
+ deleteParams := &model.DeleteEmailTemplateRequest{
+ ID: nonExistentID,
+ }
+
+ resp, err := ts.GraphQLProvider.DeleteEmailTemplate(ctx, deleteParams)
+ require.Error(t, err)
+ require.Nil(t, resp)
+ // The error message may vary depending on the storage implementation
+ assert.NotEmpty(t, err.Error())
+ })
+
+ // First create a template to test deletion
+ var templateID string
+ t.Run("setup - create template for deletion", func(t *testing.T) {
+ // Clean up any existing template
+ existingTemplate, err := ts.StorageProvider.GetEmailTemplateByEventName(ctx, constants.VerificationTypeInviteMember)
+ if err == nil && existingTemplate != nil {
+ err = ts.StorageProvider.DeleteEmailTemplate(ctx, existingTemplate)
+ require.NoError(t, err)
+ }
+
+ // Create a new template
+ addParams := &model.AddEmailTemplateRequest{
+ EventName: constants.VerificationTypeInviteMember,
+ Subject: "Invitation to Join",
+ Template: "You've been invited to join our platform: {{.URL}}",
+ }
+
+ resp, err := ts.GraphQLProvider.AddEmailTemplate(ctx, addParams)
+ require.NoError(t, err)
+ require.NotNil(t, resp)
+
+ // Get the created template to get its ID
+ template, err := ts.StorageProvider.GetEmailTemplateByEventName(ctx, constants.VerificationTypeInviteMember)
+ require.NoError(t, err)
+ require.NotNil(t, template)
+ templateID = template.ID
+ })
+
+ t.Run("should successfully delete template", func(t *testing.T) {
+ deleteParams := &model.DeleteEmailTemplateRequest{
+ ID: templateID,
+ }
+
+ resp, err := ts.GraphQLProvider.DeleteEmailTemplate(ctx, deleteParams)
+ require.NoError(t, err)
+ require.NotNil(t, resp)
+ assert.Contains(t, resp.Message, "Email templated deleted successfully")
+
+ // Verify the template was deleted
+ template, err := ts.StorageProvider.GetEmailTemplateByID(ctx, templateID)
+ assert.Error(t, err) // Should get an error because template should be gone
+ assert.Nil(t, template)
+ })
+
+ t.Run("should fail when trying to delete already deleted template", func(t *testing.T) {
+ // Try to delete the same template again
+ deleteParams := &model.DeleteEmailTemplateRequest{
+ ID: templateID,
+ }
+
+ resp, err := ts.GraphQLProvider.DeleteEmailTemplate(ctx, deleteParams)
+ require.Error(t, err)
+ require.Nil(t, resp)
+ // The error message may vary depending on the storage implementation
+ assert.NotEmpty(t, err.Error())
+ })
+
+ // Test with multiple email templates
+ var template1ID, template2ID string
+ t.Run("setup - create multiple templates", func(t *testing.T) {
+ // First, clean up any existing templates with these event names
+ existingTemplate1, err := ts.StorageProvider.GetEmailTemplateByEventName(ctx, constants.VerificationTypeBasicAuthSignup)
+ if err == nil && existingTemplate1 != nil {
+ err = ts.StorageProvider.DeleteEmailTemplate(ctx, existingTemplate1)
+ require.NoError(t, err)
+ }
+
+ existingTemplate2, err := ts.StorageProvider.GetEmailTemplateByEventName(ctx, constants.VerificationTypeForgotPassword)
+ if err == nil && existingTemplate2 != nil {
+ err = ts.StorageProvider.DeleteEmailTemplate(ctx, existingTemplate2)
+ require.NoError(t, err)
+ }
+
+ // Create first template
+ addParams1 := &model.AddEmailTemplateRequest{
+ EventName: constants.VerificationTypeBasicAuthSignup,
+ Subject: "Verify Your Signup",
+ Template: "Please verify your signup: {{.URL}}",
+ }
+
+ resp, err := ts.GraphQLProvider.AddEmailTemplate(ctx, addParams1)
+ require.NoError(t, err)
+ require.NotNil(t, resp)
+
+ template1, err := ts.StorageProvider.GetEmailTemplateByEventName(ctx, constants.VerificationTypeBasicAuthSignup)
+ require.NoError(t, err)
+ require.NotNil(t, template1)
+ template1ID = template1.ID
+
+ // Create second template
+ addParams2 := &model.AddEmailTemplateRequest{
+ EventName: constants.VerificationTypeForgotPassword,
+ Subject: "Password Reset",
+ Template: "Please reset your password: {{.URL}}",
+ }
+
+ resp, err = ts.GraphQLProvider.AddEmailTemplate(ctx, addParams2)
+ require.NoError(t, err)
+ require.NotNil(t, resp)
+
+ template2, err := ts.StorageProvider.GetEmailTemplateByEventName(ctx, constants.VerificationTypeForgotPassword)
+ require.NoError(t, err)
+ require.NotNil(t, template2)
+ template2ID = template2.ID
+ })
+
+ t.Run("should delete first template without affecting second", func(t *testing.T) {
+ deleteParams := &model.DeleteEmailTemplateRequest{
+ ID: template1ID,
+ }
+
+ resp, err := ts.GraphQLProvider.DeleteEmailTemplate(ctx, deleteParams)
+ require.NoError(t, err)
+ require.NotNil(t, resp)
+ assert.Contains(t, resp.Message, "Email templated deleted successfully")
+
+ // First template should be gone
+ template1, err := ts.StorageProvider.GetEmailTemplateByID(ctx, template1ID)
+ assert.Error(t, err)
+ assert.Nil(t, template1)
+
+ // Second template should still exist
+ template2, err := ts.StorageProvider.GetEmailTemplateByID(ctx, template2ID)
+ assert.NoError(t, err)
+ assert.NotNil(t, template2)
+ assert.Equal(t, constants.VerificationTypeForgotPassword, template2.EventName)
+ })
+
+ t.Run("should delete second template", func(t *testing.T) {
+ deleteParams := &model.DeleteEmailTemplateRequest{
+ ID: template2ID,
+ }
+
+ resp, err := ts.GraphQLProvider.DeleteEmailTemplate(ctx, deleteParams)
+ require.NoError(t, err)
+ require.NotNil(t, resp)
+ assert.Contains(t, resp.Message, "Email templated deleted successfully")
+
+ // Second template should now be gone
+ template2, err := ts.StorageProvider.GetEmailTemplateByID(ctx, template2ID)
+ assert.Error(t, err)
+ assert.Nil(t, template2)
+ })
+}
diff --git a/internal/integration_tests/delete_user_test.go b/internal/integration_tests/delete_user_test.go
new file mode 100644
index 000000000..32a61e79d
--- /dev/null
+++ b/internal/integration_tests/delete_user_test.go
@@ -0,0 +1,51 @@
+package integration_tests
+
+import (
+ "fmt"
+ "testing"
+
+ "github.com/google/uuid"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/crypto"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+)
+
+// TestDeleteUser tests the delete user functionality by the admin
+func TestDeleteUser(t *testing.T) {
+ cfg := getTestConfig()
+ ts := initTestSetup(t, cfg)
+ req, ctx := createContext(ts)
+
+ // Create a test user
+ email := "delete_user_test_" + uuid.New().String() + "@authorizer.dev"
+ password := "Password@123"
+ // Signup the user
+ signupReq := &model.SignUpRequest{
+ Email: &email,
+ Password: password,
+ ConfirmPassword: password,
+ }
+ signupRes, err := ts.GraphQLProvider.SignUp(ctx, signupReq)
+ require.NoError(t, err)
+ require.NotNil(t, signupRes)
+ require.NotNil(t, signupRes.User)
+
+ t.Run("should fail without admin cookie", func(t *testing.T) {
+ deleteRes, err := ts.GraphQLProvider.DeleteUser(ctx, &model.DeleteUserRequest{Email: email})
+ require.Error(t, err)
+ require.Nil(t, deleteRes)
+ })
+
+ t.Run("should delete user", func(t *testing.T) {
+ h, err := crypto.EncryptPassword(cfg.AdminSecret)
+ assert.Nil(t, err)
+
+ req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
+ deleteRes, err := ts.GraphQLProvider.DeleteUser(ctx, &model.DeleteUserRequest{Email: email})
+ require.NoError(t, err)
+ require.NotNil(t, deleteRes)
+ })
+}
diff --git a/internal/integration_tests/delete_webhook_test.go b/internal/integration_tests/delete_webhook_test.go
new file mode 100644
index 000000000..ec31f9a51
--- /dev/null
+++ b/internal/integration_tests/delete_webhook_test.go
@@ -0,0 +1,135 @@
+package integration_tests
+
+import (
+ "fmt"
+ "testing"
+
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/crypto"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/refs"
+ "github.com/google/uuid"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+// TestDeleteWebhookTest tests the delete webhook functionality by the admin
+func TestDeleteWebhookTest(t *testing.T) {
+ cfg := getTestConfig()
+ ts := initTestSetup(t, cfg)
+ req, ctx := createContext(ts)
+
+ // Create a test user
+ email := "delete_webhook_user_test_" + uuid.New().String() + "@authorizer.dev"
+ password := "Password@123"
+ // Signup the user
+ signupReq := &model.SignUpRequest{
+ Email: &email,
+ Password: password,
+ ConfirmPassword: password,
+ }
+ signupRes, err := ts.GraphQLProvider.SignUp(ctx, signupReq)
+ require.NoError(t, err)
+ require.NotNil(t, signupRes)
+ require.NotNil(t, signupRes.User)
+
+ // First add a webhook to delete
+ h, err := crypto.EncryptPassword(cfg.AdminSecret)
+ assert.Nil(t, err)
+ req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
+
+ eventNameToDelete := constants.UserCreatedWebhookEvent
+ eventNameToPersist := constants.UserLoginWebhookEvent
+
+ addedWebhook, err := ts.GraphQLProvider.AddWebhook(ctx, &model.AddWebhookRequest{
+ EventName: eventNameToDelete,
+ EventDescription: refs.NewStringRef("webhook to be deleted"),
+ Endpoint: "http://webhook-to-delete.com",
+ Enabled: true,
+ Headers: map[string]any{
+ "Content-Type": "application/json",
+ },
+ })
+ require.NoError(t, err)
+ assert.NotNil(t, addedWebhook)
+
+ // Get the webhook to delete
+ webhooks, err := ts.StorageProvider.GetWebhookByEventName(ctx, eventNameToDelete)
+ require.NoError(t, err)
+ require.NotEmpty(t, webhooks)
+ webhookID := webhooks[0].ID
+
+ // Create another webhook that won't be deleted (to verify we're not deleting all webhooks)
+ persistentWebhook, err := ts.GraphQLProvider.AddWebhook(ctx, &model.AddWebhookRequest{
+ EventName: eventNameToPersist,
+ EventDescription: refs.NewStringRef("webhook that should persist"),
+ Endpoint: "http://persistent-webhook.com",
+ Enabled: true,
+ })
+ require.NoError(t, err)
+ assert.NotNil(t, persistentWebhook)
+
+ t.Run("should fail without admin cookie", func(t *testing.T) {
+ // Remove admin cookie
+ req.Header.Del("Cookie")
+
+ resp, err := ts.GraphQLProvider.DeleteWebhook(ctx, &model.WebhookRequest{
+ ID: webhookID,
+ })
+ require.Error(t, err)
+ require.Nil(t, resp)
+ })
+
+ // Re-add the admin cookie for the rest of the tests
+ req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
+
+ t.Run("should fail with invalid webhook ID", func(t *testing.T) {
+ resp, err := ts.GraphQLProvider.DeleteWebhook(ctx, &model.WebhookRequest{
+ ID: uuid.NewString(),
+ })
+ require.Error(t, err)
+ require.Nil(t, resp)
+ })
+
+ t.Run("should fail with blank webhook ID", func(t *testing.T) {
+ resp, err := ts.GraphQLProvider.DeleteWebhook(ctx, &model.WebhookRequest{
+ ID: "",
+ })
+ require.Error(t, err)
+ require.Nil(t, resp)
+ })
+
+ t.Run("should delete webhook successfully", func(t *testing.T) {
+ // Verify webhook exists before deletion
+ webhookBeforeDelete, err := ts.StorageProvider.GetWebhookByID(ctx, webhookID)
+ require.NoError(t, err)
+ require.NotNil(t, webhookBeforeDelete)
+
+ // Delete the webhook
+ resp, err := ts.GraphQLProvider.DeleteWebhook(ctx, &model.WebhookRequest{
+ ID: webhookID,
+ })
+ require.NoError(t, err)
+ require.NotNil(t, resp)
+ assert.Contains(t, resp.Message, "successfully")
+
+ // Verify webhook was deleted
+ webhookAfterDelete, err := ts.StorageProvider.GetWebhookByID(ctx, webhookID)
+ require.Error(t, err) // Should error because webhook no longer exists
+ require.Nil(t, webhookAfterDelete)
+
+ // Verify other webhooks still exist
+ persistentWebhooks, err := ts.StorageProvider.GetWebhookByEventName(ctx, eventNameToPersist)
+ require.NoError(t, err)
+ require.NotEmpty(t, persistentWebhooks)
+ })
+
+ t.Run("should fail to delete already deleted webhook", func(t *testing.T) {
+ // Try to delete the same webhook again
+ resp, err := ts.GraphQLProvider.DeleteWebhook(ctx, &model.WebhookRequest{
+ ID: webhookID,
+ })
+ require.Error(t, err)
+ require.Nil(t, resp)
+ })
+}
diff --git a/internal/integration_tests/enable_access_test.go b/internal/integration_tests/enable_access_test.go
new file mode 100644
index 000000000..f4ba6d09b
--- /dev/null
+++ b/internal/integration_tests/enable_access_test.go
@@ -0,0 +1,76 @@
+package integration_tests
+
+import (
+ "fmt"
+ "testing"
+
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/crypto"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/google/uuid"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+// TestEnableAccessUser tests the enable access functionality by the admin
+func TestEnableAccessUser(t *testing.T) {
+ cfg := getTestConfig()
+ ts := initTestSetup(t, cfg)
+ req, ctx := createContext(ts)
+
+ // Create a test user
+ email := "enable_access_test_" + uuid.New().String() + "@authorizer.dev"
+ password := "Password@123"
+ // Signup the user
+ signupReq := &model.SignUpRequest{
+ Email: &email,
+ Password: password,
+ ConfirmPassword: password,
+ }
+ signupRes, err := ts.GraphQLProvider.SignUp(ctx, signupReq)
+ require.NoError(t, err)
+ require.NotNil(t, signupRes)
+ require.NotNil(t, signupRes.User)
+
+ t.Run("should fail without admin cookie", func(t *testing.T) {
+ revokedUserDets, err := ts.GraphQLProvider.EnableAccess(ctx, &model.UpdateAccessRequest{
+ UserID: signupRes.User.ID,
+ })
+ require.Error(t, err)
+ require.Nil(t, revokedUserDets)
+ })
+
+ t.Run("should fail with blank userid", func(t *testing.T) {
+ h, err := crypto.EncryptPassword(cfg.AdminSecret)
+ assert.Nil(t, err)
+
+ req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
+ _, err = ts.GraphQLProvider.EnableAccess(ctx, &model.UpdateAccessRequest{
+ UserID: "",
+ })
+ require.Error(t, err)
+ })
+
+ t.Run("should fail with unknown userid", func(t *testing.T) {
+ h, err := crypto.EncryptPassword(cfg.AdminSecret)
+ assert.Nil(t, err)
+
+ req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
+ _, err = ts.GraphQLProvider.EnableAccess(ctx, &model.UpdateAccessRequest{
+ UserID: uuid.NewString(),
+ })
+ require.Error(t, err)
+ })
+
+ t.Run("should enable access user", func(t *testing.T) {
+ h, err := crypto.EncryptPassword(cfg.AdminSecret)
+ assert.Nil(t, err)
+
+ req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
+ enableAccessDets, err := ts.GraphQLProvider.EnableAccess(ctx, &model.UpdateAccessRequest{
+ UserID: signupRes.User.ID,
+ })
+ require.NoError(t, err)
+ assert.NotNil(t, enableAccessDets)
+ })
+}
diff --git a/internal/integration_tests/forgot_password_test.go b/internal/integration_tests/forgot_password_test.go
new file mode 100644
index 000000000..6b8e21255
--- /dev/null
+++ b/internal/integration_tests/forgot_password_test.go
@@ -0,0 +1,60 @@
+package integration_tests
+
+import (
+ "testing"
+
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/refs"
+ "github.com/google/uuid"
+ "github.com/stretchr/testify/assert"
+)
+
+// TestForgotPassword tests the forgot password functionality
+func TestForgotPassword(t *testing.T) {
+ cfg := getTestConfig()
+ ts := initTestSetup(t, cfg)
+ _, ctx := createContext(ts)
+
+ // Create a test user
+ email := "forgot_password_test_" + uuid.New().String() + "@authorizer.dev"
+ password := "Password@123"
+ // Signup the user
+ signupReq := &model.SignUpRequest{
+ Email: &email,
+ Password: password,
+ ConfirmPassword: password,
+ }
+
+ signupRes, err := ts.GraphQLProvider.SignUp(ctx, signupReq)
+ assert.NoError(t, err)
+ assert.NotNil(t, signupRes)
+ assert.NotNil(t, signupRes.User)
+
+ // Create forgot password request
+ t.Run("should fail for invalid email", func(t *testing.T) {
+ forgotPasswordReq := &model.ForgotPasswordRequest{
+ Email: refs.NewStringRef("invalid-email@gmail.com"),
+ }
+ forgotPasswordRes, err := ts.GraphQLProvider.ForgotPassword(ctx, forgotPasswordReq)
+ assert.Error(t, err)
+ assert.Nil(t, forgotPasswordRes)
+ })
+
+ t.Run("should send forgot password email", func(t *testing.T) {
+ forgotPasswordReq := &model.ForgotPasswordRequest{
+ Email: refs.NewStringRef(email),
+ }
+ forgotPasswordRes, err := ts.GraphQLProvider.ForgotPassword(ctx, forgotPasswordReq)
+ assert.NoError(t, err)
+ assert.NotNil(t, forgotPasswordRes)
+ assert.NotEmpty(t, forgotPasswordRes.Message)
+
+ // Validate if the entry is created in db
+ request, err := ts.StorageProvider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeForgotPassword)
+ assert.NoError(t, err)
+ assert.NotNil(t, request)
+ assert.NotEmpty(t, request.Token)
+ assert.Equal(t, email, request.Email)
+ })
+}
diff --git a/internal/integration_tests/invite_members_test.go b/internal/integration_tests/invite_members_test.go
new file mode 100644
index 000000000..a90ee1d2e
--- /dev/null
+++ b/internal/integration_tests/invite_members_test.go
@@ -0,0 +1,90 @@
+package integration_tests
+
+import (
+ "fmt"
+ "testing"
+
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/crypto"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/google/uuid"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+// TestInviteMembersUser tests the invite user functionality by the admin
+func TestInviteMembersUser(t *testing.T) {
+ cfg := getTestConfig()
+ ts := initTestSetup(t, cfg)
+ req, ctx := createContext(ts)
+
+ // Create a test user
+ email := "invite_user_test_" + uuid.New().String() + "@authorizer.dev"
+ emailTo := "test_user_invitation_" + uuid.New().String() + "@authorizer.dev"
+ password := "Password@123"
+ url := "https://authorizer.dev/"
+ // Signup the user
+ signupReq := &model.SignUpRequest{
+ Email: &email,
+ Password: password,
+ ConfirmPassword: password,
+ }
+ signupRes, err := ts.GraphQLProvider.SignUp(ctx, signupReq)
+ require.NoError(t, err)
+ require.NotNil(t, signupRes)
+ require.NotNil(t, signupRes.User)
+
+ t.Run("should fail without admin cookie", func(t *testing.T) {
+ invitedUserDets, err := ts.GraphQLProvider.InviteMembers(ctx, &model.InviteMemberRequest{
+ Emails: []string{emailTo},
+ RedirectURI: &url,
+ })
+ require.Error(t, err)
+ require.Nil(t, invitedUserDets)
+ })
+
+ t.Run("should fail to invite user as email sending is disabled", func(t *testing.T) {
+ h, err := crypto.EncryptPassword(cfg.AdminSecret)
+ assert.Nil(t, err)
+
+ req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
+ _, err = ts.GraphQLProvider.InviteMembers(ctx, &model.InviteMemberRequest{
+ Emails: []string{emailTo},
+ RedirectURI: &url,
+ })
+ require.Error(t, err)
+ })
+
+ t.Run("should fail to invite user as email is blank", func(t *testing.T) {
+ cfg.IsEmailServiceEnabled = true
+ cfg.EnableBasicAuthentication = true
+ cfg.EnableMagicLinkLogin = true
+ h, err := crypto.EncryptPassword(cfg.AdminSecret)
+ assert.Nil(t, err)
+
+ req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
+ _, err = ts.GraphQLProvider.InviteMembers(ctx, &model.InviteMemberRequest{
+ Emails: []string{},
+ RedirectURI: &url,
+ })
+ require.Error(t, err)
+ })
+
+ t.Run("should invite user as email sending is enabled", func(t *testing.T) {
+ cfg.IsEmailServiceEnabled = true
+ cfg.EnableBasicAuthentication = true
+ cfg.EnableMagicLinkLogin = true
+ h, err := crypto.EncryptPassword(cfg.AdminSecret)
+ assert.Nil(t, err)
+
+ req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
+ invitedUserDets, err := ts.GraphQLProvider.InviteMembers(ctx, &model.InviteMemberRequest{
+ Emails: []string{emailTo},
+ RedirectURI: &url,
+ })
+ require.NoError(t, err)
+ for _, user := range invitedUserDets.Users {
+ assert.Equal(t, *user.Email, emailTo)
+ }
+ })
+}
diff --git a/internal/integration_tests/login_test.go b/internal/integration_tests/login_test.go
new file mode 100644
index 000000000..c4374744f
--- /dev/null
+++ b/internal/integration_tests/login_test.go
@@ -0,0 +1,101 @@
+package integration_tests
+
+import (
+ "fmt"
+ "testing"
+ "time"
+
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/google/uuid"
+ "github.com/stretchr/testify/assert"
+)
+
+// TestLogin tests the login functionality of the Authorizer application.
+func TestLogin(t *testing.T) {
+ // Initialize test setup
+ cfg := getTestConfig()
+ ts := initTestSetup(t, cfg)
+ _, ctx := createContext(ts)
+
+ // Test setup - create a test user
+ email := "login_test_" + uuid.New().String() + "@authorizer.dev"
+ password := "Password@123"
+
+ signupReq := &model.SignUpRequest{
+ Email: &email,
+ Password: password,
+ ConfirmPassword: password,
+ }
+ res, err := ts.GraphQLProvider.SignUp(ctx, signupReq)
+ assert.NoError(t, err)
+ assert.NotNil(t, res)
+
+ // Login tests
+ t.Run("should fail login with invalid email", func(t *testing.T) {
+ invalidEmail := "invalid@email.com"
+ loginReq := &model.LoginRequest{
+ Email: &invalidEmail,
+ Password: password,
+ }
+ res, err := ts.GraphQLProvider.Login(ctx, loginReq)
+ assert.Error(t, err)
+ assert.Nil(t, res)
+ })
+
+ t.Run("should fail login with invalid password", func(t *testing.T) {
+ loginReq := &model.LoginRequest{
+ Email: &email,
+ Password: "WrongPassword@123",
+ }
+ res, err := ts.GraphQLProvider.Login(ctx, loginReq)
+ assert.Error(t, err)
+ assert.Nil(t, res)
+ })
+
+ t.Run("should login successfully with valid credentials", func(t *testing.T) {
+ loginReq := &model.LoginRequest{
+ Email: &email,
+ Password: password,
+ }
+ res, err := ts.GraphQLProvider.Login(ctx, loginReq)
+ assert.NoError(t, err)
+ assert.NotNil(t, res)
+
+ // Verify response contains expected tokens
+ assert.NotEmpty(t, res.AccessToken)
+ assert.NotNil(t, res.User)
+ assert.Equal(t, email, *res.User.Email)
+ assert.True(t, res.User.EmailVerified)
+ })
+
+ t.Run("should fail login with empty credentials", func(t *testing.T) {
+ loginReq := &model.LoginRequest{}
+ res, err := ts.GraphQLProvider.Login(ctx, loginReq)
+ assert.Error(t, err)
+ assert.Nil(t, res)
+ })
+
+ t.Run("mobile login", func(t *testing.T) {
+ mobile := fmt.Sprintf("%d", time.Now().Add(10*time.Second).Unix())
+ signUpReq := &model.SignUpRequest{
+ PhoneNumber: &mobile,
+ Password: password,
+ ConfirmPassword: password,
+ }
+ res, err := ts.GraphQLProvider.SignUp(ctx, signUpReq)
+ assert.NoError(t, err)
+ assert.NotNil(t, res)
+
+ // Login
+ loginReq := &model.LoginRequest{
+ PhoneNumber: &mobile,
+ Password: password,
+ }
+ res, err = ts.GraphQLProvider.Login(ctx, loginReq)
+ assert.NoError(t, err)
+ assert.NotEmpty(t, res.AccessToken)
+ assert.NotNil(t, res.User)
+ assert.Equal(t, mobile, *res.User.PhoneNumber)
+ assert.True(t, res.User.PhoneNumberVerified)
+ })
+}
diff --git a/internal/integration_tests/logout_test.go b/internal/integration_tests/logout_test.go
new file mode 100644
index 000000000..f8477422f
--- /dev/null
+++ b/internal/integration_tests/logout_test.go
@@ -0,0 +1,76 @@
+package integration_tests
+
+import (
+ "testing"
+
+ "github.com/google/uuid"
+ "github.com/stretchr/testify/assert"
+
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+)
+
+// TestLogout tests the logout functionality of the Authorizer application.
+func TestLogout(t *testing.T) {
+ cfg := getTestConfig()
+ ts := initTestSetup(t, cfg)
+ _, ctx := createContext(ts)
+
+ // Create a test user and login to get tokens
+ email := "logout_test_" + uuid.New().String() + "@authorizer.dev"
+ password := "Password@123"
+
+ // Signup the user
+ signupReq := &model.SignUpRequest{
+ Email: &email,
+ Password: password,
+ ConfirmPassword: password,
+ }
+ signupRes, err := ts.GraphQLProvider.SignUp(ctx, signupReq)
+ assert.NoError(t, err)
+ assert.NotNil(t, signupRes)
+ assert.Equal(t, email, *signupRes.User.Email)
+ assert.NotEmpty(t, *signupRes.AccessToken)
+
+ // Login to get fresh tokens
+ loginReq := &model.LoginRequest{
+ Email: &email,
+ Password: password,
+ }
+ loginRes, err := ts.GraphQLProvider.Login(ctx, loginReq)
+ assert.NoError(t, err)
+ assert.NotNil(t, loginRes)
+ assert.NotEmpty(t, *loginRes.AccessToken)
+
+ // Test cases
+ t.Run("should fail logout without access token", func(t *testing.T) {
+ // Clear any existing authorization header
+ ts.GinContext.Request.Header.Set("Authorization", "")
+
+ logoutRes, err := ts.GraphQLProvider.Logout(ctx)
+ assert.Error(t, err)
+ assert.Nil(t, logoutRes)
+ })
+
+ t.Run("should fail logout with invalid access token", func(t *testing.T) {
+ // Set an invalid token
+ ts.GinContext.Request.Header.Set("Authorization", "Bearer invalid_token")
+
+ logoutRes, err := ts.GraphQLProvider.Logout(ctx)
+ assert.Error(t, err)
+ assert.Nil(t, logoutRes)
+ })
+
+ t.Run("should successfully logout with valid access token", func(t *testing.T) {
+ // Set the valid access token
+ ts.GinContext.Request.Header.Set("Authorization", "Bearer "+*loginRes.AccessToken)
+ logoutRes, err := ts.GraphQLProvider.Logout(ctx)
+ assert.NoError(t, err)
+ assert.NotNil(t, logoutRes)
+ assert.NotNil(t, logoutRes.Message)
+
+ // Try to access a protected endpoint with the same token
+ profile, err := ts.GraphQLProvider.Profile(ctx)
+ assert.Error(t, err)
+ assert.Nil(t, profile)
+ })
+}
diff --git a/internal/integration_tests/magic_link_login_test.go b/internal/integration_tests/magic_link_login_test.go
new file mode 100644
index 000000000..a303a07a8
--- /dev/null
+++ b/internal/integration_tests/magic_link_login_test.go
@@ -0,0 +1,72 @@
+package integration_tests
+
+import (
+ "testing"
+
+ "github.com/google/uuid"
+ "github.com/stretchr/testify/assert"
+
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+)
+
+// TestMagicLinkLogin tests the magic link login functionality of the Authorizer application.
+func TestMagicLinkLogin(t *testing.T) {
+ cfg := getTestConfig()
+ cfg.EnableMagicLinkLogin = true
+ cfg.SMTPHost = "localhost"
+ cfg.SMTPPort = 1025
+ cfg.SMTPSenderEmail = "test@authorizer.dev"
+ cfg.SMTPSenderName = "Test"
+ cfg.SMTPLocalName = "Test"
+ cfg.SkipTLSVerification = true
+ cfg.IsEmailServiceEnabled = true
+ cfg.IsSMSServiceEnabled = true
+ cfg.EnableEmailVerification = true
+ ts := initTestSetup(t, cfg)
+ _, ctx := createContext(ts)
+
+ email := "magic_link_user" + uuid.New().String() + "@authorizer.dev"
+
+ t.Run("should fail for missing email", func(t *testing.T) {
+ loginReq := &model.MagicLinkLoginRequest{}
+ res, err := ts.GraphQLProvider.MagicLinkLogin(ctx, loginReq)
+ assert.Error(t, err)
+ assert.Nil(t, res)
+ })
+ t.Run("should fail for invalid email", func(t *testing.T) {
+ loginReq := &model.MagicLinkLoginRequest{
+ Email: "invalid-email",
+ }
+ res, err := ts.GraphQLProvider.MagicLinkLogin(ctx, loginReq)
+ assert.Error(t, err)
+ assert.Nil(t, res)
+ })
+ t.Run("should pass for valid email", func(t *testing.T) {
+ res, err := ts.GraphQLProvider.MagicLinkLogin(ctx, &model.MagicLinkLoginRequest{
+ Email: email,
+ })
+ assert.NoError(t, err)
+ assert.NotNil(t, res)
+ assert.NotEmpty(t, res.Message)
+
+ verificationRequest, err := ts.StorageProvider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeMagicLinkLogin)
+ assert.NoError(t, err)
+ assert.NotNil(t, verificationRequest)
+ verifyRes, err := ts.GraphQLProvider.VerifyEmail(ctx, &model.VerifyEmailRequest{
+ Token: verificationRequest.Token,
+ })
+ assert.NoError(t, err)
+ assert.NotEmpty(t, *verifyRes.AccessToken)
+
+ // Set the Authorization header for the Profile request
+ ts.GinContext.Request.Header.Set("Authorization", "Bearer "+*verifyRes.AccessToken)
+
+ profile, err := ts.GraphQLProvider.Profile(ctx)
+ assert.Nil(t, err)
+ assert.NotNil(t, profile)
+
+ // Clean up the header after the test
+ ts.GinContext.Request.Header.Set("Authorization", "")
+ })
+}
diff --git a/internal/integration_tests/profile_test.go b/internal/integration_tests/profile_test.go
new file mode 100644
index 000000000..a206ff507
--- /dev/null
+++ b/internal/integration_tests/profile_test.go
@@ -0,0 +1,97 @@
+package integration_tests
+
+import (
+ "fmt"
+ "strings"
+ "testing"
+
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/google/uuid"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+// TestProfile tests the profile functionality
+func TestProfile(t *testing.T) {
+ // Initialize test setup
+ cfg := getTestConfig()
+ ts := initTestSetup(t, cfg)
+ req, ctx := createContext(ts)
+
+ // Test setup - create a test user
+ email := "profile_test_" + uuid.New().String() + "@authorizer.dev"
+ password := "Password@123"
+
+ signupReq := &model.SignUpRequest{
+ Email: &email,
+ Password: password,
+ ConfirmPassword: password,
+ }
+ res, err := ts.GraphQLProvider.SignUp(ctx, signupReq)
+ assert.NoError(t, err)
+ assert.NotNil(t, res)
+
+ // Profile tests
+ t.Run("after login", func(t *testing.T) {
+ loginReq := &model.LoginRequest{
+ Email: &email,
+ Password: password,
+ }
+ loginRes, err := ts.GraphQLProvider.Login(ctx, loginReq)
+ assert.NoError(t, err)
+ assert.NotNil(t, loginRes)
+
+ // Verify response contains expected tokens
+ assert.NotEmpty(t, loginRes.AccessToken)
+ assert.NotNil(t, loginRes.User)
+ assert.Equal(t, email, *loginRes.User.Email)
+ assert.True(t, loginRes.User.EmailVerified)
+
+ t.Run("should fail without cookie and authorization header", func(t *testing.T) {
+ res, err := ts.GraphQLProvider.Profile(ctx)
+ assert.Error(t, err)
+ assert.Nil(t, res)
+ })
+
+ t.Run("should return profile with browser session", func(t *testing.T) {
+ allData, err := ts.MemoryStoreProvider.GetAllData()
+ require.NoError(t, err)
+ sessionToken := ""
+ for k, v := range allData {
+ if strings.Contains(k, constants.TokenTypeSessionToken) {
+ sessionToken = v
+ break
+ }
+ }
+ req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AppCookieName+"_session", sessionToken))
+ defer func() {
+ req.Header.Del("Cookie")
+ }()
+ res, err := ts.GraphQLProvider.Profile(ctx)
+ require.NoError(t, err)
+ require.NotNil(t, res)
+ assert.Equal(t, email, *res.Email)
+ })
+
+ t.Run("should return profile with authorization header", func(t *testing.T) {
+ allData, err := ts.MemoryStoreProvider.GetAllData()
+ require.NoError(t, err)
+ accessToken := ""
+ for k, v := range allData {
+ if strings.Contains(k, constants.TokenTypeAccessToken) {
+ accessToken = v
+ break
+ }
+ }
+ req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", accessToken))
+ defer func() {
+ req.Header.Del("Authorization")
+ }()
+ res, err := ts.GraphQLProvider.Profile(ctx)
+ require.NoError(t, err)
+ require.NotNil(t, res)
+ assert.Equal(t, email, *res.Email)
+ })
+ })
+}
diff --git a/internal/integration_tests/resend_otp_test.go b/internal/integration_tests/resend_otp_test.go
new file mode 100644
index 000000000..066cc9528
--- /dev/null
+++ b/internal/integration_tests/resend_otp_test.go
@@ -0,0 +1,117 @@
+package integration_tests
+
+import (
+ "fmt"
+ "strings"
+ "testing"
+
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/refs"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+// TestResendOTP tests the resend verify OTP functionality
+func TestResendOTP(t *testing.T) {
+ cfg := getTestConfig()
+ cfg.IsSMSServiceEnabled = true
+ cfg.EnableEmailOTP = true
+ cfg.EnableSMSOTP = true
+ cfg.EnablePhoneVerification = true
+ cfg.EnableMobileBasicAuthentication = true
+ cfg.EnableMFA = true
+ cfg.SMTPHost = "localhost"
+ cfg.SMTPPort = 1025
+ cfg.SMTPSenderEmail = "test@authorizer.dev"
+ cfg.SMTPSenderName = "Test"
+ cfg.SMTPLocalName = "Test"
+ cfg.SkipTLSVerification = true
+ cfg.IsEmailServiceEnabled = true
+ cfg.IsSMSServiceEnabled = true
+ cfg.EnableEmailVerification = true
+ cfg.TwilioAPISecret = "test-twilio-api-secret"
+ cfg.TwilioAPIKey = "test-twilio-api-key"
+ cfg.TwilioAccountSID = "test-twilio-account-sid"
+ cfg.TwilioSender = "test-twilio-sender"
+ ts := initTestSetup(t, cfg)
+ req, ctx := createContext(ts)
+
+ // Create a test user
+ mobile := "+14155552672"
+ password := "Password@123"
+ // Signup the user
+ signupReq := &model.SignUpRequest{
+ PhoneNumber: &mobile,
+ Password: password,
+ ConfirmPassword: password,
+ }
+
+ signupRes, err := ts.GraphQLProvider.SignUp(ctx, signupReq)
+ assert.NoError(t, err)
+ assert.NotNil(t, signupRes)
+ // Expect the user to be nil, as the email is not verified yet
+ assert.Nil(t, signupRes.User)
+
+ // Get the OTP from db
+ otpData, err := ts.StorageProvider.GetOTPByPhoneNumber(ctx, mobile)
+ require.NoError(t, err)
+ assert.NotNil(t, otpData)
+ // User
+ userData, err := ts.StorageProvider.GetUserByPhoneNumber(ctx, mobile)
+ require.NoError(t, err)
+ assert.NotNil(t, userData)
+
+ t.Run("should fail if request for given email or phone number does not exists", func(t *testing.T) {
+ resendReq := &model.ResendOTPRequest{
+ PhoneNumber: refs.NewStringRef("2131231212"),
+ }
+ resendRes, err := ts.GraphQLProvider.ResendOTP(ctx, resendReq)
+ assert.Error(t, err)
+ assert.Nil(t, resendRes)
+ })
+ t.Run("should send resend request{mobile}", func(t *testing.T) {
+ resendReq := &model.ResendOTPRequest{
+ PhoneNumber: refs.NewStringRef(mobile),
+ }
+ resendRes, err := ts.GraphQLProvider.ResendOTP(ctx, resendReq)
+ assert.NoError(t, err)
+ assert.NotNil(t, resendRes)
+ req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.MfaCookieName+"_session", constants.TestEnv))
+ t.Run("old OTP should be invalidated", func(t *testing.T) {
+ verificationReq := &model.VerifyOTPRequest{
+ PhoneNumber: &mobile,
+ Otp: otpData.Otp,
+ }
+ verificationRes, err := ts.GraphQLProvider.VerifyOTP(ctx, verificationReq)
+ assert.Error(t, err)
+ assert.Nil(t, verificationRes)
+ })
+ t.Run("should verify OTP", func(t *testing.T) {
+ // Get MFA session cookie
+ allData, err := ts.MemoryStoreProvider.GetAllData()
+ require.NoError(t, err)
+ sessionKey := ""
+ for k := range allData {
+ if strings.Contains(k, userData.ID) {
+ splitData := strings.Split(k, ":")
+ if len(splitData) > 1 {
+ sessionKey = splitData[1]
+ break
+ }
+ }
+ }
+ req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.MfaCookieName+"_session", sessionKey))
+ newOtpData, err := ts.StorageProvider.GetOTPByPhoneNumber(ctx, mobile)
+ require.NoError(t, err)
+ assert.NotNil(t, newOtpData)
+ verificationReq := &model.VerifyOTPRequest{
+ PhoneNumber: &mobile,
+ Otp: newOtpData.Otp,
+ }
+ verificationRes, err := ts.GraphQLProvider.VerifyOTP(ctx, verificationReq)
+ require.NoError(t, err)
+ assert.NotNil(t, verificationRes)
+ })
+ })
+}
diff --git a/internal/integration_tests/resend_verify_email_test.go b/internal/integration_tests/resend_verify_email_test.go
new file mode 100644
index 000000000..34fbe6f5c
--- /dev/null
+++ b/internal/integration_tests/resend_verify_email_test.go
@@ -0,0 +1,80 @@
+package integration_tests
+
+import (
+ "testing"
+
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/google/uuid"
+ "github.com/stretchr/testify/assert"
+)
+
+// TestResendVerifyEmail tests the resend verify email functionality
+func TestResendVerifyEmail(t *testing.T) {
+ cfg := getTestConfig()
+ cfg.IsEmailServiceEnabled = true
+ cfg.EnableEmailVerification = true
+ ts := initTestSetup(t, cfg)
+ _, ctx := createContext(ts)
+
+ // Create a test user
+ email := "resend_verify_email_test_" + uuid.New().String() + "@authorizer.dev"
+ password := "Password@123"
+ // Signup the user
+ signupReq := &model.SignUpRequest{
+ Email: &email,
+ Password: password,
+ ConfirmPassword: password,
+ }
+
+ signupRes, err := ts.GraphQLProvider.SignUp(ctx, signupReq)
+ assert.NoError(t, err)
+ assert.NotNil(t, signupRes)
+ // Expect the user to be nil, as the email is not verified yet
+ assert.Nil(t, signupRes.User)
+
+ t.Run("should fail for invalid token", func(t *testing.T) {
+ verificationReq := &model.VerifyEmailRequest{
+ Token: "invalid-token",
+ }
+ verificationRes, err := ts.GraphQLProvider.VerifyEmail(ctx, verificationReq)
+ assert.Error(t, err)
+ assert.Nil(t, verificationRes)
+ })
+
+ t.Run("should resend verify email", func(t *testing.T) {
+ // Get the verification token from db
+ request, err := ts.StorageProvider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeBasicAuthSignup)
+ assert.NoError(t, err)
+ assert.NotNil(t, request)
+ assert.NotEmpty(t, request.Token)
+
+ // Verify email with an invalid token
+ verificationReq := &model.ResendVerifyEmailRequest{
+ Email: email,
+ Identifier: constants.VerificationTypeBasicAuthSignup,
+ }
+
+ res, err := ts.GraphQLProvider.ResendVerifyEmail(ctx, verificationReq)
+ assert.NoError(t, err)
+ assert.NotNil(t, res)
+
+ // Check if the verification request has different token
+ request2, err := ts.StorageProvider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeBasicAuthSignup)
+ assert.NoError(t, err)
+ assert.NotNil(t, request2)
+ assert.NotEmpty(t, request2.Token)
+ assert.NotEqual(t, request.Token, request2.Token)
+
+ // Verify email with the new token
+ verificationReq2 := &model.VerifyEmailRequest{
+ Token: request2.Token,
+ }
+ verificationRes, err := ts.GraphQLProvider.VerifyEmail(ctx, verificationReq2)
+ assert.NoError(t, err)
+ assert.NotNil(t, verificationRes)
+ assert.NotNil(t, verificationRes.User)
+ assert.Equal(t, email, *verificationRes.User.Email)
+ assert.Equal(t, true, verificationRes.User.EmailVerified)
+ })
+}
diff --git a/internal/integration_tests/reset_password_test.go b/internal/integration_tests/reset_password_test.go
new file mode 100644
index 000000000..8db617353
--- /dev/null
+++ b/internal/integration_tests/reset_password_test.go
@@ -0,0 +1,84 @@
+package integration_tests
+
+import (
+ "testing"
+
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/refs"
+ "github.com/google/uuid"
+ "github.com/stretchr/testify/assert"
+)
+
+// TestResetPassword tests the reset password functionality
+func TestResetPassword(t *testing.T) {
+ cfg := getTestConfig()
+ ts := initTestSetup(t, cfg)
+ _, ctx := createContext(ts)
+
+ // Create a test user
+ email := "reset_password_test_" + uuid.New().String() + "@authorizer.dev"
+ password := "Password@123"
+ // Signup the user
+ signupReq := &model.SignUpRequest{
+ Email: &email,
+ Password: password,
+ ConfirmPassword: password,
+ }
+
+ signupRes, err := ts.GraphQLProvider.SignUp(ctx, signupReq)
+ assert.NoError(t, err)
+ assert.NotNil(t, signupRes)
+ assert.NotNil(t, signupRes.User)
+
+ // Create forgot password request
+ t.Run("should fail for invalid request", func(t *testing.T) {
+ resetPasswordReq := &model.ResetPasswordRequest{
+ Token: refs.NewStringRef("test"),
+ Password: "NewPassword@123",
+ ConfirmPassword: "NewPassword@123",
+ }
+ forgotPasswordRes, err := ts.GraphQLProvider.ResetPassword(ctx, resetPasswordReq)
+ assert.Error(t, err)
+ assert.Nil(t, forgotPasswordRes)
+ })
+
+ t.Run("should reset password with verification token", func(t *testing.T) {
+ forgotPasswordReq := &model.ForgotPasswordRequest{
+ Email: refs.NewStringRef(email),
+ }
+ forgotPasswordRes, err := ts.GraphQLProvider.ForgotPassword(ctx, forgotPasswordReq)
+ assert.NoError(t, err)
+ assert.NotNil(t, forgotPasswordRes)
+ assert.NotEmpty(t, forgotPasswordRes.Message)
+
+ // Validate if the entry is created in db
+ request, err := ts.StorageProvider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeForgotPassword)
+ assert.NoError(t, err)
+ assert.NotNil(t, request)
+ assert.NotEmpty(t, request.Token)
+ assert.Equal(t, email, request.Email)
+
+ // Reset password using the token
+ resetPasswordReq := &model.ResetPasswordRequest{
+ Token: refs.NewStringRef(request.Token),
+ Password: "NewPassword@123",
+ ConfirmPassword: "NewPassword@123",
+ }
+
+ resetPasswordRes, err := ts.GraphQLProvider.ResetPassword(ctx, resetPasswordReq)
+ assert.NoError(t, err)
+ assert.NotNil(t, resetPasswordRes)
+ assert.NotEmpty(t, resetPasswordRes.Message)
+
+ // Validate if the password is updated in db by logging in
+ loginReq := &model.LoginRequest{
+ Email: &email,
+ Password: "NewPassword@123",
+ }
+ loginRes, err := ts.GraphQLProvider.Login(ctx, loginReq)
+ assert.NoError(t, err)
+ assert.NotNil(t, loginRes)
+ assert.NotNil(t, loginRes.AccessToken)
+ })
+}
diff --git a/internal/integration_tests/revoke_access_test.go b/internal/integration_tests/revoke_access_test.go
new file mode 100644
index 000000000..be7d06534
--- /dev/null
+++ b/internal/integration_tests/revoke_access_test.go
@@ -0,0 +1,76 @@
+package integration_tests
+
+import (
+ "fmt"
+ "testing"
+
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/crypto"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/google/uuid"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+// TestRevokeAccessUser tests the revoke access functionality by the admin
+func TestRevokeAccessUser(t *testing.T) {
+ cfg := getTestConfig()
+ ts := initTestSetup(t, cfg)
+ req, ctx := createContext(ts)
+
+ // Create a test user
+ email := "revoke_access_test_" + uuid.New().String() + "@authorizer.dev"
+ password := "Password@123"
+ // Signup the user
+ signupReq := &model.SignUpRequest{
+ Email: &email,
+ Password: password,
+ ConfirmPassword: password,
+ }
+ signupRes, err := ts.GraphQLProvider.SignUp(ctx, signupReq)
+ require.NoError(t, err)
+ require.NotNil(t, signupRes)
+ require.NotNil(t, signupRes.User)
+
+ t.Run("should fail without admin cookie", func(t *testing.T) {
+ revokeAccessDets, err := ts.GraphQLProvider.RevokeAccess(ctx, &model.UpdateAccessRequest{
+ UserID: signupRes.User.ID,
+ })
+ require.Error(t, err)
+ require.Nil(t, revokeAccessDets)
+ })
+
+ t.Run("should fail with blank userid", func(t *testing.T) {
+ h, err := crypto.EncryptPassword(cfg.AdminSecret)
+ assert.Nil(t, err)
+
+ req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
+ _, err = ts.GraphQLProvider.RevokeAccess(ctx, &model.UpdateAccessRequest{
+ UserID: "",
+ })
+ require.Error(t, err)
+ })
+
+ t.Run("should fail with unknown userid", func(t *testing.T) {
+ h, err := crypto.EncryptPassword(cfg.AdminSecret)
+ assert.Nil(t, err)
+
+ req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
+ _, err = ts.GraphQLProvider.RevokeAccess(ctx, &model.UpdateAccessRequest{
+ UserID: uuid.NewString(),
+ })
+ require.Error(t, err)
+ })
+
+ t.Run("should revoke access", func(t *testing.T) {
+ h, err := crypto.EncryptPassword(cfg.AdminSecret)
+ assert.Nil(t, err)
+
+ req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
+ revokeAccessDets, err := ts.GraphQLProvider.RevokeAccess(ctx, &model.UpdateAccessRequest{
+ UserID: signupRes.User.ID,
+ })
+ require.NoError(t, err)
+ assert.NotNil(t, revokeAccessDets)
+ })
+}
diff --git a/internal/integration_tests/revoke_test.go b/internal/integration_tests/revoke_test.go
new file mode 100644
index 000000000..f7db4eab3
--- /dev/null
+++ b/internal/integration_tests/revoke_test.go
@@ -0,0 +1,67 @@
+package integration_tests
+
+import (
+ "testing"
+
+ "github.com/google/uuid"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+)
+
+// TestRevoke tests the revoke functionality
+func TestRevoke(t *testing.T) {
+ cfg := getTestConfig()
+ ts := initTestSetup(t, cfg)
+ _, ctx := createContext(ts)
+
+ // Create a test user
+ email := "revoke_test_" + uuid.New().String() + "@authorizer.dev"
+ password := "Password@123"
+ // Signup the user
+ signupReq := &model.SignUpRequest{
+ Email: &email,
+ Password: password,
+ ConfirmPassword: password,
+ }
+
+ signupRes, err := ts.GraphQLProvider.SignUp(ctx, signupReq)
+ assert.NoError(t, err)
+ assert.NotNil(t, signupRes)
+ assert.NotNil(t, signupRes.User)
+
+ // Create forgot password request
+ t.Run("should fail for invalid session", func(t *testing.T) {
+ revokeReq := &model.OAuthRevokeRequest{
+ RefreshToken: "invalid_token",
+ }
+ revokeRes, err := ts.GraphQLProvider.Revoke(ctx, revokeReq)
+ assert.Error(t, err)
+ assert.Nil(t, revokeRes)
+ })
+
+ t.Run("should revoke", func(t *testing.T) {
+ // Login request
+ loginReq := &model.LoginRequest{
+ Email: &email,
+ Password: password,
+ Scope: []string{"offline_access"},
+ }
+ loginRes, err := ts.GraphQLProvider.Login(ctx, loginReq)
+ assert.NoError(t, err)
+ assert.NotNil(t, loginRes)
+ assert.NotEmpty(t, loginRes.RefreshToken)
+ assert.NotEmpty(t, loginRes.AccessToken)
+
+ // Revoke refresh token
+ revokeReq := &model.OAuthRevokeRequest{
+ RefreshToken: *loginRes.RefreshToken,
+ }
+
+ revokeRes, err := ts.GraphQLProvider.Revoke(ctx, revokeReq)
+ require.NoError(t, err)
+ assert.NotNil(t, revokeRes)
+ assert.NotEmpty(t, revokeRes.Message)
+ })
+}
diff --git a/internal/integration_tests/session_test.go b/internal/integration_tests/session_test.go
new file mode 100644
index 000000000..6615b3a9b
--- /dev/null
+++ b/internal/integration_tests/session_test.go
@@ -0,0 +1,76 @@
+package integration_tests
+
+import (
+ "fmt"
+ "strings"
+ "testing"
+
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/google/uuid"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+// TestSession tests the session functionality
+func TestSession(t *testing.T) {
+ // Initialize test setup
+ cfg := getTestConfig()
+ ts := initTestSetup(t, cfg)
+ req, ctx := createContext(ts)
+
+ // Test setup - create a test user
+ email := "session_test_" + uuid.New().String() + "@authorizer.dev"
+ password := "Password@123"
+
+ signupReq := &model.SignUpRequest{
+ Email: &email,
+ Password: password,
+ ConfirmPassword: password,
+ }
+ res, err := ts.GraphQLProvider.SignUp(ctx, signupReq)
+ assert.NoError(t, err)
+ assert.NotNil(t, res)
+
+ // Session tests
+ t.Run("after login", func(t *testing.T) {
+ loginReq := &model.LoginRequest{
+ Email: &email,
+ Password: password,
+ }
+ loginRes, err := ts.GraphQLProvider.Login(ctx, loginReq)
+ assert.NoError(t, err)
+ assert.NotNil(t, loginRes)
+
+ // Verify response contains expected tokens
+ assert.NotEmpty(t, loginRes.AccessToken)
+ assert.NotNil(t, loginRes.User)
+ assert.Equal(t, email, *loginRes.User.Email)
+ assert.True(t, loginRes.User.EmailVerified)
+
+ t.Run("should fail without cookie", func(t *testing.T) {
+ res, err := ts.GraphQLProvider.Session(ctx, &model.SessionQueryRequest{})
+ assert.Error(t, err)
+ assert.Nil(t, res)
+ })
+
+ t.Run("should return new access token with cookie", func(t *testing.T) {
+ allData, err := ts.MemoryStoreProvider.GetAllData()
+ require.NoError(t, err)
+ sessionToken := ""
+ for k, v := range allData {
+ if strings.Contains(k, constants.TokenTypeSessionToken) {
+ sessionToken = v
+ break
+ }
+ }
+ req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AppCookieName+"_session", sessionToken))
+ res, err := ts.GraphQLProvider.Session(ctx, &model.SessionQueryRequest{})
+ require.NoError(t, err)
+ require.NotNil(t, res)
+ assert.NotEmpty(t, res.AccessToken)
+ assert.NotEqual(t, res.AccessToken, res.RefreshToken)
+ assert.Equal(t, email, *res.User.Email)
+ })
+ })
+}
diff --git a/internal/integration_tests/signup_test.go b/internal/integration_tests/signup_test.go
new file mode 100644
index 000000000..e3515b656
--- /dev/null
+++ b/internal/integration_tests/signup_test.go
@@ -0,0 +1,141 @@
+package integration_tests
+
+import (
+ "fmt"
+ "testing"
+ "time"
+
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/google/uuid"
+ "github.com/stretchr/testify/assert"
+)
+
+// TestSignup tests the signup functionality of the Authorizer application.
+func TestSignup(t *testing.T) {
+ cfg := getTestConfig()
+ ts := initTestSetup(t, cfg)
+ _, ctx := createContext(ts)
+
+ email := "signup_test_" + uuid.New().String() + "@authorizer.dev"
+ password := "Password@123"
+
+ t.Run("should fail for missing email or phone number", func(t *testing.T) {
+ signupReq := &model.SignUpRequest{
+ Password: password,
+ }
+ res, err := ts.GraphQLProvider.SignUp(ctx, signupReq)
+ assert.Error(t, err)
+ assert.Nil(t, res)
+ })
+
+ t.Run("should fail for missing confirm password", func(t *testing.T) {
+ signupReq := &model.SignUpRequest{
+ Email: &email,
+ Password: password,
+ }
+
+ res, err := ts.GraphQLProvider.SignUp(ctx, signupReq)
+ assert.Error(t, err)
+ assert.Nil(t, res)
+ })
+
+ t.Run("should fail for mismatch confirm password", func(t *testing.T) {
+ signupReq := &model.SignUpRequest{
+ Email: &email,
+ Password: password,
+ ConfirmPassword: "test@123",
+ }
+
+ res, err := ts.GraphQLProvider.SignUp(ctx, signupReq)
+ assert.Error(t, err)
+ assert.Nil(t, res)
+ })
+
+ t.Run("should fail for weak password", func(t *testing.T) {
+ signupReq := &model.SignUpRequest{
+ Email: &email,
+ Password: "test",
+ ConfirmPassword: "test",
+ }
+
+ res, err := ts.GraphQLProvider.SignUp(ctx, signupReq)
+ assert.Error(t, err)
+ assert.Nil(t, res)
+ })
+
+ t.Run("should fail for invalid email", func(t *testing.T) {
+ invalidEmail := "test"
+ signupReq := &model.SignUpRequest{
+ Email: &invalidEmail,
+ Password: password,
+ ConfirmPassword: password,
+ }
+ res, err := ts.GraphQLProvider.SignUp(ctx, signupReq)
+ assert.Error(t, err)
+ assert.Nil(t, res)
+ })
+
+ t.Run("should fail for invalid mobile number", func(t *testing.T) {
+ invalidMobileNumber := "1243234"
+ signupReq := &model.SignUpRequest{
+ PhoneNumber: &invalidMobileNumber,
+ Password: password,
+ ConfirmPassword: password,
+ }
+ res, err := ts.GraphQLProvider.SignUp(ctx, signupReq)
+ assert.Error(t, err)
+ assert.Nil(t, res)
+ })
+
+ t.Run("should pass for valid email", func(t *testing.T) {
+ signupReq := &model.SignUpRequest{
+ Email: &email,
+ Password: password,
+ ConfirmPassword: password,
+ }
+ res, err := ts.GraphQLProvider.SignUp(ctx, signupReq)
+ assert.NoError(t, err)
+ assert.NotNil(t, res)
+ assert.NotNil(t, res.User)
+
+ t.Run("should fail for duplicate email", func(t *testing.T) {
+ signupReq := &model.SignUpRequest{
+ Email: &email,
+ Password: password,
+ ConfirmPassword: password,
+ }
+ res, err := ts.GraphQLProvider.SignUp(ctx, signupReq)
+ assert.Error(t, err)
+ assert.Nil(t, res)
+ })
+ })
+
+ t.Run("should pass for valid mobile number", func(t *testing.T) {
+ mobileNumber := fmt.Sprintf("%d", time.Now().Unix())
+ signupReq := &model.SignUpRequest{
+ PhoneNumber: &mobileNumber,
+ Password: password,
+ ConfirmPassword: password,
+ }
+ res, err := ts.GraphQLProvider.SignUp(ctx, signupReq)
+ assert.NoError(t, err)
+ assert.NotNil(t, res)
+ // Validate mobile number
+ assert.Equal(t, mobileNumber, *res.User.PhoneNumber)
+ assert.True(t, res.User.PhoneNumberVerified)
+ // Auth formula should be basic auth based on mobile number
+ assert.Contains(t, constants.AuthRecipeMethodMobileBasicAuth, res.User.SignupMethods)
+
+ t.Run("should fail for duplicate mobile number", func(t *testing.T) {
+ signupReq := &model.SignUpRequest{
+ PhoneNumber: &mobileNumber,
+ Password: password,
+ ConfirmPassword: password,
+ }
+ res, err := ts.GraphQLProvider.SignUp(ctx, signupReq)
+ assert.Error(t, err)
+ assert.Nil(t, res)
+ })
+ })
+}
diff --git a/internal/integration_tests/test_endpoint_test.go b/internal/integration_tests/test_endpoint_test.go
new file mode 100644
index 000000000..1c77bc00e
--- /dev/null
+++ b/internal/integration_tests/test_endpoint_test.go
@@ -0,0 +1,223 @@
+package integration_tests
+
+import (
+ "encoding/json"
+ "fmt"
+ "net/http"
+ "net/http/httptest"
+ "testing"
+ "time"
+
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/crypto"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/google/uuid"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+// TestEndpointTest tests the webhook endpoint testing functionality by the admin
+func TestEndpointTest(t *testing.T) {
+ cfg := getTestConfig()
+ ts := initTestSetup(t, cfg)
+ req, ctx := createContext(ts)
+
+ // Create a test user
+ email := "test_endpoint_user_" + uuid.New().String() + "@authorizer.dev"
+ password := "Password@123"
+
+ // Signup the user
+ signupReq := &model.SignUpRequest{
+ Email: &email,
+ Password: password,
+ ConfirmPassword: password,
+ }
+ signupRes, err := ts.GraphQLProvider.SignUp(ctx, signupReq)
+ require.NoError(t, err)
+ require.NotNil(t, signupRes)
+ require.NotNil(t, signupRes.User)
+
+ // Create a test server to simulate a webhook endpoint
+ var lastReceivedRequest struct {
+ EventName string
+ Headers map[string]string
+ }
+
+ testServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ // Clear the previous request data
+ lastReceivedRequest = struct {
+ EventName string
+ Headers map[string]string
+ }{
+ Headers: make(map[string]string),
+ }
+
+ // Read request body
+ decoder := json.NewDecoder(r.Body)
+ var requestData map[string]interface{}
+ err := decoder.Decode(&requestData)
+ if err != nil {
+ w.WriteHeader(http.StatusBadRequest)
+ w.Write([]byte(`{"error":"invalid request body"}`))
+ return
+ }
+
+ // Capture the received event name and headers for test validation
+ if eventName, ok := requestData["event_name"].(string); ok {
+ lastReceivedRequest.EventName = eventName
+ }
+
+ // Capture headers
+ for k, v := range r.Header {
+ if len(v) > 0 {
+ lastReceivedRequest.Headers[k] = v[0]
+ }
+ }
+
+ // Send appropriate response
+ w.Header().Set("Content-Type", "application/json")
+ w.WriteHeader(http.StatusOK)
+ response := fmt.Sprintf(`{"received_event":"%s","custom_header":"%s"}`,
+ lastReceivedRequest.EventName, r.Header.Get("X-Custom-Header"))
+ w.Write([]byte(response))
+ }))
+ defer testServer.Close()
+
+ t.Run("should fail without admin cookie", func(t *testing.T) {
+ // Attempt to test endpoint without admin authentication
+ params := &model.TestEndpointRequest{
+ Endpoint: testServer.URL,
+ EventName: constants.UserLoginWebhookEvent,
+ Headers: map[string]interface{}{
+ "X-Custom-Header": "test-value",
+ },
+ }
+
+ resp, err := ts.GraphQLProvider.TestEndpoint(ctx, params)
+ require.Error(t, err)
+ require.Nil(t, resp)
+ assert.Contains(t, err.Error(), "unauthorized")
+ })
+
+ // Add admin cookie for the rest of the tests
+ h, err := crypto.EncryptPassword(cfg.AdminSecret)
+ assert.Nil(t, err)
+ req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
+
+ t.Run("should fail with invalid event name", func(t *testing.T) {
+ params := &model.TestEndpointRequest{
+ Endpoint: testServer.URL,
+ EventName: "invalid_event_name",
+ Headers: map[string]interface{}{},
+ }
+
+ resp, err := ts.GraphQLProvider.TestEndpoint(ctx, params)
+ require.Error(t, err)
+ require.Nil(t, resp)
+ assert.Contains(t, err.Error(), "invalid event_name")
+ })
+
+ t.Run("should successfully test endpoint with login event", func(t *testing.T) {
+ // Clear previous request data
+ lastReceivedRequest.EventName = ""
+ lastReceivedRequest.Headers = make(map[string]string)
+
+ params := &model.TestEndpointRequest{
+ Endpoint: testServer.URL,
+ EventName: constants.UserLoginWebhookEvent,
+ Headers: map[string]interface{}{
+ "X-Custom-Header": "test-login-event",
+ "Content-Type": "application/json",
+ },
+ }
+
+ resp, err := ts.GraphQLProvider.TestEndpoint(ctx, params)
+ require.NoError(t, err)
+ require.NotNil(t, resp)
+
+ // Wait a moment for the request to be processed by our test server
+ time.Sleep(50 * time.Millisecond)
+
+ // Verify HTTP status
+ require.NotNil(t, resp.HTTPStatus)
+ assert.Equal(t, int64(http.StatusOK), *resp.HTTPStatus)
+
+ // Verify the received event name from the test server
+ assert.Equal(t, constants.UserLoginWebhookEvent, lastReceivedRequest.EventName)
+
+ // Verify response body
+ require.NotNil(t, resp.Response)
+ responseBody := *resp.Response
+
+ // Parse response JSON
+ var respData map[string]interface{}
+ err = json.Unmarshal([]byte(responseBody), &respData)
+ require.NoError(t, err)
+
+ assert.Equal(t, constants.UserLoginWebhookEvent, respData["received_event"])
+ assert.Equal(t, "test-login-event", respData["custom_header"])
+ })
+
+ t.Run("should successfully test endpoint with user created event", func(t *testing.T) {
+ // Clear previous request data
+ lastReceivedRequest.EventName = ""
+ lastReceivedRequest.Headers = make(map[string]string)
+
+ // Create a separate test server for user created event
+ userCreatedServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ decoder := json.NewDecoder(r.Body)
+ var requestData map[string]interface{}
+ decoder.Decode(&requestData)
+
+ eventName := requestData["event_name"].(string)
+ customHeader := r.Header.Get("X-Custom-Header")
+
+ w.Header().Set("Content-Type", "application/json")
+ w.WriteHeader(http.StatusOK)
+ response := fmt.Sprintf(`{"received_event":"%s","custom_header":"%s"}`,
+ eventName, customHeader)
+ w.Write([]byte(response))
+ }))
+ defer userCreatedServer.Close()
+
+ params := &model.TestEndpointRequest{
+ Endpoint: userCreatedServer.URL,
+ EventName: constants.UserLoginWebhookEvent,
+ Headers: map[string]interface{}{
+ "X-Custom-Header": "test-user-login-event",
+ },
+ }
+
+ resp, err := ts.GraphQLProvider.TestEndpoint(ctx, params)
+ require.NoError(t, err)
+ require.NotNil(t, resp)
+
+ // Verify HTTP status
+ require.NotNil(t, resp.HTTPStatus)
+ assert.Equal(t, int64(http.StatusOK), *resp.HTTPStatus)
+
+ // Verify response body directly
+ require.NotNil(t, resp.Response)
+ responseBody := *resp.Response
+
+ // Parse response JSON
+ var respData map[string]interface{}
+ err = json.Unmarshal([]byte(responseBody), &respData)
+ require.NoError(t, err)
+
+ assert.Equal(t, constants.UserLoginWebhookEvent, respData["received_event"])
+ assert.Equal(t, "test-user-login-event", respData["custom_header"])
+ })
+
+ t.Run("should handle endpoint that doesn't exist", func(t *testing.T) {
+ params := &model.TestEndpointRequest{
+ Endpoint: "http://non-existent-endpoint.example",
+ EventName: constants.UserLoginWebhookEvent,
+ Headers: map[string]interface{}{},
+ }
+
+ resp, err := ts.GraphQLProvider.TestEndpoint(ctx, params)
+ require.Error(t, err)
+ require.Nil(t, resp)
+ })
+}
diff --git a/internal/integration_tests/test_helper.go b/internal/integration_tests/test_helper.go
new file mode 100644
index 000000000..1ba2db0b0
--- /dev/null
+++ b/internal/integration_tests/test_helper.go
@@ -0,0 +1,176 @@
+package integration_tests
+
+import (
+ "context"
+ "net/http"
+ "net/http/httptest"
+ "testing"
+
+ "github.com/gin-gonic/gin"
+ "github.com/rs/zerolog"
+ "github.com/stretchr/testify/require"
+
+ "github.com/authorizerdev/authorizer/internal/authenticators"
+ "github.com/authorizerdev/authorizer/internal/config"
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/email"
+ "github.com/authorizerdev/authorizer/internal/events"
+ "github.com/authorizerdev/authorizer/internal/graphql"
+ "github.com/authorizerdev/authorizer/internal/http_handlers"
+ "github.com/authorizerdev/authorizer/internal/memory_store"
+ "github.com/authorizerdev/authorizer/internal/sms"
+ "github.com/authorizerdev/authorizer/internal/storage"
+ "github.com/authorizerdev/authorizer/internal/token"
+)
+
+// testSetup represents the test setup
+type testSetup struct {
+ GraphQLProvider graphql.Provider
+ HttpProvider http_handlers.Provider
+ HttpServer *httptest.Server
+ Config *config.Config
+ Logger *zerolog.Logger
+ GinContext *gin.Context
+ // Used for specific tests where we need to access the storage
+ StorageProvider storage.Provider
+ MemoryStoreProvider memory_store.Provider
+}
+
+func createContext(s *testSetup) (*http.Request, context.Context) {
+ req, _ := http.NewRequest(
+ "POST",
+ "http://"+s.HttpServer.Listener.Addr().String()+"/graphql",
+ nil,
+ )
+
+ ctx := context.WithValue(req.Context(), "GinContextKey", s.GinContext)
+ s.GinContext.Request = req
+ return req, ctx
+}
+
+func getTestConfig() *config.Config {
+ // Initialize config with test settings
+ cfg := &config.Config{
+ Env: constants.TestEnv,
+ DatabaseType: constants.DbTypePostgres,
+ DatabaseURL: "postgres://postgres:postgres@localhost:5432/postgres",
+ JWTSecret: "test-secret",
+ ClientID: "test-client-id",
+ ClientSecret: "test-client-secret",
+ AllowedOrigins: []string{"http://localhost:3000"},
+ JWTType: "HS256",
+ AdminSecret: "test-admin-secret",
+ TwilioAPISecret: "test-twilio-api-secret",
+ TwilioAPIKey: "test-twilio-api-key",
+ TwilioAccountSID: "test-twilio-account-sid",
+ TwilioSender: "test-twilio-sender",
+ DefaultRoles: []string{"user"},
+ EnableSignup: true,
+ EnableBasicAuthentication: true,
+ EnableMobileBasicAuthentication: true,
+ EnableLoginPage: true,
+ EnableStrongPassword: true,
+ IsSMSServiceEnabled: true,
+ }
+
+ return cfg
+}
+
+// initTestSetup initializes the test setup
+func initTestSetup(t *testing.T, cfg *config.Config) *testSetup {
+ // Initialize logger
+ logger := zerolog.New(zerolog.NewTestWriter(t)).With().Timestamp().Logger()
+
+ // Initialize storage provider first as it's required by other providers
+ storageProvider, err := storage.New(cfg, &storage.Dependencies{
+ Log: &logger,
+ })
+ require.NoError(t, err)
+
+ // Initialize other providers
+ authProvider, err := authenticators.New(cfg, &authenticators.Dependencies{
+ Log: &logger,
+ StorageProvider: storageProvider,
+ })
+ require.NoError(t, err)
+
+ emailProvider, err := email.New(cfg, &email.Dependencies{
+ Log: &logger,
+ StorageProvider: storageProvider,
+ })
+ require.NoError(t, err)
+
+ eventsProvider, err := events.New(cfg, &events.Dependencies{
+ Log: &logger,
+ StorageProvider: storageProvider,
+ })
+ require.NoError(t, err)
+
+ memoryStoreProvider, err := memory_store.New(cfg, &memory_store.Dependencies{
+ Log: &logger,
+ })
+ require.NoError(t, err)
+
+ smsProvider, err := sms.New(cfg, &sms.Dependencies{
+ Log: &logger,
+ })
+ require.NoError(t, err)
+
+ tokenProvider, err := token.New(cfg, &token.Dependencies{
+ Log: &logger,
+ MemoryStoreProvider: memoryStoreProvider,
+ })
+ require.NoError(t, err)
+
+ // Create dependencies struct
+ gqlDeps := &graphql.Dependencies{
+ Log: &logger,
+ AuthenticatorProvider: authProvider,
+ EmailProvider: emailProvider,
+ EventsProvider: eventsProvider,
+ MemoryStoreProvider: memoryStoreProvider,
+ SMSProvider: smsProvider,
+ StorageProvider: storageProvider,
+ TokenProvider: tokenProvider,
+ }
+
+ // Create dependencies struct
+ httpDeps := &http_handlers.Dependencies{
+ Log: &logger,
+ AuthenticatorProvider: authProvider,
+ EmailProvider: emailProvider,
+ EventsProvider: eventsProvider,
+ MemoryStoreProvider: memoryStoreProvider,
+ SMSProvider: smsProvider,
+ StorageProvider: storageProvider,
+ TokenProvider: tokenProvider,
+ }
+
+ // Create GraphQL provider
+ gqlProvider, err := graphql.New(cfg, gqlDeps)
+ require.NoError(t, err)
+
+ // Create HTTP provider
+ httpProvider, err := http_handlers.New(cfg, httpDeps)
+ require.NoError(t, err)
+
+ w := httptest.NewRecorder()
+ ctx, r := gin.CreateTestContext(w)
+ r.Use(httpProvider.CORSMiddleware())
+ r.Use(httpProvider.ContextMiddleware())
+ r.Use(httpProvider.LoggerMiddleware())
+
+ r.POST("/graphql", httpProvider.GraphqlHandler())
+
+ server := httptest.NewServer(r)
+
+ return &testSetup{
+ GraphQLProvider: gqlProvider,
+ HttpProvider: httpProvider,
+ HttpServer: server,
+ Logger: &logger,
+ GinContext: ctx,
+ StorageProvider: storageProvider,
+ MemoryStoreProvider: memoryStoreProvider,
+ }
+}
diff --git a/internal/integration_tests/update_email_template_test.go b/internal/integration_tests/update_email_template_test.go
new file mode 100644
index 000000000..4047cb25a
--- /dev/null
+++ b/internal/integration_tests/update_email_template_test.go
@@ -0,0 +1,248 @@
+package integration_tests
+
+import (
+ "fmt"
+ "testing"
+
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/crypto"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/refs"
+ "github.com/google/uuid"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+// TestUpdateEmailTemplate tests the update email template functionality by the admin
+func TestUpdateEmailTemplate(t *testing.T) {
+ cfg := getTestConfig()
+ ts := initTestSetup(t, cfg)
+ req, ctx := createContext(ts)
+
+ // Create a test user
+ email := "update_email_template_test_" + uuid.New().String() + "@authorizer.dev"
+ password := "Password@123"
+
+ // Signup the user
+ signupReq := &model.SignUpRequest{
+ Email: &email,
+ Password: password,
+ ConfirmPassword: password,
+ }
+ signupRes, err := ts.GraphQLProvider.SignUp(ctx, signupReq)
+ require.NoError(t, err)
+ require.NotNil(t, signupRes)
+
+ // Test without admin cookie first
+ t.Run("should fail without admin cookie", func(t *testing.T) {
+ updateParams := &model.UpdateEmailTemplateRequest{
+ ID: "some-id",
+ Subject: refs.NewStringRef("Updated Subject"),
+ Template: refs.NewStringRef("Updated Template"),
+ }
+
+ resp, err := ts.GraphQLProvider.UpdateEmailTemplate(ctx, updateParams)
+ require.Error(t, err)
+ require.Nil(t, resp)
+ assert.Contains(t, err.Error(), "unauthorized")
+ })
+
+ // Add admin cookie for the rest of the tests
+ h, err := crypto.EncryptPassword(cfg.AdminSecret)
+ assert.Nil(t, err)
+ req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
+
+ t.Run("should fail for non-existent template", func(t *testing.T) {
+ nonExistentID := uuid.New().String()
+ updateParams := &model.UpdateEmailTemplateRequest{
+ ID: nonExistentID,
+ Subject: refs.NewStringRef("Updated Subject"),
+ Template: refs.NewStringRef("Updated Template"),
+ }
+
+ resp, err := ts.GraphQLProvider.UpdateEmailTemplate(ctx, updateParams)
+ require.Error(t, err)
+ require.Nil(t, resp)
+ // The error message may vary depending on the storage implementation
+ assert.NotEmpty(t, err.Error())
+ })
+
+ // First create a template to test updating
+ var templateID string
+ t.Run("setup - create template for updating", func(t *testing.T) {
+ // Clean up any existing template
+ existingTemplate, err := ts.StorageProvider.GetEmailTemplateByEventName(ctx, constants.VerificationTypeForgotPassword)
+ if err == nil && existingTemplate != nil {
+ err = ts.StorageProvider.DeleteEmailTemplate(ctx, existingTemplate)
+ require.NoError(t, err)
+ }
+
+ // Create a new template
+ addParams := &model.AddEmailTemplateRequest{
+ EventName: constants.VerificationTypeForgotPassword,
+ Subject: "Reset Your Password",
+ Template: "Click here to reset your password: {{.URL}}",
+ Design: refs.NewStringRef("original design"),
+ }
+
+ resp, err := ts.GraphQLProvider.AddEmailTemplate(ctx, addParams)
+ require.NoError(t, err)
+ require.NotNil(t, resp)
+
+ // Get the created template to get its ID
+ template, err := ts.StorageProvider.GetEmailTemplateByEventName(ctx, constants.VerificationTypeForgotPassword)
+ require.NoError(t, err)
+ require.NotNil(t, template)
+ templateID = template.ID
+ })
+
+ t.Run("should update subject", func(t *testing.T) {
+ updateParams := &model.UpdateEmailTemplateRequest{
+ ID: templateID,
+ Subject: refs.NewStringRef("Updated Reset Password Subject"),
+ }
+
+ resp, err := ts.GraphQLProvider.UpdateEmailTemplate(ctx, updateParams)
+ require.NoError(t, err)
+ require.NotNil(t, resp)
+ assert.Contains(t, resp.Message, "Email template updated successfully")
+
+ // Verify the template was updated
+ template, err := ts.StorageProvider.GetEmailTemplateByID(ctx, templateID)
+ require.NoError(t, err)
+ require.NotNil(t, template)
+ assert.Equal(t, *updateParams.Subject, template.Subject)
+ assert.Equal(t, constants.VerificationTypeForgotPassword, template.EventName) // Event name unchanged
+ })
+
+ t.Run("should update template content", func(t *testing.T) {
+ updateParams := &model.UpdateEmailTemplateRequest{
+ ID: templateID,
+ Template: refs.NewStringRef("New content for password reset: {{.URL}} - {{.AppName}}"),
+ }
+
+ resp, err := ts.GraphQLProvider.UpdateEmailTemplate(ctx, updateParams)
+ require.NoError(t, err)
+ require.NotNil(t, resp)
+ assert.Contains(t, resp.Message, "Email template updated successfully")
+
+ // Verify the template was updated
+ template, err := ts.StorageProvider.GetEmailTemplateByID(ctx, templateID)
+ require.NoError(t, err)
+ require.NotNil(t, template)
+ assert.Equal(t, *updateParams.Template, template.Template)
+ })
+
+ t.Run("should update design", func(t *testing.T) {
+ updateParams := &model.UpdateEmailTemplateRequest{
+ ID: templateID,
+ Design: refs.NewStringRef("updated design with new styles"),
+ }
+
+ resp, err := ts.GraphQLProvider.UpdateEmailTemplate(ctx, updateParams)
+ require.NoError(t, err)
+ require.NotNil(t, resp)
+ assert.Contains(t, resp.Message, "Email template updated successfully")
+
+ // Verify the template was updated
+ template, err := ts.StorageProvider.GetEmailTemplateByID(ctx, templateID)
+ require.NoError(t, err)
+ require.NotNil(t, template)
+ assert.Equal(t, *updateParams.Design, template.Design)
+ })
+
+ t.Run("should update event name", func(t *testing.T) {
+ // First make sure the target event name doesn't exist yet
+ existingTemplate, err := ts.StorageProvider.GetEmailTemplateByEventName(ctx, constants.VerificationTypeUpdateEmail)
+ if err == nil && existingTemplate != nil {
+ err = ts.StorageProvider.DeleteEmailTemplate(ctx, existingTemplate)
+ require.NoError(t, err)
+ }
+
+ updateParams := &model.UpdateEmailTemplateRequest{
+ ID: templateID,
+ EventName: refs.NewStringRef(constants.VerificationTypeUpdateEmail),
+ }
+
+ resp, err := ts.GraphQLProvider.UpdateEmailTemplate(ctx, updateParams)
+ require.NoError(t, err)
+ require.NotNil(t, resp)
+ assert.Contains(t, resp.Message, "Email template updated successfully")
+
+ // Verify the template was updated
+ template, err := ts.StorageProvider.GetEmailTemplateByID(ctx, templateID)
+ require.NoError(t, err)
+ require.NotNil(t, template)
+ assert.Equal(t, constants.VerificationTypeUpdateEmail, template.EventName)
+ })
+
+ t.Run("should fail with invalid event name", func(t *testing.T) {
+ updateParams := &model.UpdateEmailTemplateRequest{
+ ID: templateID,
+ EventName: refs.NewStringRef("invalid_event_name"),
+ }
+
+ resp, err := ts.GraphQLProvider.UpdateEmailTemplate(ctx, updateParams)
+ require.Error(t, err)
+ require.Nil(t, resp)
+ assert.Contains(t, err.Error(), "invalid event name")
+ })
+
+ t.Run("should fail with whitespace-only subject", func(t *testing.T) {
+ updateParams := &model.UpdateEmailTemplateRequest{
+ ID: templateID,
+ Subject: refs.NewStringRef(" "),
+ }
+
+ resp, err := ts.GraphQLProvider.UpdateEmailTemplate(ctx, updateParams)
+ require.Error(t, err)
+ require.Nil(t, resp)
+ assert.Contains(t, err.Error(), "empty subject not allowed")
+ })
+
+ t.Run("should fail with whitespace-only template", func(t *testing.T) {
+ updateParams := &model.UpdateEmailTemplateRequest{
+ ID: templateID,
+ Template: refs.NewStringRef(" "),
+ }
+
+ resp, err := ts.GraphQLProvider.UpdateEmailTemplate(ctx, updateParams)
+ require.Error(t, err)
+ require.Nil(t, resp)
+ assert.Contains(t, err.Error(), "empty template not allowed")
+ })
+
+ t.Run("should fail with whitespace-only design", func(t *testing.T) {
+ updateParams := &model.UpdateEmailTemplateRequest{
+ ID: templateID,
+ Design: refs.NewStringRef(" "),
+ }
+
+ resp, err := ts.GraphQLProvider.UpdateEmailTemplate(ctx, updateParams)
+ require.Error(t, err)
+ require.Nil(t, resp)
+ assert.Contains(t, err.Error(), "empty design not allowed")
+ })
+
+ t.Run("should update multiple fields at once", func(t *testing.T) {
+ updateParams := &model.UpdateEmailTemplateRequest{
+ ID: templateID,
+ Subject: refs.NewStringRef("Multi-Update Subject"),
+ Template: refs.NewStringRef("Multi-Update Template Content"),
+ Design: refs.NewStringRef("Multi-Update Design Content"),
+ }
+
+ resp, err := ts.GraphQLProvider.UpdateEmailTemplate(ctx, updateParams)
+ require.NoError(t, err)
+ require.NotNil(t, resp)
+ assert.Contains(t, resp.Message, "Email template updated successfully")
+
+ // Verify the template was updated
+ template, err := ts.StorageProvider.GetEmailTemplateByID(ctx, templateID)
+ require.NoError(t, err)
+ require.NotNil(t, template)
+ assert.Equal(t, *updateParams.Subject, template.Subject)
+ assert.Equal(t, *updateParams.Template, template.Template)
+ assert.Equal(t, *updateParams.Design, template.Design)
+ })
+}
diff --git a/internal/integration_tests/update_profile_test.go b/internal/integration_tests/update_profile_test.go
new file mode 100644
index 000000000..c79cb47da
--- /dev/null
+++ b/internal/integration_tests/update_profile_test.go
@@ -0,0 +1,171 @@
+package integration_tests
+
+import (
+ "testing"
+
+ "github.com/google/uuid"
+ "github.com/stretchr/testify/assert"
+
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/refs"
+)
+
+// TestUpdateProfile tests the update profile functionality
+// using the GraphQL API.
+// It creates a user, updates the profile, and verifies
+// the changes in the database.
+func TestUpdateProfile(t *testing.T) {
+ cfg := getTestConfig()
+ ts := initTestSetup(t, cfg)
+ _, ctx := createContext(ts)
+
+ // Create a test user
+ email := "update_profile_test_" + uuid.New().String() + "@authorizer.dev"
+ password := "Password@123"
+
+ // Signup the user
+ signupReq := &model.SignUpRequest{
+ Email: &email,
+ Password: password,
+ ConfirmPassword: password,
+ }
+ signupRes, err := ts.GraphQLProvider.SignUp(ctx, signupReq)
+ assert.NoError(t, err)
+ assert.NotNil(t, signupRes)
+ assert.Equal(t, email, *signupRes.User.Email)
+ assert.NotEmpty(t, *signupRes.AccessToken)
+
+ // Login to get fresh tokens
+ loginReq := &model.LoginRequest{
+ Email: &email,
+ Password: password,
+ }
+ loginRes, err := ts.GraphQLProvider.Login(ctx, loginReq)
+ assert.NoError(t, err)
+ assert.NotNil(t, loginRes)
+ assert.NotEmpty(t, *loginRes.AccessToken)
+
+ // Set the authorization header for authenticated requests
+ ts.GinContext.Request.Header.Set("Authorization", "Bearer "+*loginRes.AccessToken)
+
+ // Test cases
+ t.Run("should fail update profile without authentication", func(t *testing.T) {
+ // Clear authorization header
+ ts.GinContext.Request.Header.Set("Authorization", "")
+ defer func() {
+ ts.GinContext.Request.Header.Set("Authorization", "Bearer "+*loginRes.AccessToken)
+ }()
+
+ updateReq := &model.UpdateProfileRequest{
+ GivenName: refs.NewStringRef("Test"),
+ }
+ updateRes, err := ts.GraphQLProvider.UpdateProfile(ctx, updateReq)
+ assert.Error(t, err)
+ assert.Nil(t, updateRes)
+ })
+
+ t.Run("should update basic profile information", func(t *testing.T) {
+ givenName := "John"
+ familyName := "Doe"
+ nickname := "Johnny"
+ phoneNumber := "+1234567890"
+
+ updateReq := &model.UpdateProfileRequest{
+ GivenName: refs.NewStringRef(givenName),
+ FamilyName: refs.NewStringRef(familyName),
+ Nickname: refs.NewStringRef(nickname),
+ PhoneNumber: refs.NewStringRef(phoneNumber),
+ }
+
+ updateRes, err := ts.GraphQLProvider.UpdateProfile(ctx, updateReq)
+ assert.NoError(t, err)
+ assert.NotNil(t, updateRes)
+
+ // Get the profile
+ profile, err := ts.GraphQLProvider.Profile(ctx)
+ assert.NoError(t, err)
+ assert.NotNil(t, profile)
+ assert.Equal(t, givenName, *profile.GivenName)
+ assert.Equal(t, familyName, *profile.FamilyName)
+ assert.Equal(t, nickname, *profile.Nickname)
+ assert.Equal(t, phoneNumber, *profile.PhoneNumber)
+ assert.Equal(t, email, *profile.Email)
+ })
+
+ t.Run("should update profile picture", func(t *testing.T) {
+ picture := "https://example.com/profile.jpg"
+
+ updateReq := &model.UpdateProfileRequest{
+ Picture: refs.NewStringRef(picture),
+ }
+
+ updateRes, err := ts.GraphQLProvider.UpdateProfile(ctx, updateReq)
+ assert.NoError(t, err)
+ assert.NotNil(t, updateRes)
+
+ // Get the profile
+ profile, err := ts.GraphQLProvider.Profile(ctx)
+ assert.NoError(t, err)
+ assert.NotNil(t, profile)
+ assert.Equal(t, picture, *profile.Picture)
+ })
+
+ t.Run("should update gender", func(t *testing.T) {
+ gender := "male"
+
+ updateReq := &model.UpdateProfileRequest{
+ Gender: refs.NewStringRef(gender),
+ }
+
+ updateRes, err := ts.GraphQLProvider.UpdateProfile(ctx, updateReq)
+ assert.NoError(t, err)
+ assert.NotNil(t, updateRes)
+
+ // Get the profile
+ profile, err := ts.GraphQLProvider.Profile(ctx)
+ assert.NoError(t, err)
+ assert.NotNil(t, profile)
+ })
+
+ t.Run("should update birthdate", func(t *testing.T) {
+ birthdate := "1990-01-01"
+
+ updateReq := &model.UpdateProfileRequest{
+ Birthdate: refs.NewStringRef(birthdate),
+ }
+
+ updateRes, err := ts.GraphQLProvider.UpdateProfile(ctx, updateReq)
+ assert.NoError(t, err)
+ assert.NotNil(t, updateRes)
+
+ // Get the profile
+ profile, err := ts.GraphQLProvider.Profile(ctx)
+ assert.NoError(t, err)
+ assert.NotNil(t, profile)
+ assert.Equal(t, birthdate, *profile.Birthdate)
+ })
+
+ t.Run("should update multiple fields at once", func(t *testing.T) {
+ givenName := "Updated"
+ familyName := "User"
+ picture := "https://example.com/new-profile.jpg"
+
+ updateReq := &model.UpdateProfileRequest{
+ GivenName: refs.NewStringRef(givenName),
+ FamilyName: refs.NewStringRef(familyName),
+ Picture: refs.NewStringRef(picture),
+ }
+
+ updateRes, err := ts.GraphQLProvider.UpdateProfile(ctx, updateReq)
+ assert.NoError(t, err)
+ assert.NotNil(t, updateRes)
+
+ // Get the profile
+ profile, err := ts.GraphQLProvider.Profile(ctx)
+ assert.NoError(t, err)
+ assert.NotNil(t, profile)
+ assert.Equal(t, givenName, *profile.GivenName)
+ assert.Equal(t, familyName, *profile.FamilyName)
+ assert.Equal(t, picture, *profile.Picture)
+ })
+}
diff --git a/internal/integration_tests/update_user_test.go b/internal/integration_tests/update_user_test.go
new file mode 100644
index 000000000..62126231b
--- /dev/null
+++ b/internal/integration_tests/update_user_test.go
@@ -0,0 +1,57 @@
+package integration_tests
+
+import (
+ "fmt"
+ "testing"
+
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/crypto"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/google/uuid"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+// TestUpdateUser tests the update user functionality by the admin
+func TestUpdateUser(t *testing.T) {
+ cfg := getTestConfig()
+ ts := initTestSetup(t, cfg)
+ req, ctx := createContext(ts)
+
+ // Create a test user
+ email := "update_user_test_" + uuid.New().String() + "@authorizer.dev"
+ password := "Password@123"
+ // Signup the user
+ signupReq := &model.SignUpRequest{
+ Email: &email,
+ Password: password,
+ ConfirmPassword: password,
+ }
+ signupRes, err := ts.GraphQLProvider.SignUp(ctx, signupReq)
+ require.NoError(t, err)
+ require.NotNil(t, signupRes)
+ require.NotNil(t, signupRes.User)
+
+ userFirstName := "UpdatedFirstName"
+ updateReq := &model.UpdateUserRequest{
+ ID: signupRes.User.ID,
+ GivenName: &userFirstName,
+ }
+ t.Run("should fail without admin cookie", func(t *testing.T) {
+ updateRes, err := ts.GraphQLProvider.UpdateUser(ctx, updateReq)
+ require.Error(t, err)
+ require.Nil(t, updateRes)
+ })
+
+ t.Run("should update user", func(t *testing.T) {
+ h, err := crypto.EncryptPassword(cfg.AdminSecret)
+ assert.Nil(t, err)
+
+ req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
+ updateRes, err := ts.GraphQLProvider.UpdateUser(ctx, updateReq)
+ require.NoError(t, err)
+ require.NotNil(t, updateRes)
+ require.Equal(t, updateRes.ID, signupRes.User.ID)
+ require.Equal(t, userFirstName, *updateRes.GivenName)
+ })
+}
diff --git a/internal/integration_tests/update_webhook_test.go b/internal/integration_tests/update_webhook_test.go
new file mode 100644
index 000000000..b5cf63c88
--- /dev/null
+++ b/internal/integration_tests/update_webhook_test.go
@@ -0,0 +1,198 @@
+package integration_tests
+
+import (
+ "fmt"
+ "strings"
+ "testing"
+
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/crypto"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/refs"
+ "github.com/google/uuid"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+// TestUpdateWebhookTest tests the update webhook functionality by the admin
+func TestUpdateWebhookTest(t *testing.T) {
+ cfg := getTestConfig()
+ ts := initTestSetup(t, cfg)
+ req, ctx := createContext(ts)
+
+ // Create a test user
+ email := "update_webhook_user_test_" + uuid.New().String() + "@authorizer.dev"
+ password := "Password@123"
+ // Signup the user
+ signupReq := &model.SignUpRequest{
+ Email: &email,
+ Password: password,
+ ConfirmPassword: password,
+ }
+ signupRes, err := ts.GraphQLProvider.SignUp(ctx, signupReq)
+ require.NoError(t, err)
+ require.NotNil(t, signupRes)
+ require.NotNil(t, signupRes.User)
+
+ // First add a webhook to update
+ h, err := crypto.EncryptPassword(cfg.AdminSecret)
+ assert.Nil(t, err)
+ req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
+
+ // Create a webhook with original event name
+ addedWebhook, err := ts.GraphQLProvider.AddWebhook(ctx, &model.AddWebhookRequest{
+ EventName: constants.UserCreatedWebhookEvent,
+ EventDescription: refs.NewStringRef("original description"),
+ Endpoint: "http://original-endpoint.com",
+ Enabled: false,
+ Headers: map[string]any{
+ "Content-Type": "application/json",
+ },
+ })
+ require.NoError(t, err)
+ assert.NotNil(t, addedWebhook)
+
+ // Get the webhook to update
+ webhooks, err := ts.StorageProvider.GetWebhookByEventName(ctx, constants.UserCreatedWebhookEvent)
+ require.NoError(t, err)
+ require.NotEmpty(t, webhooks)
+ webhookID := webhooks[0].ID
+
+ t.Run("should fail without admin cookie", func(t *testing.T) {
+ // Remove admin cookie
+ req.Header.Del("Cookie")
+
+ updatedWebhook, err := ts.GraphQLProvider.UpdateWebhook(ctx, &model.UpdateWebhookRequest{
+ ID: webhookID,
+ EventName: refs.NewStringRef(constants.UserCreatedWebhookEvent),
+ EventDescription: refs.NewStringRef("updated description"),
+ Endpoint: refs.NewStringRef("http://updated-endpoint.com"),
+ Enabled: refs.NewBoolRef(true),
+ Headers: map[string]any{
+ "Content-Type": "application/json",
+ "Authorization": "Bearer token",
+ },
+ })
+ require.Error(t, err)
+ require.Nil(t, updatedWebhook)
+ })
+
+ // Re-add the admin cookie for the rest of the tests
+ req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
+
+ t.Run("should fail with invalid webhook ID", func(t *testing.T) {
+ updatedWebhook, err := ts.GraphQLProvider.UpdateWebhook(ctx, &model.UpdateWebhookRequest{
+ ID: uuid.NewString(),
+ EventName: refs.NewStringRef(constants.UserCreatedWebhookEvent),
+ EventDescription: refs.NewStringRef("updated description"),
+ Endpoint: refs.NewStringRef("http://updated-endpoint.com"),
+ Enabled: refs.NewBoolRef(true),
+ })
+ require.Error(t, err)
+ require.Nil(t, updatedWebhook)
+ })
+
+ t.Run("should fail with blank webhook ID", func(t *testing.T) {
+ updatedWebhook, err := ts.GraphQLProvider.UpdateWebhook(ctx, &model.UpdateWebhookRequest{
+ ID: "",
+ EventName: refs.NewStringRef(constants.UserCreatedWebhookEvent),
+ EventDescription: refs.NewStringRef("updated description"),
+ Endpoint: refs.NewStringRef("http://updated-endpoint.com"),
+ Enabled: refs.NewBoolRef(true),
+ })
+ require.Error(t, err)
+ require.Nil(t, updatedWebhook)
+ })
+
+ t.Run("should fail with invalid event name", func(t *testing.T) {
+ updatedWebhook, err := ts.GraphQLProvider.UpdateWebhook(ctx, &model.UpdateWebhookRequest{
+ ID: webhookID,
+ EventName: refs.NewStringRef("invalid_event_name"),
+ EventDescription: refs.NewStringRef("updated description"),
+ Endpoint: refs.NewStringRef("http://updated-endpoint.com"),
+ Enabled: refs.NewBoolRef(true),
+ })
+ require.Error(t, err)
+ require.Nil(t, updatedWebhook)
+ })
+
+ t.Run("should fail with blank endpoint", func(t *testing.T) {
+ updatedWebhook, err := ts.GraphQLProvider.UpdateWebhook(ctx, &model.UpdateWebhookRequest{
+ ID: webhookID,
+ EventName: refs.NewStringRef(constants.UserCreatedWebhookEvent),
+ EventDescription: refs.NewStringRef("updated description"),
+ Endpoint: refs.NewStringRef(""),
+ Enabled: refs.NewBoolRef(true),
+ })
+ require.Error(t, err)
+ require.Nil(t, updatedWebhook)
+ })
+
+ t.Run("should update webhook successfully", func(t *testing.T) {
+ // Use a different event name for the update to avoid conflicts
+ newEventName := constants.UserLoginWebhookEvent
+ updatedEndpoint := "http://updated-endpoint.com"
+
+ updatedWebhook, err := ts.GraphQLProvider.UpdateWebhook(ctx, &model.UpdateWebhookRequest{
+ ID: webhookID,
+ EventName: refs.NewStringRef(newEventName),
+ EventDescription: refs.NewStringRef("updated description"),
+ Endpoint: refs.NewStringRef(updatedEndpoint),
+ Enabled: refs.NewBoolRef(true),
+ Headers: map[string]any{
+ "Content-Type": "application/json",
+ "Authorization": "Bearer token",
+ },
+ })
+ require.NoError(t, err)
+ assert.NotNil(t, updatedWebhook)
+
+ // Verify the webhook was updated correctly
+ updatedWebhooks, err := ts.StorageProvider.GetWebhookByID(ctx, webhookID)
+ require.NoError(t, err)
+ assert.NotNil(t, updatedWebhooks)
+
+ // Use the same event name that we provided in the update request
+ assert.Contains(t, updatedWebhooks.EventName, newEventName)
+ assert.Equal(t, "updated description", updatedWebhooks.EventDescription)
+ assert.Equal(t, updatedEndpoint, updatedWebhooks.EndPoint)
+ assert.Equal(t, true, updatedWebhooks.Enabled)
+ })
+
+ t.Run("should partially update webhook", func(t *testing.T) {
+ // First get the current webhook state to verify what fields stay unchanged
+ currentWebhook, err := ts.StorageProvider.GetWebhookByID(ctx, webhookID)
+ require.NoError(t, err)
+
+ // Store the current values for later verification
+ currentEventName := strings.Split(currentWebhook.EventName, "-")[0]
+ currentEndpoint := currentWebhook.EndPoint
+
+ // Update only the description and enabled status
+ updatedWebhook, err := ts.GraphQLProvider.UpdateWebhook(ctx, &model.UpdateWebhookRequest{
+ ID: webhookID,
+ EventDescription: refs.NewStringRef("new partial description"),
+ Enabled: refs.NewBoolRef(false),
+ // Don't update event name or endpoint
+ })
+ require.NoError(t, err)
+ assert.NotNil(t, updatedWebhook)
+
+ // Verify only specified fields were updated
+ afterPartialUpdate, err := ts.StorageProvider.GetWebhookByID(ctx, webhookID)
+ require.NoError(t, err)
+ assert.NotNil(t, afterPartialUpdate)
+
+ // The event name should remain the same as before
+ assert.Contains(t, afterPartialUpdate.EventName, currentEventName)
+
+ // Description should be updated
+ assert.Equal(t, "new partial description", afterPartialUpdate.EventDescription)
+
+ // Endpoint should remain unchanged
+ assert.Equal(t, currentEndpoint, afterPartialUpdate.EndPoint)
+
+ // Enabled should be updated
+ assert.Equal(t, false, afterPartialUpdate.Enabled)
+ })
+}
diff --git a/internal/integration_tests/validate_jwt_token_test.go b/internal/integration_tests/validate_jwt_token_test.go
new file mode 100644
index 000000000..3a8b709e9
--- /dev/null
+++ b/internal/integration_tests/validate_jwt_token_test.go
@@ -0,0 +1,91 @@
+package integration_tests
+
+import (
+ "strings"
+ "testing"
+
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/google/uuid"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+// TestValidateJWTToken add test cases for validating JWT tokens
+func TestValidateJWTToken(t *testing.T) {
+ // Initialize test setup
+ cfg := getTestConfig()
+ ts := initTestSetup(t, cfg)
+ _, ctx := createContext(ts)
+
+ // Test setup - create a test user
+ email := "validate_jwt_test_" + uuid.New().String() + "@authorizer.dev"
+ password := "Password@123"
+
+ signupReq := &model.SignUpRequest{
+ Email: &email,
+ Password: password,
+ ConfirmPassword: password,
+ }
+ res, err := ts.GraphQLProvider.SignUp(ctx, signupReq)
+ assert.NoError(t, err)
+ assert.NotNil(t, res)
+
+ // Profile tests
+ t.Run("after login", func(t *testing.T) {
+ loginReq := &model.LoginRequest{
+ Email: &email,
+ Password: password,
+ }
+ loginRes, err := ts.GraphQLProvider.Login(ctx, loginReq)
+ assert.NoError(t, err)
+ assert.NotNil(t, loginRes)
+
+ // Verify response contains expected tokens
+ assert.NotEmpty(t, loginRes.AccessToken)
+ assert.NotNil(t, loginRes.User)
+ assert.Equal(t, email, *loginRes.User.Email)
+ assert.True(t, loginRes.User.EmailVerified)
+
+ t.Run("should fail without token", func(t *testing.T) {
+ res, err := ts.GraphQLProvider.ValidateJWTToken(ctx, &model.ValidateJWTTokenRequest{})
+ assert.Error(t, err)
+ assert.Nil(t, res)
+ })
+
+ t.Run("should fail without token type", func(t *testing.T) {
+ res, err := ts.GraphQLProvider.ValidateJWTToken(ctx, &model.ValidateJWTTokenRequest{
+ Token: "invalid-token",
+ })
+ assert.Error(t, err)
+ assert.Nil(t, res)
+ })
+
+ t.Run("should fail with invalid token", func(t *testing.T) {
+ res, err := ts.GraphQLProvider.ValidateJWTToken(ctx, &model.ValidateJWTTokenRequest{
+ Token: "invalid-token",
+ TokenType: constants.TokenTypeAccessToken,
+ })
+ assert.Error(t, err)
+ assert.Nil(t, res)
+ })
+
+ t.Run("should pass with valid input", func(t *testing.T) {
+ allData, err := ts.MemoryStoreProvider.GetAllData()
+ require.NoError(t, err)
+ accessToken := ""
+ for k, v := range allData {
+ if strings.Contains(k, constants.TokenTypeAccessToken) {
+ accessToken = v
+ break
+ }
+ }
+ res, err := ts.GraphQLProvider.ValidateJWTToken(ctx, &model.ValidateJWTTokenRequest{
+ Token: accessToken,
+ TokenType: constants.TokenTypeAccessToken,
+ })
+ require.NoError(t, err)
+ require.NotNil(t, res)
+ })
+ })
+}
diff --git a/internal/integration_tests/validate_session_test.go b/internal/integration_tests/validate_session_test.go
new file mode 100644
index 000000000..a5cd959fa
--- /dev/null
+++ b/internal/integration_tests/validate_session_test.go
@@ -0,0 +1,99 @@
+package integration_tests
+
+import (
+ "strings"
+ "testing"
+
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/google/uuid"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+// TestValidateSession add test cases for validating session tokens
+func TestValidateSession(t *testing.T) {
+ // Initialize test setup
+ cfg := getTestConfig()
+ ts := initTestSetup(t, cfg)
+ _, ctx := createContext(ts)
+
+ // Test setup - create a test user
+ email := "validate_session_test_" + uuid.New().String() + "@authorizer.dev"
+ password := "Password@123"
+
+ signupReq := &model.SignUpRequest{
+ Email: &email,
+ Password: password,
+ ConfirmPassword: password,
+ }
+ res, err := ts.GraphQLProvider.SignUp(ctx, signupReq)
+ assert.NoError(t, err)
+ assert.NotNil(t, res)
+
+ // Profile tests
+ t.Run("after login", func(t *testing.T) {
+ loginReq := &model.LoginRequest{
+ Email: &email,
+ Password: password,
+ }
+ loginRes, err := ts.GraphQLProvider.Login(ctx, loginReq)
+ assert.NoError(t, err)
+ assert.NotNil(t, loginRes)
+
+ // Verify response contains expected tokens
+ assert.NotEmpty(t, loginRes.AccessToken)
+ assert.NotNil(t, loginRes.User)
+ assert.Equal(t, email, *loginRes.User.Email)
+ assert.True(t, loginRes.User.EmailVerified)
+
+ t.Run("should fail without cookie", func(t *testing.T) {
+ res, err := ts.GraphQLProvider.ValidateSession(ctx, &model.ValidateSessionRequest{})
+ assert.Error(t, err)
+ assert.Nil(t, res)
+ })
+
+ t.Run("should fail with invalid cookie", func(t *testing.T) {
+ res, err := ts.GraphQLProvider.ValidateSession(ctx, &model.ValidateSessionRequest{
+ Cookie: "invalid-token",
+ })
+ assert.Error(t, err)
+ assert.Nil(t, res)
+ })
+
+ t.Run("should pass with valid input", func(t *testing.T) {
+ allData, err := ts.MemoryStoreProvider.GetAllData()
+ require.NoError(t, err)
+ sessionToken := ""
+ for k, v := range allData {
+ if strings.Contains(k, constants.TokenTypeSessionToken) {
+ sessionToken = v
+ break
+ }
+ }
+ res, err := ts.GraphQLProvider.ValidateSession(ctx, &model.ValidateSessionRequest{
+ Cookie: sessionToken,
+ })
+ require.NoError(t, err)
+ require.NotNil(t, res)
+
+ t.Run("should fail with invalid roles", func(t *testing.T) {
+ res, err := ts.GraphQLProvider.ValidateSession(ctx, &model.ValidateSessionRequest{
+ Cookie: sessionToken,
+ Roles: []string{"invalid-role"},
+ })
+ assert.Error(t, err)
+ assert.Nil(t, res)
+ })
+ t.Run("should pass with valid roles", func(t *testing.T) {
+ res, err := ts.GraphQLProvider.ValidateSession(ctx, &model.ValidateSessionRequest{
+ Cookie: sessionToken,
+ Roles: []string{"user"},
+ })
+ assert.NoError(t, err)
+ assert.NotNil(t, res)
+ assert.True(t, res.IsValid)
+ })
+ })
+ })
+}
diff --git a/internal/integration_tests/verify_email_test.go b/internal/integration_tests/verify_email_test.go
new file mode 100644
index 000000000..418375bc7
--- /dev/null
+++ b/internal/integration_tests/verify_email_test.go
@@ -0,0 +1,65 @@
+package integration_tests
+
+import (
+ "testing"
+
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/google/uuid"
+ "github.com/stretchr/testify/assert"
+)
+
+// TestVerifyEmail tests the verify email functionality
+// using the GraphQL API.
+// It creates a user, verifies the email, and checks
+// the changes in the database.
+func TestVerifyEmail(t *testing.T) {
+ cfg := getTestConfig()
+ cfg.IsEmailServiceEnabled = true
+ cfg.EnableEmailVerification = true
+ ts := initTestSetup(t, cfg)
+ _, ctx := createContext(ts)
+
+ // Create a test user
+ email := "verify_email_test_" + uuid.New().String() + "@authorizer.dev"
+ password := "Password@123"
+ // Signup the user
+ signupReq := &model.SignUpRequest{
+ Email: &email,
+ Password: password,
+ ConfirmPassword: password,
+ }
+
+ signupRes, err := ts.GraphQLProvider.SignUp(ctx, signupReq)
+ assert.NoError(t, err)
+ assert.NotNil(t, signupRes)
+ // Expect the user to be nil, as the email is not verified yet
+ assert.Nil(t, signupRes.User)
+
+ t.Run("should fail for invalid token", func(t *testing.T) {
+ verificationReq := &model.VerifyEmailRequest{
+ Token: "invalid-token",
+ }
+ verificationRes, err := ts.GraphQLProvider.VerifyEmail(ctx, verificationReq)
+ assert.Error(t, err)
+ assert.Nil(t, verificationRes)
+ })
+
+ t.Run("should verify email", func(t *testing.T) {
+ // Get the verification token from db
+ request, err := ts.StorageProvider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeBasicAuthSignup)
+ assert.NoError(t, err)
+ assert.NotNil(t, request)
+ assert.NotEmpty(t, request.Token)
+
+ // Verify email with an invalid token
+ verificationReq := &model.VerifyEmailRequest{
+ Token: request.Token,
+ }
+
+ verificationRes, err := ts.GraphQLProvider.VerifyEmail(ctx, verificationReq)
+ assert.NoError(t, err)
+ assert.NotNil(t, verificationRes)
+ assert.NotEmpty(t, verificationRes.AccessToken)
+ })
+}
diff --git a/internal/integration_tests/verify_otp_test.go b/internal/integration_tests/verify_otp_test.go
new file mode 100644
index 000000000..a2ec958c7
--- /dev/null
+++ b/internal/integration_tests/verify_otp_test.go
@@ -0,0 +1,107 @@
+package integration_tests
+
+import (
+ "fmt"
+ "strings"
+ "testing"
+
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+// TestVerifyOTP tests the resend verify OTP functionality
+func TestVerifyOTP(t *testing.T) {
+ cfg := getTestConfig()
+ cfg.IsSMSServiceEnabled = true
+ cfg.EnableEmailOTP = true
+ cfg.EnableSMSOTP = true
+ cfg.SMTPHost = "localhost"
+ cfg.SMTPPort = 1025
+ cfg.SMTPSenderEmail = "test@authorizer.dev"
+ cfg.SMTPSenderName = "Test"
+ cfg.SMTPLocalName = "Test"
+ cfg.SkipTLSVerification = true
+ cfg.IsEmailServiceEnabled = true
+ cfg.IsSMSServiceEnabled = true
+ cfg.EnableEmailVerification = true
+ cfg.TwilioAPISecret = "test-twilio-api-secret"
+ cfg.TwilioAPIKey = "test-twilio-api-key"
+ cfg.TwilioAccountSID = "test-twilio-account-sid"
+ cfg.TwilioSender = "test-twilio-sender"
+ cfg.EnableMobileBasicAuthentication = true
+ cfg.EnablePhoneVerification = true
+ ts := initTestSetup(t, cfg)
+ req, ctx := createContext(ts)
+
+ // Create a test user
+ mobile := "+14155552671"
+ password := "Password@123"
+ // Signup the user
+ signupReq := &model.SignUpRequest{
+ PhoneNumber: &mobile,
+ Password: password,
+ ConfirmPassword: password,
+ }
+
+ signupRes, err := ts.GraphQLProvider.SignUp(ctx, signupReq)
+ assert.NoError(t, err)
+ assert.NotNil(t, signupRes)
+ // Expect the user to be nil, as the email is not verified yet
+ assert.Nil(t, signupRes.User)
+
+ // Get the OTP from db
+ otpData, err := ts.StorageProvider.GetOTPByPhoneNumber(ctx, mobile)
+ require.NoError(t, err)
+ assert.NotNil(t, otpData)
+ // User
+ userData, err := ts.StorageProvider.GetUserByPhoneNumber(ctx, mobile)
+ require.NoError(t, err)
+ assert.NotNil(t, userData)
+
+ t.Run("should fail for invalid cookie", func(t *testing.T) {
+ verificationReq := &model.VerifyOTPRequest{
+ PhoneNumber: &mobile,
+ Otp: otpData.Otp,
+ }
+ verificationRes, err := ts.GraphQLProvider.VerifyOTP(ctx, verificationReq)
+ assert.Error(t, err)
+ assert.Nil(t, verificationRes)
+ })
+
+ t.Run("should fail for invalid OTP", func(t *testing.T) {
+ req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.MfaCookieName+"_session", "test"))
+ verificationReq := &model.VerifyOTPRequest{
+ PhoneNumber: &mobile,
+ Otp: "-----",
+ }
+ verificationRes, err := ts.GraphQLProvider.VerifyOTP(ctx, verificationReq)
+ assert.Error(t, err)
+ assert.Nil(t, verificationRes)
+ })
+
+ t.Run("should verify OTP", func(t *testing.T) {
+ // Get MFA session cookie
+ allData, err := ts.MemoryStoreProvider.GetAllData()
+ require.NoError(t, err)
+ sessionKey := ""
+ for k := range allData {
+ if strings.Contains(k, userData.ID) {
+ splitData := strings.Split(k, ":")
+ if len(splitData) > 1 {
+ sessionKey = splitData[1]
+ break
+ }
+ }
+ }
+ req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.MfaCookieName+"_session", sessionKey))
+ verificationReq := &model.VerifyOTPRequest{
+ PhoneNumber: &mobile,
+ Otp: otpData.Otp,
+ }
+ verificationRes, err := ts.GraphQLProvider.VerifyOTP(ctx, verificationReq)
+ require.NoError(t, err)
+ assert.NotNil(t, verificationRes)
+ })
+}
diff --git a/internal/memory_store/in_memory/provider.go b/internal/memory_store/in_memory/provider.go
new file mode 100644
index 000000000..d27e6077c
--- /dev/null
+++ b/internal/memory_store/in_memory/provider.go
@@ -0,0 +1,36 @@
+package in_memory
+
+import (
+ "sync"
+
+ "github.com/rs/zerolog"
+
+ "github.com/authorizerdev/authorizer/internal/config"
+ "github.com/authorizerdev/authorizer/internal/memory_store/in_memory/stores"
+)
+
+// Dependencies struct for in_memory store provider
+type Dependencies struct {
+ Log *zerolog.Logger
+}
+
+type provider struct {
+ config *config.Config
+ dependencies *Dependencies
+ mutex sync.Mutex
+ sessionStore *stores.SessionStore
+ mfasessionStore *stores.SessionStore
+ stateStore *stores.StateStore
+}
+
+// NewInMemoryStore returns a new in-memory store.
+func NewInMemoryProvider(cfg *config.Config, deps *Dependencies) (*provider, error) {
+ return &provider{
+ config: cfg,
+ dependencies: deps,
+ mutex: sync.Mutex{},
+ sessionStore: stores.NewSessionStore(),
+ mfasessionStore: stores.NewSessionStore(),
+ stateStore: stores.NewStateStore(),
+ }, nil
+}
diff --git a/server/memorystore/providers/inmemory/store.go b/internal/memory_store/in_memory/store.go
similarity index 53%
rename from server/memorystore/providers/inmemory/store.go
rename to internal/memory_store/in_memory/store.go
index b20fb6221..83b73b2a3 100644
--- a/server/memorystore/providers/inmemory/store.go
+++ b/internal/memory_store/in_memory/store.go
@@ -1,10 +1,9 @@
-package inmemory
+package in_memory
import (
"fmt"
- "os"
- "github.com/authorizerdev/authorizer/server/constants"
+ "github.com/authorizerdev/authorizer/internal/constants"
)
// SetUserSession sets the user session for given user identifier in form recipe:user_id
@@ -14,10 +13,10 @@ func (c *provider) SetUserSession(userId, key, token string, expiration int64) e
}
// GetUserSession returns value for given session token
-func (c *provider) GetUserSession(userId, sessionToken string) (string, error) {
- val := c.sessionStore.Get(userId, sessionToken)
+func (c *provider) GetUserSession(userId, key string) (string, error) {
+ val := c.sessionStore.Get(userId, key)
if val == "" {
- return "", fmt.Errorf("Not found")
+ return "", fmt.Errorf("not found")
}
return val, nil
}
@@ -29,10 +28,16 @@ func (c *provider) DeleteAllUserSessions(userId string) error {
}
// DeleteUserSession deletes the user session from the in-memory store.
-func (c *provider) DeleteUserSession(userId, sessionToken string) error {
- c.sessionStore.Remove(userId, constants.TokenTypeSessionToken+"_"+sessionToken)
- c.sessionStore.Remove(userId, constants.TokenTypeAccessToken+"_"+sessionToken)
- c.sessionStore.Remove(userId, constants.TokenTypeRefreshToken+"_"+sessionToken)
+func (c *provider) DeleteUserSession(userId, key string) error {
+ keys := []string{
+ constants.TokenTypeSessionToken + "_" + key,
+ constants.TokenTypeAccessToken + "_" + key,
+ constants.TokenTypeRefreshToken + "_" + key,
+ }
+
+ for _, k := range keys {
+ c.sessionStore.Remove(userId, k)
+ }
return nil
}
@@ -52,11 +57,20 @@ func (c *provider) SetMfaSession(userId, key string, expiration int64) error {
func (c *provider) GetMfaSession(userId, key string) (string, error) {
val := c.mfasessionStore.Get(userId, key)
if val == "" {
- return "", fmt.Errorf("Not found")
+ return "", fmt.Errorf("not found")
}
return val, nil
}
+// GetAllMfaSessions returns all mfa sessions for given userId
+func (p *provider) GetAllMfaSessions(userId string) ([]string, error) {
+ values := p.mfasessionStore.GetAll(userId)
+ if len(values) == 0 {
+ return nil, fmt.Errorf("not found")
+ }
+ return values, nil
+}
+
// DeleteMfaSession deletes given mfa session from in-memory store.
func (c *provider) DeleteMfaSession(userId, key string) error {
c.mfasessionStore.Remove(userId, key)
@@ -65,10 +79,9 @@ func (c *provider) DeleteMfaSession(userId, key string) error {
// SetState sets the state in the in-memory store.
func (c *provider) SetState(key, state string) error {
- if os.Getenv("ENV") != constants.TestEnv {
- c.mutex.Lock()
- defer c.mutex.Unlock()
- }
+ c.mutex.Lock()
+ defer c.mutex.Unlock()
+
c.stateStore.Set(key, state)
return nil
@@ -85,37 +98,17 @@ func (c *provider) RemoveState(key string) error {
return nil
}
-// UpdateEnvStore to update the whole env store object
-func (c *provider) UpdateEnvStore(store map[string]interface{}) error {
- c.envStore.UpdateStore(store)
- return nil
-}
-
-// GetEnvStore returns the env store object
-func (c *provider) GetEnvStore() (map[string]interface{}, error) {
- return c.envStore.GetStore(), nil
-}
-
-// UpdateEnvVariable to update the particular env variable
-func (c *provider) UpdateEnvVariable(key string, value interface{}) error {
- c.envStore.Set(key, value)
- return nil
-}
-
-// GetStringStoreEnvVariable to get the env variable from string store object
-func (c *provider) GetStringStoreEnvVariable(key string) (string, error) {
- res := c.envStore.Get(key)
- if res == nil {
- return "", nil
+// GetAllData returns all the data from the in-memory store
+// This is used for testing purposes only
+func (c *provider) GetAllData() (map[string]string, error) {
+ // Get all data from the session store and mfa session store
+ // and merge them into a single map
+ data := make(map[string]string)
+ for k, v := range c.sessionStore.GetAllData() {
+ data[k] = v
}
- return fmt.Sprintf("%v", res), nil
-}
-
-// GetBoolStoreEnvVariable to get the env variable from bool store object
-func (c *provider) GetBoolStoreEnvVariable(key string) (bool, error) {
- res := c.envStore.Get(key)
- if res == nil {
- return false, nil
+ for k, v := range c.mfasessionStore.GetAllData() {
+ data[k] = v
}
- return res.(bool), nil
+ return data, nil
}
diff --git a/internal/memory_store/in_memory/stores/env_store.go b/internal/memory_store/in_memory/stores/env_store.go
new file mode 100644
index 000000000..c0b84b7aa
--- /dev/null
+++ b/internal/memory_store/in_memory/stores/env_store.go
@@ -0,0 +1,48 @@
+package stores
+
+// EnvStore struct to store the env variables
+// type EnvStore struct {
+// mutex sync.Mutex
+// store map[string]interface{}
+// }
+
+// // NewEnvStore create a new env store
+// func NewEnvStore() *EnvStore {
+// return &EnvStore{
+// mutex: sync.Mutex{},
+// store: make(map[string]interface{}),
+// }
+// }
+
+// // UpdateEnvStore to update the whole env store object
+// func (e *EnvStore) UpdateStore(store map[string]interface{}) {
+// e.mutex.Lock()
+// defer e.mutex.Unlock()
+
+// // just override the keys + new keys
+// for key, value := range store {
+// e.store[key] = value
+// }
+// }
+
+// // GetStore returns the env store
+// func (e *EnvStore) GetStore() map[string]interface{} {
+// e.mutex.Lock()
+// defer e.mutex.Unlock()
+// return e.store
+// }
+
+// // Get returns the value of the key in evn store
+// func (e *EnvStore) Get(key string) interface{} {
+// e.mutex.Lock()
+// defer e.mutex.Unlock()
+// return e.store[key]
+// }
+
+// // Set sets the value of the key in env store
+// func (e *EnvStore) Set(key string, value interface{}) {
+// e.mutex.Lock()
+// defer e.mutex.Unlock()
+
+// e.store[key] = value
+// }
diff --git a/server/memorystore/providers/inmemory/stores/session_store.go b/internal/memory_store/in_memory/stores/session_store.go
similarity index 81%
rename from server/memorystore/providers/inmemory/stores/session_store.go
rename to internal/memory_store/in_memory/stores/session_store.go
index a92902264..dacce5860 100644
--- a/server/memorystore/providers/inmemory/stores/session_store.go
+++ b/internal/memory_store/in_memory/stores/session_store.go
@@ -85,6 +85,26 @@ func (s *SessionStore) Get(key, subKey string) string {
return ""
}
+// Get returns the value of the key in state store
+func (s *SessionStore) GetAll(key string) []string {
+ s.mutex.Lock()
+ defer s.mutex.Unlock()
+ currentTime := time.Now().Unix()
+ // Match all keys with the given key
+ var values []string
+ for k, v := range s.store {
+ if strings.HasPrefix(k, key) {
+ if v.ExpiresAt > currentTime {
+ values = append(values, v.Value)
+ } else {
+ // Delete expired items
+ delete(s.store, k)
+ }
+ }
+ }
+ return values
+}
+
// Set sets the value of the key in state store
func (s *SessionStore) Set(key string, subKey, value string, expiration int64) {
s.mutex.Lock()
@@ -142,3 +162,15 @@ func (s *SessionStore) RemoveByNamespace(namespace string) error {
}
return nil
}
+
+// GetAllData returns all the data from the session store
+// This is used for testing purposes only
+func (s *SessionStore) GetAllData() map[string]string {
+ s.mutex.Lock()
+ defer s.mutex.Unlock()
+ data := make(map[string]string)
+ for k, v := range s.store {
+ data[k] = v.Value
+ }
+ return data
+}
diff --git a/server/memorystore/providers/inmemory/stores/state_store.go b/internal/memory_store/in_memory/stores/state_store.go
similarity index 100%
rename from server/memorystore/providers/inmemory/stores/state_store.go
rename to internal/memory_store/in_memory/stores/state_store.go
diff --git a/server/memorystore/providers/providers.go b/internal/memory_store/provider.go
similarity index 58%
rename from server/memorystore/providers/providers.go
rename to internal/memory_store/provider.go
index 331e34a50..1155c8b20 100644
--- a/server/memorystore/providers/providers.go
+++ b/internal/memory_store/provider.go
@@ -1,4 +1,29 @@
-package providers
+package memory_store
+
+import (
+ "github.com/rs/zerolog"
+
+ "github.com/authorizerdev/authorizer/internal/config"
+ "github.com/authorizerdev/authorizer/internal/memory_store/in_memory"
+ "github.com/authorizerdev/authorizer/internal/memory_store/redis"
+)
+
+// Dependencies struct for memory store provider
+type Dependencies struct {
+ Log *zerolog.Logger
+}
+
+// New returns a new memory store provider
+func New(cfg *config.Config, deps *Dependencies) (Provider, error) {
+ if cfg.RedisURL != "" {
+ return redis.NewRedisProvider(cfg, &redis.Dependencies{
+ Log: deps.Log,
+ })
+ }
+ return in_memory.NewInMemoryProvider(cfg, &in_memory.Dependencies{
+ Log: deps.Log,
+ })
+}
// Provider defines current memory store provider
type Provider interface {
@@ -16,6 +41,8 @@ type Provider interface {
SetMfaSession(userId, key string, expiration int64) error
// GetMfaSession returns value of given mfa session
GetMfaSession(userId, key string) (string, error)
+ // GetAllMfaSessions returns all mfa sessions for given userId
+ GetAllMfaSessions(userId string) ([]string, error)
// DeleteMfaSession deletes given mfa session from in-memory store.
DeleteMfaSession(userId, key string) error
@@ -26,16 +53,7 @@ type Provider interface {
// RemoveState removes the social login state from the session store
RemoveState(key string) error
- // methods for env store
-
- // UpdateEnvStore to update the whole env store object
- UpdateEnvStore(store map[string]interface{}) error
- // GetEnvStore() returns the env store object
- GetEnvStore() (map[string]interface{}, error)
- // UpdateEnvVariable to update the particular env variable
- UpdateEnvVariable(key string, value interface{}) error
- // GetStringStoreEnvVariable to get the string env variable from env store
- GetStringStoreEnvVariable(key string) (string, error)
- // GetBoolStoreEnvVariable to get the bool env variable from env store
- GetBoolStoreEnvVariable(key string) (bool, error)
+ // GetAllData returns all the data from the session store
+ // This is used for testing purposes only
+ GetAllData() (map[string]string, error)
}
diff --git a/internal/memory_store/provider_test.go b/internal/memory_store/provider_test.go
new file mode 100644
index 000000000..ea5b8aa8c
--- /dev/null
+++ b/internal/memory_store/provider_test.go
@@ -0,0 +1,161 @@
+package memory_store
+
+import (
+ "testing"
+ "time"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+
+ "github.com/authorizerdev/authorizer/internal/config"
+)
+
+const (
+ memoryStoreTypeRedis = "redis"
+ memoryStoreTypeInMemory = "inmemory"
+)
+
+var memoryStoreTypes = []string{
+ memoryStoreTypeRedis,
+ memoryStoreTypeInMemory,
+}
+
+func getTestMemoryStorageConfig(storageType string) *config.Config {
+ cfg := &config.Config{
+ Env: "prod",
+ }
+ switch storageType {
+ case memoryStoreTypeRedis:
+ cfg.RedisURL = "redis://localhost:6380"
+ case memoryStoreTypeInMemory:
+ cfg.RedisURL = ""
+ default:
+ cfg.RedisURL = ""
+ }
+ return cfg
+}
+
+// TestMemoryStoreProvider tests the memory store provider
+func TestMemoryStoreProvider(t *testing.T) {
+ for _, storeType := range memoryStoreTypes {
+ t.Run("should test memory store provider for "+storeType, func(t *testing.T) {
+ cfg := getTestMemoryStorageConfig(storeType)
+ p, err := New(cfg, &Dependencies{})
+ require.NoError(t, err)
+ require.NotNil(t, p)
+ err = p.SetUserSession("auth_provider:123", "session_token_key", "test_hash123", time.Now().Add(60*time.Second).Unix())
+ assert.NoError(t, err)
+ err = p.SetUserSession("auth_provider:123", "access_token_key", "test_jwt123", time.Now().Add(60*time.Second).Unix())
+ assert.NoError(t, err)
+ // Same user multiple session
+ err = p.SetUserSession("auth_provider:123", "session_token_key1", "test_hash1123", time.Now().Add(60*time.Second).Unix())
+ assert.NoError(t, err)
+ err = p.SetUserSession("auth_provider:123", "access_token_key1", "test_jwt1123", time.Now().Add(60*time.Second).Unix())
+ assert.NoError(t, err)
+ // Different user session
+ err = p.SetUserSession("auth_provider:124", "session_token_key", "test_hash124", time.Now().Add(5*time.Second).Unix())
+ assert.NoError(t, err)
+ err = p.SetUserSession("auth_provider:124", "access_token_key", "test_jwt124", time.Now().Add(5*time.Second).Unix())
+ assert.NoError(t, err)
+ // Different provider session
+ err = p.SetUserSession("auth_provider1:124", "session_token_key", "test_hash124", time.Now().Add(60*time.Second).Unix())
+ assert.NoError(t, err)
+ err = p.SetUserSession("auth_provider1:124", "access_token_key", "test_jwt124", time.Now().Add(60*time.Second).Unix())
+ assert.NoError(t, err)
+ // Different provider session
+ err = p.SetUserSession("auth_provider1:123", "session_token_key", "test_hash1123", time.Now().Add(60*time.Second).Unix())
+ assert.NoError(t, err)
+ err = p.SetUserSession("auth_provider1:123", "access_token_key", "test_jwt1123", time.Now().Add(60*time.Second).Unix())
+ assert.NoError(t, err)
+ // Get session
+ key, err := p.GetUserSession("auth_provider:123", "session_token_key")
+ assert.NoError(t, err)
+ assert.Equal(t, "test_hash123", key)
+ key, err = p.GetUserSession("auth_provider:123", "access_token_key")
+ assert.NoError(t, err)
+ assert.Equal(t, "test_jwt123", key)
+ key, err = p.GetUserSession("auth_provider:124", "session_token_key")
+ assert.NoError(t, err)
+ assert.Equal(t, "test_hash124", key)
+ key, err = p.GetUserSession("auth_provider:124", "access_token_key")
+ assert.NoError(t, err)
+ assert.Equal(t, "test_jwt124", key)
+ // Expire some tokens and make sure they are empty
+ time.Sleep(5 * time.Second)
+ key, err = p.GetUserSession("auth_provider:124", "session_token_key")
+ assert.Empty(t, key)
+ assert.Error(t, err)
+ key, err = p.GetUserSession("auth_provider:124", "access_token_key")
+ assert.Empty(t, key)
+ assert.Error(t, err)
+ // Delete user session
+ err = p.DeleteUserSession("auth_provider:123", "key")
+ assert.NoError(t, err)
+ err = p.DeleteUserSession("auth_provider:123", "key")
+ assert.NoError(t, err)
+ key, err = p.GetUserSession("auth_provider:123", "key")
+ assert.Empty(t, key)
+ assert.Error(t, err)
+ key, err = p.GetUserSession("auth_provider:123", "access_token_key")
+ assert.Empty(t, key)
+ assert.Error(t, err)
+ // Delete all user session
+ err = p.DeleteAllUserSessions("123")
+ assert.NoError(t, err)
+ err = p.DeleteAllUserSessions("123")
+ assert.NoError(t, err)
+ key, err = p.GetUserSession("auth_provider:123", "session_token_key1")
+ assert.Empty(t, key)
+ assert.Error(t, err)
+ key, err = p.GetUserSession("auth_provider:123", "access_token_key1")
+ assert.Empty(t, key)
+ assert.Error(t, err)
+ key, err = p.GetUserSession("auth_provider1:123", "session_token_key")
+ assert.Empty(t, key)
+ assert.Error(t, err)
+ key, err = p.GetUserSession("auth_provider1:123", "access_token_key")
+ assert.Empty(t, key)
+ assert.Error(t, err)
+ // Delete namespace
+ err = p.DeleteSessionForNamespace("auth_provider")
+ assert.NoError(t, err)
+ err = p.DeleteSessionForNamespace("auth_provider1")
+ assert.NoError(t, err)
+ key, err = p.GetUserSession("auth_provider:123", "session_token_key1")
+ assert.Empty(t, key)
+ assert.Error(t, err)
+ key, err = p.GetUserSession("auth_provider:123", "access_token_key1")
+ assert.Empty(t, key)
+ assert.Error(t, err)
+ key, err = p.GetUserSession("auth_provider1:123", "session_token_key")
+ assert.Empty(t, key)
+ assert.Error(t, err)
+ key, err = p.GetUserSession("auth_provider1:123", "access_token_key")
+ assert.Empty(t, key)
+ assert.Error(t, err)
+ key, err = p.GetUserSession("auth_provider:124", "session_token_key1")
+ assert.Empty(t, key)
+ assert.Error(t, err)
+ key, err = p.GetUserSession("auth_provider:124", "access_token_key1")
+ assert.Empty(t, key)
+ assert.Error(t, err)
+ key, err = p.GetUserSession("auth_provider1:124", "session_token_key")
+ assert.Empty(t, key)
+ assert.Error(t, err)
+ key, err = p.GetUserSession("auth_provider1:124", "access_token_key")
+ assert.Empty(t, key)
+ assert.Error(t, err)
+
+ err = p.SetMfaSession("auth_provider:123", "session123", time.Now().Add(60*time.Second).Unix())
+ assert.NoError(t, err)
+ key, err = p.GetMfaSession("auth_provider:123", "session123")
+ assert.NoError(t, err)
+ assert.Equal(t, "auth_provider:123", key)
+ err = p.DeleteMfaSession("auth_provider:123", "session123")
+ assert.NoError(t, err)
+ key, err = p.GetMfaSession("auth_provider:123", "session123")
+ assert.Error(t, err)
+ assert.Empty(t, key)
+ })
+ }
+}
diff --git a/server/memorystore/providers/redis/provider.go b/internal/memory_store/redis/provider.go
similarity index 69%
rename from server/memorystore/providers/redis/provider.go
rename to internal/memory_store/redis/provider.go
index 17fb475dc..0e9142c65 100644
--- a/server/memorystore/providers/redis/provider.go
+++ b/internal/memory_store/redis/provider.go
@@ -6,13 +6,20 @@ import (
"time"
"github.com/redis/go-redis/v9"
- log "github.com/sirupsen/logrus"
+ "github.com/rs/zerolog"
+
+ "github.com/authorizerdev/authorizer/internal/config"
)
const (
dialTimeout = 60 * time.Second
)
+// Dependencies struct for redis provider
+type Dependencies struct {
+ Log *zerolog.Logger
+}
+
// RedisClient is the interface for redis client & redis cluster client
type RedisClient interface {
HMSet(ctx context.Context, key string, values ...interface{}) *redis.BoolCmd
@@ -29,17 +36,20 @@ type RedisClient interface {
}
type provider struct {
+ config *config.Config
+ dependencies *Dependencies
+
ctx context.Context
store RedisClient
}
// NewRedisProvider returns a new redis provider
-func NewRedisProvider(redisURL string) (*provider, error) {
- redisURLHostPortsList := strings.Split(redisURL, ",")
+func NewRedisProvider(cfg *config.Config, deps *Dependencies) (*provider, error) {
+ redisURLHostPortsList := strings.Split(cfg.RedisURL, ",")
if len(redisURLHostPortsList) > 1 {
opt, err := redis.ParseURL(redisURLHostPortsList[0])
if err != nil {
- log.Debug("error parsing redis url: ", err)
+ deps.Log.Debug().Err(err).Msg("error parsing redis url")
return nil, err
}
urls := []string{opt.Addr}
@@ -50,19 +60,21 @@ func NewRedisProvider(redisURL string) (*provider, error) {
ctx := context.Background()
_, err = rdb.Ping(ctx).Result()
if err != nil {
- log.Debug("error connecting to redis: ", err)
+ deps.Log.Debug().Err(err).Msg("error connecting to redis")
return nil, err
}
return &provider{
- ctx: ctx,
- store: rdb,
+ config: cfg,
+ dependencies: deps,
+ ctx: ctx,
+ store: rdb,
}, nil
}
- opt, err := redis.ParseURL(redisURL)
+ opt, err := redis.ParseURL(cfg.RedisURL)
if err != nil {
- log.Debug("error parsing redis url: ", err)
+ deps.Log.Debug().Err(err).Msg("error parsing redis url")
return nil, err
}
opt.DialTimeout = dialTimeout
@@ -70,11 +82,13 @@ func NewRedisProvider(redisURL string) (*provider, error) {
ctx := context.Background()
_, err = rdb.Ping(ctx).Result()
if err != nil {
- log.Debug("error connecting to redis: ", err)
+ deps.Log.Debug().Err(err).Msg("error connecting to redis")
return nil, err
}
return &provider{
- ctx: ctx,
- store: rdb,
+ config: cfg,
+ dependencies: deps,
+ ctx: ctx,
+ store: rdb,
}, nil
}
diff --git a/internal/memory_store/redis/store.go b/internal/memory_store/redis/store.go
new file mode 100644
index 000000000..ae5ebc48d
--- /dev/null
+++ b/internal/memory_store/redis/store.go
@@ -0,0 +1,189 @@
+package redis
+
+import (
+ "fmt"
+ "time"
+
+ "github.com/authorizerdev/authorizer/internal/constants"
+)
+
+var (
+ // state store prefix
+ stateStorePrefix = "authorizer_state:"
+)
+
+const mfaSessionPrefix = "mfa_session_"
+
+// SetUserSession sets the user session for given user identifier in form recipe:user_id
+func (p *provider) SetUserSession(userId, key, token string, expiration int64) error {
+ currentTime := time.Now()
+ expireTime := time.Unix(expiration, 0)
+ duration := expireTime.Sub(currentTime)
+ err := p.store.Set(p.ctx, fmt.Sprintf("%s:%s", userId, key), token, duration).Err()
+ if err != nil {
+ p.dependencies.Log.Debug().Err(err).Msg("Error saving user session to redis")
+ return err
+ }
+ return nil
+}
+
+// GetUserSession returns the user session from redis store.
+func (p *provider) GetUserSession(userId, key string) (string, error) {
+ data, err := p.store.Get(p.ctx, fmt.Sprintf("%s:%s", userId, key)).Result()
+ if err != nil {
+ return "", err
+ }
+ return data, nil
+}
+
+// DeleteUserSession deletes the user session from redis store.
+func (p *provider) DeleteUserSession(userId, key string) error {
+ keys := []string{
+ constants.TokenTypeSessionToken + "_" + key,
+ constants.TokenTypeAccessToken + "_" + key,
+ constants.TokenTypeRefreshToken + "_" + key,
+ }
+ for _, k := range keys {
+ if err := p.store.Del(p.ctx, fmt.Sprintf("%s:%s", userId, k)).Err(); err != nil {
+ p.dependencies.Log.Debug().Err(err).Msg("Error deleting user session from redis")
+ // continue
+ }
+ }
+
+ return nil
+}
+
+// DeleteAllUserSessions deletes all the user session from redis
+func (p *provider) DeleteAllUserSessions(userID string) error {
+ res := p.store.Keys(p.ctx, fmt.Sprintf("*%s*", userID))
+ if res.Err() != nil {
+ p.dependencies.Log.Debug().Err(res.Err()).Msg("Error getting all user sessions from redis")
+ return res.Err()
+ }
+ keys := res.Val()
+ for _, key := range keys {
+ err := p.store.Del(p.ctx, key).Err()
+ if err != nil {
+ p.dependencies.Log.Debug().Err(err).Msg("Error deleting all user sessions from redis")
+ continue
+ }
+ }
+ return nil
+}
+
+// DeleteSessionForNamespace to delete session for a given namespace example google,github
+func (p *provider) DeleteSessionForNamespace(namespace string) error {
+ res := p.store.Keys(p.ctx, fmt.Sprintf("%s:*", namespace))
+ if res.Err() != nil {
+ p.dependencies.Log.Debug().Err(res.Err()).Msg("Error getting all user sessions from redis")
+ return res.Err()
+ }
+ keys := res.Val()
+ for _, key := range keys {
+ err := p.store.Del(p.ctx, key).Err()
+ if err != nil {
+ p.dependencies.Log.Debug().Err(err).Msg("Error deleting all user sessions from redis")
+ continue
+ }
+ }
+ return nil
+}
+
+// SetMfaSession sets the mfa session with key and value of userId
+func (p *provider) SetMfaSession(userId, key string, expiration int64) error {
+ currentTime := time.Now()
+ expireTime := time.Unix(expiration, 0)
+ duration := expireTime.Sub(currentTime)
+ err := p.store.Set(p.ctx, fmt.Sprintf("%s%s:%s", mfaSessionPrefix, userId, key), userId, duration).Err()
+ if err != nil {
+ p.dependencies.Log.Debug().Err(err).Msg("Error saving mfa session to redis")
+ return err
+ }
+ return nil
+}
+
+// GetMfaSession returns value of given mfa session
+func (p *provider) GetMfaSession(userId, key string) (string, error) {
+ data, err := p.store.Get(p.ctx, fmt.Sprintf("%s%s:%s", mfaSessionPrefix, userId, key)).Result()
+ if err != nil {
+ return "", err
+ }
+ return data, nil
+}
+
+// GetAllMfaSessions returns all mfa sessions for given userId
+func (p *provider) GetAllMfaSessions(userId string) ([]string, error) {
+ res := p.store.Keys(p.ctx, fmt.Sprintf("%s%s:*", mfaSessionPrefix, userId))
+ if res.Err() != nil {
+ p.dependencies.Log.Debug().Err(res.Err()).Msg("Error getting all mfa sessions from redis")
+ return nil, res.Err()
+ }
+ keys := res.Val()
+ for i := 0; i < len(keys); i++ {
+ keys[i] = keys[i][len(mfaSessionPrefix)+len(userId)+1:]
+ }
+ return keys, nil
+}
+
+// DeleteMfaSession deletes given mfa session from in-memory store.
+func (p *provider) DeleteMfaSession(userId, key string) error {
+ if err := p.store.Del(p.ctx, fmt.Sprintf("%s%s:%s", mfaSessionPrefix, userId, key)).Err(); err != nil {
+ p.dependencies.Log.Debug().Err(err).Msg("Error deleting mfa session from redis")
+ // continue
+ }
+ return nil
+}
+
+// SetState sets the state in redis store.
+func (p *provider) SetState(key, value string) error {
+ err := p.store.Set(p.ctx, stateStorePrefix+key, value, 0).Err()
+ if err != nil {
+ p.dependencies.Log.Debug().Err(err).Msg("Error saving state to redis")
+ return err
+ }
+
+ return nil
+}
+
+// GetState gets the state from redis store.
+func (p *provider) GetState(key string) (string, error) {
+ data, err := p.store.Get(p.ctx, stateStorePrefix+key).Result()
+ if err != nil {
+ p.dependencies.Log.Debug().Err(err).Msg("Error getting state from redis")
+ return "", err
+ }
+
+ return data, err
+}
+
+// RemoveState removes the state from redis store.
+func (p *provider) RemoveState(key string) error {
+ err := p.store.Del(p.ctx, stateStorePrefix+key).Err()
+ if err != nil {
+ p.dependencies.Log.Debug().Err(err).Msg("Error deleting state from redis")
+ return err
+ }
+
+ return nil
+}
+
+// GetAllData returns all the data from the session store
+// This is used for testing purposes only
+func (p *provider) GetAllData() (map[string]string, error) {
+ res := p.store.Keys(p.ctx, "*")
+ if res.Err() != nil {
+ p.dependencies.Log.Debug().Err(res.Err()).Msg("Error getting all data from redis")
+ return nil, res.Err()
+ }
+ keys := res.Val()
+ data := make(map[string]string)
+ for _, key := range keys {
+ val, err := p.store.Get(p.ctx, key).Result()
+ if err != nil {
+ p.dependencies.Log.Debug().Err(err).Msg("Error getting all data from redis")
+ continue
+ }
+ data[key] = val
+ }
+ return data, nil
+}
diff --git a/internal/oauth/get_oauth_config.go b/internal/oauth/get_oauth_config.go
new file mode 100644
index 000000000..d4b39eb56
--- /dev/null
+++ b/internal/oauth/get_oauth_config.go
@@ -0,0 +1,109 @@
+package oauth
+
+import (
+ "fmt"
+
+ "github.com/gin-gonic/gin"
+ "golang.org/x/oauth2"
+ "golang.org/x/oauth2/endpoints"
+
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/parsers"
+)
+
+// GetOAuthConfig returns the OAuth config for the given provider
+func (o *oauthProvider) GetOAuthConfig(ctx *gin.Context, provider string) (*oauth2.Config, error) {
+ hostname := parsers.GetHost(ctx)
+ redirectURL := fmt.Sprintf("%s/oauth_callback/%s", hostname, provider)
+ var clientID, clientSecret string
+ var endPoint *oauth2.Endpoint
+ var scopes []string
+ switch provider {
+ case constants.AuthRecipeMethodGoogle:
+ if o.GoogleClientID != "" && o.GoogleClientSecret != "" {
+ clientID = o.GoogleClientID
+ clientSecret = o.GoogleClientSecret
+ endPoint = &endpoints.Google
+ scopes = o.GoogleScopes
+ }
+ case constants.AuthRecipeMethodGithub:
+ if o.GithubClientID != "" && o.GithubClientSecret != "" {
+ clientID = o.GithubClientID
+ clientSecret = o.GithubClientSecret
+ endPoint = &endpoints.GitHub
+ scopes = o.GithubScopes
+ }
+ case constants.AuthRecipeMethodFacebook:
+ if o.FacebookClientID != "" && o.FacebookClientSecret != "" {
+ clientID = o.FacebookClientID
+ clientSecret = o.FacebookClientSecret
+ endPoint = &endpoints.Facebook
+ scopes = o.FacebookScopes
+ }
+ case constants.AuthRecipeMethodLinkedIn:
+ if o.LinkedinClientID != "" && o.LinkedinClientSecret != "" {
+ clientID = o.LinkedinClientID
+ clientSecret = o.LinkedinClientSecret
+ endPoint = &endpoints.LinkedIn
+ scopes = o.LinkedinScopes
+ }
+ case constants.AuthRecipeMethodApple:
+ if o.AppleClientID != "" && o.AppleClientSecret != "" {
+ clientID = o.AppleClientID
+ clientSecret = o.AppleClientSecret
+ endPoint = &endpoints.Apple
+ scopes = o.AppleScopes
+ }
+ case constants.AuthRecipeMethodTwitter:
+ if o.TwitterClientID != "" && o.TwitterClientSecret != "" {
+ clientID = o.TwitterClientID
+ clientSecret = o.TwitterClientSecret
+ endPoint = &endpoints.X
+ scopes = o.TwitterScopes
+ }
+ case constants.AuthRecipeMethodDiscord:
+ if o.DiscordClientID != "" && o.DiscordClientSecret != "" {
+ clientID = o.DiscordClientID
+ clientSecret = o.DiscordClientSecret
+ endPoint = &endpoints.Discord
+ scopes = o.DiscordScopes
+ }
+ case constants.AuthRecipeMethodMicrosoft:
+ if o.MicrosoftClientID != "" && o.MicrosoftClientSecret != "" {
+ ep := endpoints.AzureAD(o.MicrosoftTenantID)
+ clientID = o.MicrosoftClientID
+ clientSecret = o.MicrosoftClientSecret
+ endPoint = &ep
+ scopes = o.MicrosoftScopes
+ }
+ case constants.AuthRecipeMethodTwitch:
+ if o.TwitchClientID != "" && o.TwitchClientSecret != "" {
+ clientID = o.TwitchClientID
+ clientSecret = o.TwitchClientSecret
+ endPoint = &endpoints.Twitch
+ scopes = o.TwitchScopes
+ }
+ case constants.AuthRecipeMethodRoblox:
+ if o.RobloxClientID != "" && o.RobloxClientSecret != "" {
+ clientID = o.RobloxClientID
+ clientSecret = o.RobloxClientSecret
+ endPoint = &oauth2.Endpoint{
+ AuthURL: "https://apis.roblox.com/oauth/v1/authorize",
+ TokenURL: "https://apis.roblox.com/oauth/v1/token",
+ }
+ scopes = o.RobloxScopes
+ }
+ default:
+ return nil, fmt.Errorf("unsupported provider: %s", provider)
+ }
+ if clientID == "" || clientSecret == "" {
+ return nil, fmt.Errorf("client ID or client secret is empty for provider: %s", provider)
+ }
+ return &oauth2.Config{
+ ClientID: clientID,
+ ClientSecret: clientSecret,
+ RedirectURL: redirectURL,
+ Endpoint: *endPoint,
+ Scopes: scopes,
+ }, nil
+}
diff --git a/internal/oauth/provider.go b/internal/oauth/provider.go
new file mode 100644
index 000000000..928115c60
--- /dev/null
+++ b/internal/oauth/provider.go
@@ -0,0 +1,39 @@
+package oauth
+
+import (
+ "github.com/gin-gonic/gin"
+ "github.com/rs/zerolog"
+ "golang.org/x/oauth2"
+
+ "github.com/authorizerdev/authorizer/internal/config"
+)
+
+// Dependencies struct for memory store provider
+type Dependencies struct {
+ Log *zerolog.Logger
+}
+
+// oauthProvider is a struct that contains reference to the config and dependencies
+// It is used to initialize the OAuth providers
+type oauthProvider struct {
+ *config.Config
+ *Dependencies
+}
+
+// Ensure interface is implemented
+var _ Provider = &oauthProvider{}
+
+// Provider is the interface that provides the methods to interact with the oauth providers.
+type Provider interface {
+ // GetOAuthConfig returns the OAuth config for the given provider
+ GetOAuthConfig(ctx *gin.Context, provider string) (*oauth2.Config, error)
+}
+
+// New constructs a new graphql provider with given arguments
+func New(cfg *config.Config, deps *Dependencies) (Provider, error) {
+ g := &oauthProvider{
+ Config: cfg,
+ Dependencies: deps,
+ }
+ return g, nil
+}
diff --git a/server/parsers/url.go b/internal/parsers/url.go
similarity index 76%
rename from server/parsers/url.go
rename to internal/parsers/url.go
index 4eb067d8f..9a05ed300 100644
--- a/server/parsers/url.go
+++ b/internal/parsers/url.go
@@ -5,9 +5,6 @@ import (
"strings"
"github.com/gin-gonic/gin"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/memorystore"
)
// GetHost returns hostname from request context
@@ -15,15 +12,16 @@ import (
// 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)
- if err != nil {
- authorizerURL = ""
- }
- if authorizerURL != "" {
- return strings.TrimSuffix(authorizerURL, "/")
- }
-
- authorizerURL = c.Request.Header.Get("X-Authorizer-URL")
+ // TODO see how we can do based on config
+ // authorizerURL, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAuthorizerURL)
+ // if err != nil {
+ // authorizerURL = ""
+ // }
+ // if authorizerURL != "" {
+ // return strings.TrimSuffix(authorizerURL, "/")
+ // }
+
+ authorizerURL := c.Request.Header.Get("X-Authorizer-URL")
if authorizerURL != "" {
return strings.TrimSuffix(authorizerURL, "/")
}
@@ -93,9 +91,6 @@ func GetDomainName(uri string) string {
// GetAppURL to get /app url if not configured by user
func GetAppURL(gc *gin.Context) string {
- envAppURL, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAppURL)
- if envAppURL == "" || err != nil {
- envAppURL = GetHost(gc) + "/app"
- }
+ envAppURL := GetHost(gc) + "/app"
return envAppURL
}
diff --git a/server/refs/bool.go b/internal/refs/bool.go
similarity index 100%
rename from server/refs/bool.go
rename to internal/refs/bool.go
diff --git a/server/refs/int.go b/internal/refs/int.go
similarity index 100%
rename from server/refs/int.go
rename to internal/refs/int.go
diff --git a/server/refs/string.go b/internal/refs/string.go
similarity index 100%
rename from server/refs/string.go
rename to internal/refs/string.go
diff --git a/internal/server/http_routes.go b/internal/server/http_routes.go
new file mode 100644
index 000000000..8ecd88228
--- /dev/null
+++ b/internal/server/http_routes.go
@@ -0,0 +1,63 @@
+package server
+
+import (
+ "encoding/json"
+ "html/template"
+
+ "github.com/gin-gonic/gin"
+)
+
+// NewRouter creates new gin router
+func (s *server) NewRouter() *gin.Engine {
+ router := gin.New()
+
+ router.Use(s.Dependencies.HTTPProvider.LoggerMiddleware())
+ router.Use(s.Dependencies.HTTPProvider.ContextMiddleware())
+ router.Use(s.Dependencies.HTTPProvider.CORSMiddleware())
+ router.Use(s.Dependencies.HTTPProvider.ClientCheckMiddleware())
+
+ router.GET("/", s.Dependencies.HTTPProvider.RootHandler())
+ router.GET("/health", s.Dependencies.HTTPProvider.HealthHandler())
+ router.POST("/graphql", s.Dependencies.HTTPProvider.GraphqlHandler())
+ router.GET("/playground", s.Dependencies.HTTPProvider.PlaygroundHandler())
+ router.GET("/oauth_login/:oauth_provider", s.Dependencies.HTTPProvider.OAuthLoginHandler())
+ router.GET("/oauth_callback/:oauth_provider", s.Dependencies.HTTPProvider.OAuthCallbackHandler())
+ router.POST("/oauth_callback/:oauth_provider", s.Dependencies.HTTPProvider.OAuthCallbackHandler())
+ router.GET("/verify_email", s.Dependencies.HTTPProvider.VerifyEmailHandler())
+ // OPEN ID routes
+ router.GET("/.well-known/openid-configuration", s.Dependencies.HTTPProvider.OpenIDConfigurationHandler())
+ router.GET("/.well-known/jwks.json", s.Dependencies.HTTPProvider.JWKsHandler())
+ router.GET("/authorize", s.Dependencies.HTTPProvider.AuthorizeHandler())
+ router.GET("/userinfo", s.Dependencies.HTTPProvider.UserInfoHandler())
+ router.GET("/logout", s.Dependencies.HTTPProvider.LogoutHandler())
+ router.POST("/oauth/token", s.Dependencies.HTTPProvider.TokenHandler())
+ router.POST("/oauth/revoke", s.Dependencies.HTTPProvider.RevokeRefreshTokenHandler())
+
+ // Set up template functions for JSON encoding
+ router.SetFuncMap(template.FuncMap{
+ "json": func(v interface{}) template.JS {
+ a, _ := json.Marshal(v)
+ return template.JS(a)
+ },
+ })
+ router.LoadHTMLGlob("web/templates/*")
+ // // login page app related routes.
+ app := router.Group("/app")
+ {
+ app.Static("/favicon_io", "web/app/favicon_io")
+ app.Static("/build", "web/app/build")
+ app.GET("/", s.Dependencies.HTTPProvider.AppHandler())
+ app.GET("/:page", s.Dependencies.HTTPProvider.AppHandler())
+ }
+
+ // // dashboard related routes
+ dashboard := router.Group("/dashboard")
+ {
+ dashboard.Static("/favicon_io", "web/dashboard/favicon_io")
+ dashboard.Static("/build", "web/dashboard/build")
+ dashboard.Static("/public", "web/dashboard/public")
+ dashboard.GET("/", s.Dependencies.HTTPProvider.DashboardHandler())
+ dashboard.GET("/:page", s.Dependencies.HTTPProvider.DashboardHandler())
+ }
+ return router
+}
diff --git a/internal/server/server.go b/internal/server/server.go
new file mode 100644
index 000000000..3c361a63d
--- /dev/null
+++ b/internal/server/server.go
@@ -0,0 +1,60 @@
+package server
+
+import (
+ "context"
+ "fmt"
+
+ "github.com/rs/zerolog"
+
+ "github.com/authorizerdev/authorizer/internal/graphql"
+ "github.com/authorizerdev/authorizer/internal/http_handlers"
+)
+
+// Configuration of a server.
+type Config struct {
+ // Host address to accept requests on
+ Host string
+ // Port number to serve HTTP requests on
+ HTTPPort int
+ // Port number to serve Metrics requests on
+ MetricsPort int
+}
+
+// Dependencies for a server
+type Dependencies struct {
+ Log *zerolog.Logger
+ GraphQLProvider graphql.Provider
+ HTTPProvider http_handlers.Provider
+}
+
+// New constructs a new server with given arguments
+func New(cfg *Config, deps *Dependencies) (*server, error) {
+ s := &server{
+ Config: cfg,
+ Dependencies: deps,
+ }
+ return s, nil
+}
+
+// Network server
+type server struct {
+ Config *Config
+ Dependencies *Dependencies
+}
+
+// Run the server until the given context is canceled
+func (s *server) Run(ctx context.Context) error {
+ // Create new router
+ ginRouter := s.NewRouter()
+ // Start the server
+ go func() {
+ s.Dependencies.Log.Info().Str("host", s.Config.Host).Int("port", s.Config.HTTPPort).Msg("Starting HTTP server")
+ err := ginRouter.Run(s.Config.Host + ":" + fmt.Sprintf("%d", s.Config.HTTPPort))
+ if err != nil {
+ s.Dependencies.Log.Error().Err(err).Msg("HTTP server failed")
+ }
+ }()
+ // Wait until context closed
+ <-ctx.Done()
+ return nil
+}
diff --git a/internal/sms/provider.go b/internal/sms/provider.go
new file mode 100644
index 000000000..b5d95aec8
--- /dev/null
+++ b/internal/sms/provider.go
@@ -0,0 +1,33 @@
+package sms
+
+import (
+ "github.com/authorizerdev/authorizer/internal/config"
+ "github.com/authorizerdev/authorizer/internal/sms/twilio"
+ "github.com/rs/zerolog"
+)
+
+// Dependencies for sms provider
+type Dependencies struct {
+ Log *zerolog.Logger
+}
+
+// Provider interface to send sms
+type Provider interface {
+ // SendSMS sends sms
+ SendSMS(sendTo, messageBody string) error
+}
+
+// New returns a new sms provider
+func New(cfg *config.Config, deps *Dependencies) (Provider, error) {
+ var provider Provider
+ var err error
+ if cfg.TwilioAPIKey != "" && cfg.TwilioAPISecret != "" && cfg.TwilioAccountSID != "" && cfg.TwilioSender != "" {
+ provider, err = twilio.NewTwilioProvider(cfg, &twilio.Dependencies{
+ Log: deps.Log,
+ })
+ if err != nil {
+ return nil, err
+ }
+ }
+ return provider, nil
+}
diff --git a/internal/sms/twilio/provider.go b/internal/sms/twilio/provider.go
new file mode 100644
index 000000000..a91dcf189
--- /dev/null
+++ b/internal/sms/twilio/provider.go
@@ -0,0 +1,42 @@
+package twilio
+
+import (
+ "fmt"
+
+ "github.com/authorizerdev/authorizer/internal/config"
+ "github.com/rs/zerolog"
+)
+
+// Dependencies struct for twilio provider
+type Dependencies struct {
+ Log *zerolog.Logger
+}
+
+type provider struct {
+ config *config.Config
+ dependencies *Dependencies
+}
+
+// NewTwilioProvider returns a new twilio provider
+func NewTwilioProvider(cfg *config.Config, deps *Dependencies) (*provider, error) {
+ if cfg.TwilioAPIKey == "" {
+ deps.Log.Debug().Msg("missing twilio api key")
+ return nil, fmt.Errorf("missing twilio api key")
+ }
+ if cfg.TwilioAPISecret == "" {
+ deps.Log.Debug().Msg("missing twilio api secret")
+ return nil, fmt.Errorf("missing twilio api secret")
+ }
+ if cfg.TwilioSender == "" {
+ deps.Log.Debug().Msg("missing twilio sender")
+ return nil, fmt.Errorf("missing twilio sender")
+ }
+ if cfg.TwilioAccountSID == "" {
+ deps.Log.Debug().Msg("missing twilio account sid")
+ return nil, fmt.Errorf("missing twilio account sid")
+ }
+ return &provider{
+ config: cfg,
+ dependencies: deps,
+ }, nil
+}
diff --git a/internal/sms/twilio/sms.go b/internal/sms/twilio/sms.go
new file mode 100644
index 000000000..caf8a99bc
--- /dev/null
+++ b/internal/sms/twilio/sms.go
@@ -0,0 +1,26 @@
+package twilio
+
+import (
+ twilio "github.com/twilio/twilio-go"
+ api "github.com/twilio/twilio-go/rest/api/v2010"
+)
+
+// SendSMS util to send sms
+func (p *provider) SendSMS(sendTo, messageBody string) error {
+ client := twilio.NewRestClientWithParams(twilio.ClientParams{
+ Username: p.config.TwilioAPIKey,
+ Password: p.config.TwilioAPISecret,
+ AccountSid: p.config.TwilioAccountSID,
+ })
+ message := &api.CreateMessageParams{}
+ message.SetBody(messageBody)
+ message.SetFrom(p.config.TwilioSender)
+ message.SetTo(sendTo)
+ _, err := client.Api.CreateMessage(message)
+ if err != nil {
+ p.dependencies.Log.Debug().Err(err).Msg("error sending sms")
+ return err
+ }
+
+ return nil
+}
diff --git a/server/db/providers/arangodb/authenticator.go b/internal/storage/db/arangodb/authenticator.go
similarity index 75%
rename from server/db/providers/arangodb/authenticator.go
rename to internal/storage/db/arangodb/authenticator.go
index c701ebc73..c080fc02b 100644
--- a/server/db/providers/arangodb/authenticator.go
+++ b/internal/storage/db/arangodb/authenticator.go
@@ -5,14 +5,13 @@ import (
"fmt"
"time"
- "github.com/google/uuid"
-
arangoDriver "github.com/arangodb/go-driver"
+ "github.com/google/uuid"
- "github.com/authorizerdev/authorizer/server/db/models"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
-func (p *provider) AddAuthenticator(ctx context.Context, authenticators *models.Authenticator) (*models.Authenticator, error) {
+func (p *provider) AddAuthenticator(ctx context.Context, authenticators *schemas.Authenticator) (*schemas.Authenticator, error) {
exists, _ := p.GetAuthenticatorDetailsByUserId(ctx, authenticators.UserID, authenticators.Method)
if exists != nil {
return authenticators, nil
@@ -25,7 +24,7 @@ func (p *provider) AddAuthenticator(ctx context.Context, authenticators *models.
authenticators.CreatedAt = time.Now().Unix()
authenticators.UpdatedAt = time.Now().Unix()
- authenticatorsCollection, _ := p.db.Collection(ctx, models.Collections.Authenticators)
+ authenticatorsCollection, _ := p.db.Collection(ctx, schemas.Collections.Authenticators)
meta, err := authenticatorsCollection.CreateDocument(arangoDriver.WithOverwrite(ctx), authenticators)
if err != nil {
return nil, err
@@ -36,10 +35,10 @@ func (p *provider) AddAuthenticator(ctx context.Context, authenticators *models.
return authenticators, nil
}
-func (p *provider) UpdateAuthenticator(ctx context.Context, authenticators *models.Authenticator) (*models.Authenticator, error) {
+func (p *provider) UpdateAuthenticator(ctx context.Context, authenticators *schemas.Authenticator) (*schemas.Authenticator, error) {
authenticators.UpdatedAt = time.Now().Unix()
- collection, _ := p.db.Collection(ctx, models.Collections.Authenticators)
+ collection, _ := p.db.Collection(ctx, schemas.Collections.Authenticators)
meta, err := collection.UpdateDocument(ctx, authenticators.Key, authenticators)
if err != nil {
return nil, err
@@ -50,9 +49,9 @@ func (p *provider) UpdateAuthenticator(ctx context.Context, authenticators *mode
return authenticators, nil
}
-func (p *provider) GetAuthenticatorDetailsByUserId(ctx context.Context, userId string, authenticatorType string) (*models.Authenticator, error) {
- var authenticators *models.Authenticator
- query := fmt.Sprintf("FOR d in %s FILTER d.user_id == @user_id AND d.method == @method LIMIT 1 RETURN d", models.Collections.Authenticators)
+func (p *provider) GetAuthenticatorDetailsByUserId(ctx context.Context, userId string, authenticatorType string) (*schemas.Authenticator, error) {
+ var authenticators *schemas.Authenticator
+ query := fmt.Sprintf("FOR d in %s FILTER d.user_id == @user_id AND d.method == @method LIMIT 1 RETURN d", schemas.Collections.Authenticators)
bindVars := map[string]interface{}{
"user_id": userId,
"method": authenticatorType,
diff --git a/server/db/providers/arangodb/email_template.go b/internal/storage/db/arangodb/email_template.go
similarity index 62%
rename from server/db/providers/arangodb/email_template.go
rename to internal/storage/db/arangodb/email_template.go
index 30c0fd0b8..e5cded709 100644
--- a/server/db/providers/arangodb/email_template.go
+++ b/internal/storage/db/arangodb/email_template.go
@@ -6,13 +6,14 @@ import (
"time"
arangoDriver "github.com/arangodb/go-driver"
- "github.com/authorizerdev/authorizer/server/db/models"
- "github.com/authorizerdev/authorizer/server/graph/model"
"github.com/google/uuid"
+
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
// AddEmailTemplate to add EmailTemplate
-func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate *models.EmailTemplate) (*model.EmailTemplate, error) {
+func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate *schemas.EmailTemplate) (*schemas.EmailTemplate, error) {
if emailTemplate.ID == "" {
emailTemplate.ID = uuid.New().String()
emailTemplate.Key = emailTemplate.ID
@@ -20,63 +21,63 @@ func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate *models.E
emailTemplate.Key = emailTemplate.ID
emailTemplate.CreatedAt = time.Now().Unix()
emailTemplate.UpdatedAt = time.Now().Unix()
- emailTemplateCollection, _ := p.db.Collection(ctx, models.Collections.EmailTemplate)
- _, err := emailTemplateCollection.CreateDocument(ctx, emailTemplate)
+ emailTemplateCollection, _ := p.db.Collection(ctx, schemas.Collections.EmailTemplate)
+ meta, err := emailTemplateCollection.CreateDocument(ctx, emailTemplate)
if err != nil {
return nil, err
}
- return emailTemplate.AsAPIEmailTemplate(), nil
+
+ emailTemplate.Key = meta.Key
+ emailTemplate.ID = meta.ID.String()
+ return emailTemplate, nil
}
// UpdateEmailTemplate to update EmailTemplate
-func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate *models.EmailTemplate) (*model.EmailTemplate, error) {
+func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate *schemas.EmailTemplate) (*schemas.EmailTemplate, error) {
emailTemplate.UpdatedAt = time.Now().Unix()
- emailTemplateCollection, _ := p.db.Collection(ctx, models.Collections.EmailTemplate)
+ emailTemplateCollection, _ := p.db.Collection(ctx, schemas.Collections.EmailTemplate)
meta, err := emailTemplateCollection.UpdateDocument(ctx, emailTemplate.Key, emailTemplate)
if err != nil {
return nil, err
}
emailTemplate.Key = meta.Key
emailTemplate.ID = meta.ID.String()
- return emailTemplate.AsAPIEmailTemplate(), nil
+ return emailTemplate, nil
}
// ListEmailTemplates to list EmailTemplate
-func (p *provider) ListEmailTemplate(ctx context.Context, pagination *model.Pagination) (*model.EmailTemplates, error) {
- emailTemplates := []*model.EmailTemplate{}
- query := fmt.Sprintf("FOR d in %s SORT d.created_at DESC LIMIT %d, %d RETURN d", models.Collections.EmailTemplate, pagination.Offset, pagination.Limit)
+func (p *provider) ListEmailTemplate(ctx context.Context, pagination *model.Pagination) ([]*schemas.EmailTemplate, *model.Pagination, error) {
+ emailTemplates := []*schemas.EmailTemplate{}
+ query := fmt.Sprintf("FOR d in %s SORT d.created_at DESC LIMIT %d, %d RETURN d", schemas.Collections.EmailTemplate, pagination.Offset, pagination.Limit)
sctx := arangoDriver.WithQueryFullCount(ctx)
cursor, err := p.db.Query(sctx, query, nil)
if err != nil {
- return nil, err
+ return nil, nil, err
}
defer cursor.Close()
paginationClone := pagination
paginationClone.Total = cursor.Statistics().FullCount()
for {
- var emailTemplate *models.EmailTemplate
+ var emailTemplate *schemas.EmailTemplate
meta, err := cursor.ReadDocument(ctx, &emailTemplate)
if arangoDriver.IsNoMoreDocuments(err) {
break
} else if err != nil {
- return nil, err
+ return nil, nil, err
}
if meta.Key != "" {
- emailTemplates = append(emailTemplates, emailTemplate.AsAPIEmailTemplate())
+ emailTemplates = append(emailTemplates, emailTemplate)
}
}
- return &model.EmailTemplates{
- Pagination: paginationClone,
- EmailTemplates: emailTemplates,
- }, nil
+ return emailTemplates, paginationClone, nil
}
// GetEmailTemplateByID to get EmailTemplate by id
-func (p *provider) GetEmailTemplateByID(ctx context.Context, emailTemplateID string) (*model.EmailTemplate, error) {
- var emailTemplate *models.EmailTemplate
- query := fmt.Sprintf("FOR d in %s FILTER d._key == @email_template_id RETURN d", models.Collections.EmailTemplate)
+func (p *provider) GetEmailTemplateByID(ctx context.Context, emailTemplateID string) (*schemas.EmailTemplate, error) {
+ var emailTemplate *schemas.EmailTemplate
+ query := fmt.Sprintf("FOR d in %s FILTER d._id == @id RETURN d", schemas.Collections.EmailTemplate)
bindVars := map[string]interface{}{
- "email_template_id": emailTemplateID,
+ "id": emailTemplateID,
}
cursor, err := p.db.Query(ctx, query, bindVars)
if err != nil {
@@ -95,13 +96,13 @@ func (p *provider) GetEmailTemplateByID(ctx context.Context, emailTemplateID str
return nil, err
}
}
- return emailTemplate.AsAPIEmailTemplate(), nil
+ return emailTemplate, nil
}
// GetEmailTemplateByEventName to get EmailTemplate by event_name
-func (p *provider) GetEmailTemplateByEventName(ctx context.Context, eventName string) (*model.EmailTemplate, error) {
- var emailTemplate *models.EmailTemplate
- query := fmt.Sprintf("FOR d in %s FILTER d.event_name == @event_name RETURN d", models.Collections.EmailTemplate)
+func (p *provider) GetEmailTemplateByEventName(ctx context.Context, eventName string) (*schemas.EmailTemplate, error) {
+ var emailTemplate *schemas.EmailTemplate
+ query := fmt.Sprintf("FOR d in %s FILTER d.event_name == @event_name RETURN d", schemas.Collections.EmailTemplate)
bindVars := map[string]interface{}{
"event_name": eventName,
}
@@ -122,13 +123,13 @@ func (p *provider) GetEmailTemplateByEventName(ctx context.Context, eventName st
return nil, err
}
}
- return emailTemplate.AsAPIEmailTemplate(), nil
+ return emailTemplate, nil
}
// DeleteEmailTemplate to delete EmailTemplate
-func (p *provider) DeleteEmailTemplate(ctx context.Context, emailTemplate *model.EmailTemplate) error {
- eventTemplateCollection, _ := p.db.Collection(ctx, models.Collections.EmailTemplate)
- _, err := eventTemplateCollection.RemoveDocument(ctx, emailTemplate.ID)
+func (p *provider) DeleteEmailTemplate(ctx context.Context, emailTemplate *schemas.EmailTemplate) error {
+ eventTemplateCollection, _ := p.db.Collection(ctx, schemas.Collections.EmailTemplate)
+ _, err := eventTemplateCollection.RemoveDocument(ctx, emailTemplate.Key)
if err != nil {
return err
}
diff --git a/server/db/providers/arangodb/env.go b/internal/storage/db/arangodb/env.go
similarity index 68%
rename from server/db/providers/arangodb/env.go
rename to internal/storage/db/arangodb/env.go
index 27f7c25f5..bce36a19f 100644
--- a/server/db/providers/arangodb/env.go
+++ b/internal/storage/db/arangodb/env.go
@@ -8,11 +8,11 @@ import (
arangoDriver "github.com/arangodb/go-driver"
"github.com/google/uuid"
- "github.com/authorizerdev/authorizer/server/db/models"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
// AddEnv to save environment information in database
-func (p *provider) AddEnv(ctx context.Context, env *models.Env) (*models.Env, error) {
+func (p *provider) AddEnv(ctx context.Context, env *schemas.Env) (*schemas.Env, error) {
if env.ID == "" {
env.ID = uuid.New().String()
env.Key = env.ID
@@ -20,7 +20,7 @@ func (p *provider) AddEnv(ctx context.Context, env *models.Env) (*models.Env, er
env.CreatedAt = time.Now().Unix()
env.UpdatedAt = time.Now().Unix()
- configCollection, _ := p.db.Collection(ctx, models.Collections.Env)
+ configCollection, _ := p.db.Collection(ctx, schemas.Collections.Env)
meta, err := configCollection.CreateDocument(arangoDriver.WithOverwrite(ctx), env)
if err != nil {
return nil, err
@@ -31,9 +31,9 @@ func (p *provider) AddEnv(ctx context.Context, env *models.Env) (*models.Env, er
}
// UpdateEnv to update environment information in database
-func (p *provider) UpdateEnv(ctx context.Context, env *models.Env) (*models.Env, error) {
+func (p *provider) UpdateEnv(ctx context.Context, env *schemas.Env) (*schemas.Env, error) {
env.UpdatedAt = time.Now().Unix()
- collection, _ := p.db.Collection(ctx, models.Collections.Env)
+ collection, _ := p.db.Collection(ctx, schemas.Collections.Env)
meta, err := collection.UpdateDocument(ctx, env.Key, env)
if err != nil {
return nil, err
@@ -45,9 +45,9 @@ func (p *provider) UpdateEnv(ctx context.Context, env *models.Env) (*models.Env,
}
// GetEnv to get environment information from database
-func (p *provider) GetEnv(ctx context.Context) (*models.Env, error) {
- var env *models.Env
- query := fmt.Sprintf("FOR d in %s RETURN d", models.Collections.Env)
+func (p *provider) GetEnv(ctx context.Context) (*schemas.Env, error) {
+ var env *schemas.Env
+ query := fmt.Sprintf("FOR d in %s RETURN d", schemas.Collections.Env)
cursor, err := p.db.Query(ctx, query, nil)
if err != nil {
return nil, err
diff --git a/server/db/providers/arangodb/otp.go b/internal/storage/db/arangodb/otp.go
similarity index 75%
rename from server/db/providers/arangodb/otp.go
rename to internal/storage/db/arangodb/otp.go
index 3f8f46497..dec00b86e 100644
--- a/server/db/providers/arangodb/otp.go
+++ b/internal/storage/db/arangodb/otp.go
@@ -7,22 +7,23 @@ import (
"time"
"github.com/arangodb/go-driver"
- "github.com/authorizerdev/authorizer/server/db/models"
"github.com/google/uuid"
+
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
// UpsertOTP to add or update otp
-func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models.OTP, error) {
+func (p *provider) UpsertOTP(ctx context.Context, otpParam *schemas.OTP) (*schemas.OTP, error) {
// check if email or phone number is present
if otpParam.Email == "" && otpParam.PhoneNumber == "" {
return nil, errors.New("email or phone_number is required")
}
- uniqueField := models.FieldNameEmail
+ uniqueField := schemas.FieldNameEmail
if otpParam.Email == "" && otpParam.PhoneNumber != "" {
- uniqueField = models.FieldNamePhoneNumber
+ uniqueField = schemas.FieldNamePhoneNumber
}
- var otp *models.OTP
- if uniqueField == models.FieldNameEmail {
+ var otp *schemas.OTP
+ if uniqueField == schemas.FieldNameEmail {
otp, _ = p.GetOTPByEmail(ctx, otpParam.Email)
} else {
otp, _ = p.GetOTPByPhoneNumber(ctx, otpParam.PhoneNumber)
@@ -30,7 +31,7 @@ func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models
shouldCreate := false
if otp == nil {
id := uuid.NewString()
- otp = &models.OTP{
+ otp = &schemas.OTP{
ID: id,
Key: id,
Otp: otpParam.Otp,
@@ -45,7 +46,7 @@ func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models
otp.ExpiresAt = otpParam.ExpiresAt
}
otp.UpdatedAt = time.Now().Unix()
- otpCollection, _ := p.db.Collection(ctx, models.Collections.OTP)
+ otpCollection, _ := p.db.Collection(ctx, schemas.Collections.OTP)
var meta driver.DocumentMeta
var err error
if shouldCreate {
@@ -56,15 +57,16 @@ func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models
if err != nil {
return nil, err
}
+
otp.Key = meta.Key
otp.ID = meta.ID.String()
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 otp *models.OTP
- query := fmt.Sprintf("FOR d in %s FILTER d.email == @email RETURN d", models.Collections.OTP)
+func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*schemas.OTP, error) {
+ var otp *schemas.OTP
+ query := fmt.Sprintf("FOR d in %s FILTER d.email == @email RETURN d", schemas.Collections.OTP)
bindVars := map[string]interface{}{
"email": emailAddress,
}
@@ -89,9 +91,9 @@ func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*mod
}
// GetOTPByPhoneNumber to get otp for a given phone number
-func (p *provider) GetOTPByPhoneNumber(ctx context.Context, phoneNumber string) (*models.OTP, error) {
- var otp *models.OTP
- query := fmt.Sprintf("FOR d in %s FILTER d.phone_number == @phone_number RETURN d", models.Collections.OTP)
+func (p *provider) GetOTPByPhoneNumber(ctx context.Context, phoneNumber string) (*schemas.OTP, error) {
+ var otp *schemas.OTP
+ query := fmt.Sprintf("FOR d in %s FILTER d.phone_number == @phone_number RETURN d", schemas.Collections.OTP)
bindVars := map[string]interface{}{
"phone_number": phoneNumber,
}
@@ -116,9 +118,9 @@ func (p *provider) GetOTPByPhoneNumber(ctx context.Context, phoneNumber string)
}
// DeleteOTP to delete otp
-func (p *provider) DeleteOTP(ctx context.Context, otp *models.OTP) error {
- otpCollection, _ := p.db.Collection(ctx, models.Collections.OTP)
- _, err := otpCollection.RemoveDocument(ctx, otp.ID)
+func (p *provider) DeleteOTP(ctx context.Context, otp *schemas.OTP) error {
+ otpCollection, _ := p.db.Collection(ctx, schemas.Collections.OTP)
+ _, err := otpCollection.RemoveDocument(ctx, otp.Key)
if err != nil {
return err
}
diff --git a/server/db/providers/arangodb/provider.go b/internal/storage/db/arangodb/provider.go
similarity index 64%
rename from server/db/providers/arangodb/provider.go
rename to internal/storage/db/arangodb/provider.go
index f78712333..ec73503ee 100644
--- a/server/db/providers/arangodb/provider.go
+++ b/internal/storage/db/arangodb/provider.go
@@ -9,12 +9,21 @@ import (
arangoDriver "github.com/arangodb/go-driver"
"github.com/arangodb/go-driver/http"
- "github.com/authorizerdev/authorizer/server/db/models"
- "github.com/authorizerdev/authorizer/server/memorystore"
+ "github.com/rs/zerolog"
+
+ "github.com/authorizerdev/authorizer/internal/config"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
+// Dependencies struct the arangodb data store provider
+type Dependencies struct {
+ Log *zerolog.Logger
+}
+
type provider struct {
- db arangoDriver.Database
+ config *config.Config
+ dependencies *Dependencies
+ db arangoDriver.Database
}
// for this we need arangodb instance up and running
@@ -22,12 +31,12 @@ type provider struct {
// docker run -p 8529:8529 -e ARANGO_ROOT_PASSWORD=root arangodb/arangodb:3.8.4
// NewProvider to initialize arangodb connection
-func NewProvider() (*provider, error) {
+func NewProvider(cfg *config.Config, deps *Dependencies) (*provider, error) {
ctx := context.Background()
- dbURL := memorystore.RequiredEnvStoreObj.GetRequiredEnv().DatabaseURL
- dbUsername := memorystore.RequiredEnvStoreObj.GetRequiredEnv().DatabaseUsername
- dbPassword := memorystore.RequiredEnvStoreObj.GetRequiredEnv().DatabasePassword
- dbCACertificate := memorystore.RequiredEnvStoreObj.GetRequiredEnv().DatabaseCACert
+ dbURL := cfg.DatabaseURL
+ dbUsername := cfg.DatabaseUsername
+ dbPassword := cfg.DatabasePassword
+ dbCACertificate := cfg.DatabaseCACert
httpConfig := http.ConnectionConfig{
Endpoints: []string{dbURL},
}
@@ -62,7 +71,10 @@ func NewProvider() (*provider, error) {
return nil, err
}
var arangodb arangoDriver.Database
- dbName := memorystore.RequiredEnvStoreObj.GetRequiredEnv().DatabaseName
+ dbName := cfg.DatabaseName
+ if dbName == "" {
+ return nil, fmt.Errorf("database name is required")
+ }
arangodb_exists, err := arangoClient.DatabaseExists(ctx, dbName)
if err != nil {
return nil, err
@@ -78,17 +90,17 @@ func NewProvider() (*provider, error) {
return nil, err
}
}
- userCollectionExists, err := arangodb.CollectionExists(ctx, models.Collections.User)
+ userCollectionExists, err := arangodb.CollectionExists(ctx, schemas.Collections.User)
if err != nil {
return nil, err
}
if !userCollectionExists {
- _, err = arangodb.CreateCollection(ctx, models.Collections.User, nil)
+ _, err = arangodb.CreateCollection(ctx, schemas.Collections.User, nil)
if err != nil {
return nil, err
}
}
- userCollection, err := arangodb.Collection(ctx, models.Collections.User)
+ userCollection, err := arangodb.Collection(ctx, schemas.Collections.User)
if err != nil {
return nil, err
}
@@ -101,17 +113,17 @@ func NewProvider() (*provider, error) {
Sparse: true,
})
- verificationRequestCollectionExists, err := arangodb.CollectionExists(ctx, models.Collections.VerificationRequest)
+ verificationRequestCollectionExists, err := arangodb.CollectionExists(ctx, schemas.Collections.VerificationRequest)
if err != nil {
return nil, err
}
if !verificationRequestCollectionExists {
- _, err = arangodb.CreateCollection(ctx, models.Collections.VerificationRequest, nil)
+ _, err = arangodb.CreateCollection(ctx, schemas.Collections.VerificationRequest, nil)
if err != nil {
return nil, err
}
}
- verificationRequestCollection, err := arangodb.Collection(ctx, models.Collections.VerificationRequest)
+ verificationRequestCollection, err := arangodb.Collection(ctx, schemas.Collections.VerificationRequest)
if err != nil {
return nil, err
}
@@ -123,44 +135,44 @@ func NewProvider() (*provider, error) {
Sparse: true,
})
- sessionCollectionExists, err := arangodb.CollectionExists(ctx, models.Collections.Session)
+ sessionCollectionExists, err := arangodb.CollectionExists(ctx, schemas.Collections.Session)
if err != nil {
return nil, err
}
if !sessionCollectionExists {
- _, err = arangodb.CreateCollection(ctx, models.Collections.Session, nil)
+ _, err = arangodb.CreateCollection(ctx, schemas.Collections.Session, nil)
if err != nil {
return nil, err
}
}
- sessionCollection, err := arangodb.Collection(ctx, models.Collections.Session)
+ sessionCollection, err := arangodb.Collection(ctx, schemas.Collections.Session)
if err != nil {
return nil, err
}
sessionCollection.EnsureHashIndex(ctx, []string{"user_id"}, &arangoDriver.EnsureHashIndexOptions{
Sparse: true,
})
- envCollectionExists, err := arangodb.CollectionExists(ctx, models.Collections.Env)
+ envCollectionExists, err := arangodb.CollectionExists(ctx, schemas.Collections.Env)
if err != nil {
return nil, err
}
if !envCollectionExists {
- _, err = arangodb.CreateCollection(ctx, models.Collections.Env, nil)
+ _, err = arangodb.CreateCollection(ctx, schemas.Collections.Env, nil)
if err != nil {
return nil, err
}
}
- webhookCollectionExists, err := arangodb.CollectionExists(ctx, models.Collections.Webhook)
+ webhookCollectionExists, err := arangodb.CollectionExists(ctx, schemas.Collections.Webhook)
if err != nil {
return nil, err
}
if !webhookCollectionExists {
- _, err = arangodb.CreateCollection(ctx, models.Collections.Webhook, nil)
+ _, err = arangodb.CreateCollection(ctx, schemas.Collections.Webhook, nil)
if err != nil {
return nil, err
}
}
- webhookCollection, err := arangodb.Collection(ctx, models.Collections.Webhook)
+ webhookCollection, err := arangodb.Collection(ctx, schemas.Collections.Webhook)
if err != nil {
return nil, err
}
@@ -169,17 +181,17 @@ func NewProvider() (*provider, error) {
Sparse: true,
})
- webhookLogCollectionExists, err := arangodb.CollectionExists(ctx, models.Collections.WebhookLog)
+ webhookLogCollectionExists, err := arangodb.CollectionExists(ctx, schemas.Collections.WebhookLog)
if err != nil {
return nil, err
}
if !webhookLogCollectionExists {
- _, err = arangodb.CreateCollection(ctx, models.Collections.WebhookLog, nil)
+ _, err = arangodb.CreateCollection(ctx, schemas.Collections.WebhookLog, nil)
if err != nil {
return nil, err
}
}
- webhookLogCollection, err := arangodb.Collection(ctx, models.Collections.WebhookLog)
+ webhookLogCollection, err := arangodb.Collection(ctx, schemas.Collections.WebhookLog)
if err != nil {
return nil, err
}
@@ -187,17 +199,17 @@ func NewProvider() (*provider, error) {
Sparse: true,
})
- emailTemplateCollectionExists, err := arangodb.CollectionExists(ctx, models.Collections.EmailTemplate)
+ emailTemplateCollectionExists, err := arangodb.CollectionExists(ctx, schemas.Collections.EmailTemplate)
if err != nil {
return nil, err
}
if !emailTemplateCollectionExists {
- _, err = arangodb.CreateCollection(ctx, models.Collections.EmailTemplate, nil)
+ _, err = arangodb.CreateCollection(ctx, schemas.Collections.EmailTemplate, nil)
if err != nil {
return nil, err
}
}
- emailTemplateCollection, err := arangodb.Collection(ctx, models.Collections.EmailTemplate)
+ emailTemplateCollection, err := arangodb.Collection(ctx, schemas.Collections.EmailTemplate)
if err != nil {
return nil, err
}
@@ -206,37 +218,37 @@ func NewProvider() (*provider, error) {
Sparse: true,
})
- otpCollectionExists, err := arangodb.CollectionExists(ctx, models.Collections.OTP)
+ otpCollectionExists, err := arangodb.CollectionExists(ctx, schemas.Collections.OTP)
if err != nil {
return nil, err
}
if !otpCollectionExists {
- _, err = arangodb.CreateCollection(ctx, models.Collections.OTP, nil)
+ _, err = arangodb.CreateCollection(ctx, schemas.Collections.OTP, nil)
if err != nil {
return nil, err
}
}
- otpCollection, err := arangodb.Collection(ctx, models.Collections.OTP)
+ otpCollection, err := arangodb.Collection(ctx, schemas.Collections.OTP)
if err != nil {
return nil, err
}
- otpCollection.EnsureHashIndex(ctx, []string{models.FieldNameEmail, models.FieldNamePhoneNumber}, &arangoDriver.EnsureHashIndexOptions{
+ otpCollection.EnsureHashIndex(ctx, []string{schemas.FieldNameEmail, schemas.FieldNamePhoneNumber}, &arangoDriver.EnsureHashIndexOptions{
Unique: true,
Sparse: true,
})
//authenticators table define
- authenticatorsCollectionExists, err := arangodb.CollectionExists(ctx, models.Collections.Authenticators)
+ authenticatorsCollectionExists, err := arangodb.CollectionExists(ctx, schemas.Collections.Authenticators)
if err != nil {
return nil, err
}
if !authenticatorsCollectionExists {
- _, err = arangodb.CreateCollection(ctx, models.Collections.Authenticators, nil)
+ _, err = arangodb.CreateCollection(ctx, schemas.Collections.Authenticators, nil)
if err != nil {
return nil, err
}
}
- authenticatorsCollection, err := arangodb.Collection(ctx, models.Collections.Authenticators)
+ authenticatorsCollection, err := arangodb.Collection(ctx, schemas.Collections.Authenticators)
if err != nil {
return nil, err
}
@@ -245,6 +257,8 @@ func NewProvider() (*provider, error) {
})
return &provider{
- db: arangodb,
+ config: cfg,
+ dependencies: deps,
+ db: arangodb,
}, err
}
diff --git a/server/db/providers/arangodb/session.go b/internal/storage/db/arangodb/session.go
similarity index 64%
rename from server/db/providers/arangodb/session.go
rename to internal/storage/db/arangodb/session.go
index 5dc981d38..b3a9eeccb 100644
--- a/server/db/providers/arangodb/session.go
+++ b/internal/storage/db/arangodb/session.go
@@ -4,19 +4,17 @@ import (
"context"
"time"
- "github.com/authorizerdev/authorizer/server/db/models"
- "github.com/google/uuid"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
// AddSession to save session information in database
-func (p *provider) AddSession(ctx context.Context, session *models.Session) error {
+func (p *provider) AddSession(ctx context.Context, session *schemas.Session) error {
if session.ID == "" {
- session.ID = uuid.New().String()
session.Key = session.ID
}
session.CreatedAt = time.Now().Unix()
session.UpdatedAt = time.Now().Unix()
- sessionCollection, _ := p.db.Collection(ctx, models.Collections.Session)
+ sessionCollection, _ := p.db.Collection(ctx, schemas.Collections.Session)
_, err := sessionCollection.CreateDocument(ctx, session)
if err != nil {
return err
@@ -25,6 +23,7 @@ func (p *provider) AddSession(ctx context.Context, session *models.Session) erro
}
// DeleteSession to delete session information from database
+// TODO: Implement this function
func (p *provider) DeleteSession(ctx context.Context, userId string) error {
return nil
}
diff --git a/server/db/providers/arangodb/user.go b/internal/storage/db/arangodb/user.go
similarity index 73%
rename from server/db/providers/arangodb/user.go
rename to internal/storage/db/arangodb/user.go
index 5caca74a2..0477e1c58 100644
--- a/server/db/providers/arangodb/user.go
+++ b/internal/storage/db/arangodb/user.go
@@ -10,26 +10,20 @@ import (
arangoDriver "github.com/arangodb/go-driver"
"github.com/google/uuid"
- "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/authorizerdev/authorizer/server/refs"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/refs"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
// AddUser to save user information in database
-func (p *provider) AddUser(ctx context.Context, user *models.User) (*models.User, error) {
+func (p *provider) AddUser(ctx context.Context, user *schemas.User) (*schemas.User, error) {
if user.ID == "" {
user.ID = uuid.New().String()
user.Key = user.ID
}
if user.Roles == "" {
- defaultRoles, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyDefaultRoles)
- if err != nil {
- return nil, err
- }
- user.Roles = defaultRoles
+ user.Roles = strings.Join(p.config.DefaultRoles, ",")
}
if user.PhoneNumber != nil && strings.TrimSpace(refs.StringValue(user.PhoneNumber)) != "" {
@@ -44,7 +38,7 @@ func (p *provider) AddUser(ctx context.Context, user *models.User) (*models.User
user.CreatedAt = time.Now().Unix()
user.UpdatedAt = time.Now().Unix()
- userCollection, _ := p.db.Collection(ctx, models.Collections.User)
+ userCollection, _ := p.db.Collection(ctx, schemas.Collections.User)
meta, err := userCollection.CreateDocument(arangoDriver.WithOverwrite(ctx), user)
if err != nil {
return nil, err
@@ -56,10 +50,10 @@ func (p *provider) AddUser(ctx context.Context, user *models.User) (*models.User
}
// UpdateUser to update user information in database
-func (p *provider) UpdateUser(ctx context.Context, user *models.User) (*models.User, error) {
+func (p *provider) UpdateUser(ctx context.Context, user *schemas.User) (*schemas.User, error) {
user.UpdatedAt = time.Now().Unix()
- collection, _ := p.db.Collection(ctx, models.Collections.User)
+ collection, _ := p.db.Collection(ctx, schemas.Collections.User)
meta, err := collection.UpdateDocument(ctx, user.Key, user)
if err != nil {
return nil, err
@@ -71,13 +65,13 @@ func (p *provider) UpdateUser(ctx context.Context, user *models.User) (*models.U
}
// DeleteUser to delete user information from database
-func (p *provider) DeleteUser(ctx context.Context, user *models.User) error {
- collection, _ := p.db.Collection(ctx, models.Collections.User)
+func (p *provider) DeleteUser(ctx context.Context, user *schemas.User) error {
+ collection, _ := p.db.Collection(ctx, schemas.Collections.User)
_, err := collection.RemoveDocument(ctx, user.Key)
if err != nil {
return err
}
- query := fmt.Sprintf(`FOR d IN %s FILTER d.user_id == @user_id REMOVE { _key: d._key } IN %s`, models.Collections.Session, models.Collections.Session)
+ query := fmt.Sprintf(`FOR d IN %s FILTER d.user_id == @user_id REMOVE { _key: d._key } IN %s`, schemas.Collections.Session, schemas.Collections.Session)
bindVars := map[string]interface{}{
"user_id": user.Key,
}
@@ -90,40 +84,37 @@ func (p *provider) DeleteUser(ctx context.Context, user *models.User) error {
}
// ListUsers to get list of users from database
-func (p *provider) ListUsers(ctx context.Context, pagination *model.Pagination) (*model.Users, error) {
- var users []*model.User
+func (p *provider) ListUsers(ctx context.Context, pagination *model.Pagination) ([]*schemas.User, *model.Pagination, error) {
+ var users []*schemas.User
sctx := arangoDriver.WithQueryFullCount(ctx)
- query := fmt.Sprintf("FOR d in %s SORT d.created_at DESC LIMIT %d, %d RETURN d", models.Collections.User, pagination.Offset, pagination.Limit)
+ query := fmt.Sprintf("FOR d in %s SORT d.created_at DESC LIMIT %d, %d RETURN d", schemas.Collections.User, pagination.Offset, pagination.Limit)
cursor, err := p.db.Query(sctx, query, nil)
if err != nil {
- return nil, err
+ return nil, nil, err
}
defer cursor.Close()
paginationClone := pagination
paginationClone.Total = cursor.Statistics().FullCount()
for {
- var user *models.User
+ var user *schemas.User
meta, err := cursor.ReadDocument(ctx, &user)
if arangoDriver.IsNoMoreDocuments(err) {
break
} else if err != nil {
- return nil, err
+ return nil, nil, err
}
if meta.Key != "" {
- users = append(users, user.AsAPIUser())
+ users = append(users, user)
}
}
- return &model.Users{
- Pagination: paginationClone,
- Users: users,
- }, nil
+ return users, paginationClone, nil
}
// GetUserByEmail to get user information from database using email address
-func (p *provider) GetUserByEmail(ctx context.Context, email string) (*models.User, error) {
- var user *models.User
- query := fmt.Sprintf("FOR d in %s FILTER d.email == @email RETURN d", models.Collections.User)
+func (p *provider) GetUserByEmail(ctx context.Context, email string) (*schemas.User, error) {
+ var user *schemas.User
+ query := fmt.Sprintf("FOR d in %s FILTER d.email == @email RETURN d", schemas.Collections.User)
bindVars := map[string]interface{}{
"email": email,
}
@@ -148,9 +139,9 @@ func (p *provider) GetUserByEmail(ctx context.Context, email string) (*models.Us
}
// GetUserByID to get user information from database using user ID
-func (p *provider) GetUserByID(ctx context.Context, id string) (*models.User, error) {
- var user *models.User
- query := fmt.Sprintf("FOR d in %s FILTER d._id == @id LIMIT 1 RETURN d", models.Collections.User)
+func (p *provider) GetUserByID(ctx context.Context, id string) (*schemas.User, error) {
+ var user *schemas.User
+ query := fmt.Sprintf("FOR d in %s FILTER d._id == @id LIMIT 1 RETURN d", schemas.Collections.User)
bindVars := map[string]interface{}{
"id": id,
}
@@ -191,9 +182,9 @@ func (p *provider) UpdateUsers(ctx context.Context, data map[string]interface{},
}
keysArray = strings.Trim(keysArray, " ")
keysArray = strings.TrimSuffix(keysArray, ",")
- query = fmt.Sprintf("FOR u IN %s FILTER u._id IN [%s] UPDATE u._key with %s IN %s", models.Collections.User, keysArray, string(userInfoBytes), models.Collections.User)
+ query = fmt.Sprintf("FOR u IN %s FILTER u._id IN [%s] UPDATE u._key with %s IN %s", schemas.Collections.User, keysArray, string(userInfoBytes), schemas.Collections.User)
} else {
- query = fmt.Sprintf("FOR u IN %s UPDATE u._key with %s IN %s", models.Collections.User, string(userInfoBytes), models.Collections.User)
+ query = fmt.Sprintf("FOR u IN %s UPDATE u._key with %s IN %s", schemas.Collections.User, string(userInfoBytes), schemas.Collections.User)
}
_, err = p.db.Query(ctx, query, nil)
if err != nil {
@@ -203,9 +194,9 @@ func (p *provider) UpdateUsers(ctx context.Context, data map[string]interface{},
}
// GetUserByPhoneNumber to get user information from database using phone number
-func (p *provider) GetUserByPhoneNumber(ctx context.Context, phoneNumber string) (*models.User, error) {
- var user *models.User
- query := fmt.Sprintf("FOR d in %s FILTER d.phone_number == @phone_number RETURN d", models.Collections.User)
+func (p *provider) GetUserByPhoneNumber(ctx context.Context, phoneNumber string) (*schemas.User, error) {
+ var user *schemas.User
+ query := fmt.Sprintf("FOR d in %s FILTER d.phone_number == @phone_number RETURN d", schemas.Collections.User)
bindVars := map[string]interface{}{
"phone_number": phoneNumber,
}
diff --git a/server/db/providers/arangodb/verification_requests.go b/internal/storage/db/arangodb/verification_requests.go
similarity index 71%
rename from server/db/providers/arangodb/verification_requests.go
rename to internal/storage/db/arangodb/verification_requests.go
index 2b12a994d..00a4a59a1 100644
--- a/server/db/providers/arangodb/verification_requests.go
+++ b/internal/storage/db/arangodb/verification_requests.go
@@ -6,20 +6,21 @@ import (
"time"
arangoDriver "github.com/arangodb/go-driver"
- "github.com/authorizerdev/authorizer/server/db/models"
- "github.com/authorizerdev/authorizer/server/graph/model"
"github.com/google/uuid"
+
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
// AddVerification to save verification request in database
-func (p *provider) AddVerificationRequest(ctx context.Context, verificationRequest *models.VerificationRequest) (*models.VerificationRequest, error) {
+func (p *provider) AddVerificationRequest(ctx context.Context, verificationRequest *schemas.VerificationRequest) (*schemas.VerificationRequest, error) {
if verificationRequest.ID == "" {
verificationRequest.ID = uuid.New().String()
verificationRequest.Key = verificationRequest.ID
}
verificationRequest.CreatedAt = time.Now().Unix()
verificationRequest.UpdatedAt = time.Now().Unix()
- verificationRequestRequestCollection, _ := p.db.Collection(ctx, models.Collections.VerificationRequest)
+ verificationRequestRequestCollection, _ := p.db.Collection(ctx, schemas.Collections.VerificationRequest)
meta, err := verificationRequestRequestCollection.CreateDocument(ctx, verificationRequest)
if err != nil {
return nil, err
@@ -30,9 +31,9 @@ func (p *provider) AddVerificationRequest(ctx context.Context, verificationReque
}
// GetVerificationRequestByToken to get verification request from database using token
-func (p *provider) GetVerificationRequestByToken(ctx context.Context, token string) (*models.VerificationRequest, error) {
- var verificationRequest *models.VerificationRequest
- query := fmt.Sprintf("FOR d in %s FILTER d.token == @token LIMIT 1 RETURN d", models.Collections.VerificationRequest)
+func (p *provider) GetVerificationRequestByToken(ctx context.Context, token string) (*schemas.VerificationRequest, error) {
+ var verificationRequest *schemas.VerificationRequest
+ query := fmt.Sprintf("FOR d in %s FILTER d.token == @token LIMIT 1 RETURN d", schemas.Collections.VerificationRequest)
bindVars := map[string]interface{}{
"token": token,
}
@@ -57,9 +58,9 @@ func (p *provider) GetVerificationRequestByToken(ctx context.Context, token stri
}
// 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
- query := fmt.Sprintf("FOR d in %s FILTER d.email == @email FILTER d.identifier == @identifier LIMIT 1 RETURN d", models.Collections.VerificationRequest)
+func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email string, identifier string) (*schemas.VerificationRequest, error) {
+ var verificationRequest *schemas.VerificationRequest
+ query := fmt.Sprintf("FOR d in %s FILTER d.email == @email FILTER d.identifier == @identifier LIMIT 1 RETURN d", schemas.Collections.VerificationRequest)
bindVars := map[string]interface{}{
"email": email,
"identifier": identifier,
@@ -85,41 +86,38 @@ func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email stri
}
// ListVerificationRequests to get list of verification requests from database
-func (p *provider) ListVerificationRequests(ctx context.Context, pagination *model.Pagination) (*model.VerificationRequests, error) {
- var verificationRequests []*model.VerificationRequest
+func (p *provider) ListVerificationRequests(ctx context.Context, pagination *model.Pagination) ([]*schemas.VerificationRequest, *model.Pagination, error) {
+ var verificationRequests []*schemas.VerificationRequest
sctx := arangoDriver.WithQueryFullCount(ctx)
- query := fmt.Sprintf("FOR d in %s SORT d.created_at DESC LIMIT %d, %d RETURN d", models.Collections.VerificationRequest, pagination.Offset, pagination.Limit)
+ query := fmt.Sprintf("FOR d in %s SORT d.created_at DESC LIMIT %d, %d RETURN d", schemas.Collections.VerificationRequest, pagination.Offset, pagination.Limit)
cursor, err := p.db.Query(sctx, query, nil)
if err != nil {
- return nil, err
+ return nil, nil, err
}
defer cursor.Close()
paginationClone := pagination
paginationClone.Total = cursor.Statistics().FullCount()
for {
- var verificationRequest *models.VerificationRequest
+ var verificationRequest *schemas.VerificationRequest
meta, err := cursor.ReadDocument(ctx, &verificationRequest)
if arangoDriver.IsNoMoreDocuments(err) {
break
} else if err != nil {
- return nil, err
+ return nil, nil, err
}
if meta.Key != "" {
- verificationRequests = append(verificationRequests, verificationRequest.AsAPIVerificationRequest())
+ verificationRequests = append(verificationRequests, verificationRequest)
}
}
- return &model.VerificationRequests{
- VerificationRequests: verificationRequests,
- Pagination: paginationClone,
- }, nil
+ return verificationRequests, paginationClone, nil
}
// DeleteVerificationRequest to delete verification request from database
-func (p *provider) DeleteVerificationRequest(ctx context.Context, verificationRequest *models.VerificationRequest) error {
- collection, _ := p.db.Collection(ctx, models.Collections.VerificationRequest)
+func (p *provider) DeleteVerificationRequest(ctx context.Context, verificationRequest *schemas.VerificationRequest) error {
+ collection, _ := p.db.Collection(ctx, schemas.Collections.VerificationRequest)
_, err := collection.RemoveDocument(ctx, verificationRequest.Key)
if err != nil {
return err
diff --git a/server/db/providers/arangodb/webhook.go b/internal/storage/db/arangodb/webhook.go
similarity index 59%
rename from server/db/providers/arangodb/webhook.go
rename to internal/storage/db/arangodb/webhook.go
index dbdc9e4c4..5f348dff6 100644
--- a/server/db/providers/arangodb/webhook.go
+++ b/internal/storage/db/arangodb/webhook.go
@@ -6,15 +6,15 @@ import (
"strings"
"time"
- "github.com/arangodb/go-driver"
arangoDriver "github.com/arangodb/go-driver"
- "github.com/authorizerdev/authorizer/server/db/models"
- "github.com/authorizerdev/authorizer/server/graph/model"
"github.com/google/uuid"
+
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
// AddWebhook to add webhook
-func (p *provider) AddWebhook(ctx context.Context, webhook *models.Webhook) (*model.Webhook, error) {
+func (p *provider) AddWebhook(ctx context.Context, webhook *schemas.Webhook) (*schemas.Webhook, error) {
if webhook.ID == "" {
webhook.ID = uuid.New().String()
webhook.Key = webhook.ID
@@ -24,69 +24,67 @@ func (p *provider) AddWebhook(ctx context.Context, webhook *models.Webhook) (*mo
webhook.EventName = fmt.Sprintf("%s-%d", webhook.EventName, time.Now().Unix())
webhook.CreatedAt = time.Now().Unix()
webhook.UpdatedAt = time.Now().Unix()
- webhookCollection, _ := p.db.Collection(ctx, models.Collections.Webhook)
- _, err := webhookCollection.CreateDocument(ctx, webhook)
+ webhookCollection, _ := p.db.Collection(ctx, schemas.Collections.Webhook)
+ meta, err := webhookCollection.CreateDocument(ctx, webhook)
if err != nil {
return nil, err
}
- return webhook.AsAPIWebhook(), nil
+ webhook.Key = meta.Key
+ webhook.ID = meta.ID.String()
+ return webhook, nil
}
// UpdateWebhook to update webhook
-func (p *provider) UpdateWebhook(ctx context.Context, webhook *models.Webhook) (*model.Webhook, error) {
+func (p *provider) UpdateWebhook(ctx context.Context, webhook *schemas.Webhook) (*schemas.Webhook, error) {
webhook.UpdatedAt = time.Now().Unix()
// Event is changed
if !strings.Contains(webhook.EventName, "-") {
webhook.EventName = fmt.Sprintf("%s-%d", webhook.EventName, time.Now().Unix())
}
- webhookCollection, _ := p.db.Collection(ctx, models.Collections.Webhook)
+ webhookCollection, _ := p.db.Collection(ctx, schemas.Collections.Webhook)
meta, err := webhookCollection.UpdateDocument(ctx, webhook.Key, webhook)
if err != nil {
return nil, err
}
webhook.Key = meta.Key
webhook.ID = meta.ID.String()
- return webhook.AsAPIWebhook(), nil
+ return webhook, nil
}
// ListWebhooks to list webhook
-func (p *provider) ListWebhook(ctx context.Context, pagination *model.Pagination) (*model.Webhooks, error) {
- webhooks := []*model.Webhook{}
- query := fmt.Sprintf("FOR d in %s SORT d.created_at DESC LIMIT %d, %d RETURN d", models.Collections.Webhook, pagination.Offset, pagination.Limit)
+func (p *provider) ListWebhook(ctx context.Context, pagination *model.Pagination) ([]*schemas.Webhook, *model.Pagination, error) {
+ webhooks := []*schemas.Webhook{}
+ query := fmt.Sprintf("FOR d in %s SORT d.created_at DESC LIMIT %d, %d RETURN d", schemas.Collections.Webhook, pagination.Offset, pagination.Limit)
sctx := arangoDriver.WithQueryFullCount(ctx)
cursor, err := p.db.Query(sctx, query, nil)
if err != nil {
- return nil, err
+ return nil, nil, err
}
defer cursor.Close()
paginationClone := pagination
paginationClone.Total = cursor.Statistics().FullCount()
for {
- var webhook *models.Webhook
+ var webhook *schemas.Webhook
meta, err := cursor.ReadDocument(ctx, &webhook)
if arangoDriver.IsNoMoreDocuments(err) {
break
} else if err != nil {
- return nil, err
+ return nil, nil, err
}
if meta.Key != "" {
- webhooks = append(webhooks, webhook.AsAPIWebhook())
+ webhooks = append(webhooks, webhook)
}
}
-
- return &model.Webhooks{
- Pagination: paginationClone,
- Webhooks: webhooks,
- }, nil
+ return webhooks, paginationClone, nil
}
// GetWebhookByID to get webhook by id
-func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*model.Webhook, error) {
- var webhook *models.Webhook
- query := fmt.Sprintf("FOR d in %s FILTER d._key == @webhook_id RETURN d", models.Collections.Webhook)
+func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*schemas.Webhook, error) {
+ var webhook *schemas.Webhook
+ query := fmt.Sprintf("FOR d in %s FILTER d._id == @id RETURN d", schemas.Collections.Webhook)
bindVars := map[string]interface{}{
- "webhook_id": webhookID,
+ "id": webhookID,
}
cursor, err := p.db.Query(ctx, query, bindVars)
if err != nil {
@@ -105,12 +103,12 @@ func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*model
return nil, err
}
}
- return webhook.AsAPIWebhook(), nil
+ return webhook, nil
}
// GetWebhookByEventName to get webhook by event_name
-func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string) ([]*model.Webhook, error) {
- query := fmt.Sprintf("FOR d in %s FILTER d.event_name LIKE @event_name RETURN d", models.Collections.Webhook)
+func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string) ([]*schemas.Webhook, error) {
+ query := fmt.Sprintf("FOR d in %s FILTER d.event_name LIKE @event_name RETURN d", schemas.Collections.Webhook)
bindVars := map[string]interface{}{
"event_name": eventName + "%",
}
@@ -119,30 +117,30 @@ func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string)
return nil, err
}
defer cursor.Close()
- webhooks := []*model.Webhook{}
+ webhooks := []*schemas.Webhook{}
for {
- var webhook *models.Webhook
- if _, err := cursor.ReadDocument(ctx, &webhook); driver.IsNoMoreDocuments(err) {
+ var webhook *schemas.Webhook
+ if _, err := cursor.ReadDocument(ctx, &webhook); arangoDriver.IsNoMoreDocuments(err) {
// We're done
break
} else if err != nil {
return nil, err
}
- webhooks = append(webhooks, webhook.AsAPIWebhook())
+ webhooks = append(webhooks, webhook)
}
return webhooks, nil
}
// DeleteWebhook to delete webhook
-func (p *provider) DeleteWebhook(ctx context.Context, webhook *model.Webhook) error {
- webhookCollection, _ := p.db.Collection(ctx, models.Collections.Webhook)
- _, err := webhookCollection.RemoveDocument(ctx, webhook.ID)
+func (p *provider) DeleteWebhook(ctx context.Context, webhook *schemas.Webhook) error {
+ webhookCollection, _ := p.db.Collection(ctx, schemas.Collections.Webhook)
+ _, err := webhookCollection.RemoveDocument(ctx, webhook.Key)
if err != nil {
return err
}
- query := fmt.Sprintf("FOR d IN %s FILTER d.webhook_id == @webhook_id REMOVE { _key: d._key } IN %s", models.Collections.WebhookLog, models.Collections.WebhookLog)
+ query := fmt.Sprintf("FOR d IN %s FILTER d.webhook_id == @webhook_id REMOVE { _key: d._key } IN %s", schemas.Collections.WebhookLog, schemas.Collections.WebhookLog)
bindVars := map[string]interface{}{
- "webhook_id": webhook.ID,
+ "webhook_id": webhook.Key,
}
cursor, err := p.db.Query(ctx, query, bindVars)
if err != nil {
diff --git a/server/db/providers/arangodb/webhook_log.go b/internal/storage/db/arangodb/webhook_log.go
similarity index 61%
rename from server/db/providers/arangodb/webhook_log.go
rename to internal/storage/db/arangodb/webhook_log.go
index 64db2cb28..27bd5ba35 100644
--- a/server/db/providers/arangodb/webhook_log.go
+++ b/internal/storage/db/arangodb/webhook_log.go
@@ -6,13 +6,14 @@ import (
"time"
arangoDriver "github.com/arangodb/go-driver"
- "github.com/authorizerdev/authorizer/server/db/models"
- "github.com/authorizerdev/authorizer/server/graph/model"
"github.com/google/uuid"
+
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
// AddWebhookLog to add webhook log
-func (p *provider) AddWebhookLog(ctx context.Context, webhookLog *models.WebhookLog) (*model.WebhookLog, error) {
+func (p *provider) AddWebhookLog(ctx context.Context, webhookLog *schemas.WebhookLog) (*schemas.WebhookLog, error) {
if webhookLog.ID == "" {
webhookLog.ID = uuid.New().String()
webhookLog.Key = webhookLog.ID
@@ -20,21 +21,21 @@ func (p *provider) AddWebhookLog(ctx context.Context, webhookLog *models.Webhook
webhookLog.Key = webhookLog.ID
webhookLog.CreatedAt = time.Now().Unix()
webhookLog.UpdatedAt = time.Now().Unix()
- webhookLogCollection, _ := p.db.Collection(ctx, models.Collections.WebhookLog)
+ webhookLogCollection, _ := p.db.Collection(ctx, schemas.Collections.WebhookLog)
_, err := webhookLogCollection.CreateDocument(ctx, webhookLog)
if err != nil {
return nil, err
}
- return webhookLog.AsAPIWebhookLog(), nil
+ return webhookLog, nil
}
// ListWebhookLogs to list webhook logs
-func (p *provider) ListWebhookLogs(ctx context.Context, pagination *model.Pagination, webhookID string) (*model.WebhookLogs, error) {
- webhookLogs := []*model.WebhookLog{}
+func (p *provider) ListWebhookLogs(ctx context.Context, pagination *model.Pagination, webhookID string) ([]*schemas.WebhookLog, *model.Pagination, error) {
+ webhookLogs := []*schemas.WebhookLog{}
bindVariables := map[string]interface{}{}
- query := fmt.Sprintf("FOR d in %s SORT d.created_at DESC LIMIT %d, %d RETURN d", models.Collections.WebhookLog, pagination.Offset, pagination.Limit)
+ query := fmt.Sprintf("FOR d in %s SORT d.created_at DESC LIMIT %d, %d RETURN d", schemas.Collections.WebhookLog, pagination.Offset, pagination.Limit)
if webhookID != "" {
- query = fmt.Sprintf("FOR d in %s FILTER d.webhook_id == @webhook_id SORT d.created_at DESC LIMIT %d, %d RETURN d", models.Collections.WebhookLog, pagination.Offset, pagination.Limit)
+ query = fmt.Sprintf("FOR d in %s FILTER d.webhook_id == @webhook_id SORT d.created_at DESC LIMIT %d, %d RETURN d", schemas.Collections.WebhookLog, pagination.Offset, pagination.Limit)
bindVariables = map[string]interface{}{
"webhook_id": webhookID,
}
@@ -42,25 +43,22 @@ func (p *provider) ListWebhookLogs(ctx context.Context, pagination *model.Pagina
sctx := arangoDriver.WithQueryFullCount(ctx)
cursor, err := p.db.Query(sctx, query, bindVariables)
if err != nil {
- return nil, err
+ return nil, nil, err
}
defer cursor.Close()
paginationClone := pagination
paginationClone.Total = cursor.Statistics().FullCount()
for {
- var webhookLog *models.WebhookLog
+ var webhookLog *schemas.WebhookLog
meta, err := cursor.ReadDocument(ctx, &webhookLog)
if arangoDriver.IsNoMoreDocuments(err) {
break
} else if err != nil {
- return nil, err
+ return nil, nil, err
}
if meta.Key != "" {
- webhookLogs = append(webhookLogs, webhookLog.AsAPIWebhookLog())
+ webhookLogs = append(webhookLogs, webhookLog)
}
}
- return &model.WebhookLogs{
- Pagination: paginationClone,
- WebhookLogs: webhookLogs,
- }, nil
+ return webhookLogs, paginationClone, nil
}
diff --git a/server/db/providers/cassandradb/authenticator.go b/internal/storage/db/cassandradb/authenticator.go
similarity index 86%
rename from server/db/providers/cassandradb/authenticator.go
rename to internal/storage/db/cassandradb/authenticator.go
index 369a75aa6..6feca9dac 100644
--- a/server/db/providers/cassandradb/authenticator.go
+++ b/internal/storage/db/cassandradb/authenticator.go
@@ -11,10 +11,10 @@ import (
"github.com/gocql/gocql"
"github.com/google/uuid"
- "github.com/authorizerdev/authorizer/server/db/models"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
-func (p *provider) AddAuthenticator(ctx context.Context, authenticators *models.Authenticator) (*models.Authenticator, error) {
+func (p *provider) AddAuthenticator(ctx context.Context, authenticators *schemas.Authenticator) (*schemas.Authenticator, error) {
exists, _ := p.GetAuthenticatorDetailsByUserId(ctx, authenticators.UserID, authenticators.Method)
if exists != nil {
return authenticators, nil
@@ -63,7 +63,7 @@ func (p *provider) AddAuthenticator(ctx context.Context, authenticators *models.
fields = fields[:len(fields)-1] + ")"
values = values[:len(values)-1] + ")"
- query := fmt.Sprintf("INSERT INTO %s %s VALUES %s IF NOT EXISTS", KeySpace+"."+models.Collections.Authenticators, fields, values)
+ query := fmt.Sprintf("INSERT INTO %s %s VALUES %s IF NOT EXISTS", KeySpace+"."+schemas.Collections.Authenticators, fields, values)
err = p.db.Query(query).Exec()
if err != nil {
return nil, err
@@ -72,7 +72,7 @@ func (p *provider) AddAuthenticator(ctx context.Context, authenticators *models.
return authenticators, nil
}
-func (p *provider) UpdateAuthenticator(ctx context.Context, authenticators *models.Authenticator) (*models.Authenticator, error) {
+func (p *provider) UpdateAuthenticator(ctx context.Context, authenticators *schemas.Authenticator) (*schemas.Authenticator, error) {
authenticators.UpdatedAt = time.Now().Unix()
bytes, err := json.Marshal(authenticators)
@@ -113,7 +113,7 @@ func (p *provider) UpdateAuthenticator(ctx context.Context, authenticators *mode
updateFields = strings.Trim(updateFields, " ")
updateFields = strings.TrimSuffix(updateFields, ",")
- query := fmt.Sprintf("UPDATE %s SET %s WHERE id = '%s'", KeySpace+"."+models.Collections.Authenticators, updateFields, authenticators.ID)
+ query := fmt.Sprintf("UPDATE %s SET %s WHERE id = '%s'", KeySpace+"."+schemas.Collections.Authenticators, updateFields, authenticators.ID)
err = p.db.Query(query).Exec()
if err != nil {
return nil, err
@@ -122,9 +122,9 @@ func (p *provider) UpdateAuthenticator(ctx context.Context, authenticators *mode
return authenticators, nil
}
-func (p *provider) GetAuthenticatorDetailsByUserId(ctx context.Context, userId string, authenticatorType string) (*models.Authenticator, error) {
- var authenticators models.Authenticator
- query := fmt.Sprintf("SELECT id, user_id, method, secret, recovery_codes, verified_at, created_at, updated_at FROM %s WHERE user_id = '%s' AND method = '%s' LIMIT 1 ALLOW FILTERING", KeySpace+"."+models.Collections.Authenticators, userId, authenticatorType)
+func (p *provider) GetAuthenticatorDetailsByUserId(ctx context.Context, userId string, authenticatorType string) (*schemas.Authenticator, error) {
+ var authenticators schemas.Authenticator
+ query := fmt.Sprintf("SELECT id, user_id, method, secret, recovery_codes, verified_at, created_at, updated_at FROM %s WHERE user_id = '%s' AND method = '%s' LIMIT 1 ALLOW FILTERING", KeySpace+"."+schemas.Collections.Authenticators, userId, authenticatorType)
err := p.db.Query(query).Consistency(gocql.One).Scan(&authenticators.ID, &authenticators.UserID, &authenticators.Method, &authenticators.Secret, &authenticators.RecoveryCodes, &authenticators.VerifiedAt, &authenticators.CreatedAt, &authenticators.UpdatedAt)
if err != nil {
return nil, err
diff --git a/server/db/providers/cassandradb/email_template.go b/internal/storage/db/cassandradb/email_template.go
similarity index 71%
rename from server/db/providers/cassandradb/email_template.go
rename to internal/storage/db/cassandradb/email_template.go
index 9adb7687d..908dc1ff0 100644
--- a/server/db/providers/cassandradb/email_template.go
+++ b/internal/storage/db/cassandradb/email_template.go
@@ -8,14 +8,15 @@ import (
"strings"
"time"
- "github.com/authorizerdev/authorizer/server/db/models"
- "github.com/authorizerdev/authorizer/server/graph/model"
"github.com/gocql/gocql"
"github.com/google/uuid"
+
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
// AddEmailTemplate to add EmailTemplate
-func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate *models.EmailTemplate) (*model.EmailTemplate, error) {
+func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate *schemas.EmailTemplate) (*schemas.EmailTemplate, error) {
if emailTemplate.ID == "" {
emailTemplate.ID = uuid.New().String()
}
@@ -24,18 +25,18 @@ func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate *models.E
emailTemplate.UpdatedAt = time.Now().Unix()
existingEmailTemplate, _ := p.GetEmailTemplateByEventName(ctx, emailTemplate.EventName)
if existingEmailTemplate != nil {
- return nil, fmt.Errorf("Email template with %s event_name already exists", emailTemplate.EventName)
+ return nil, fmt.Errorf("email template with %s event_name already exists", emailTemplate.EventName)
}
- insertQuery := fmt.Sprintf("INSERT INTO %s (id, event_name, subject, design, template, created_at, updated_at) VALUES ('%s', '%s', '%s','%s','%s', %d, %d)", KeySpace+"."+models.Collections.EmailTemplate, emailTemplate.ID, emailTemplate.EventName, emailTemplate.Subject, emailTemplate.Design, emailTemplate.Template, emailTemplate.CreatedAt, emailTemplate.UpdatedAt)
+ insertQuery := fmt.Sprintf("INSERT INTO %s (id, event_name, subject, design, template, created_at, updated_at) VALUES ('%s', '%s', '%s','%s','%s', %d, %d)", KeySpace+"."+schemas.Collections.EmailTemplate, emailTemplate.ID, emailTemplate.EventName, emailTemplate.Subject, emailTemplate.Design, emailTemplate.Template, emailTemplate.CreatedAt, emailTemplate.UpdatedAt)
err := p.db.Query(insertQuery).Exec()
if err != nil {
return nil, err
}
- return emailTemplate.AsAPIEmailTemplate(), nil
+ return emailTemplate, nil
}
// UpdateEmailTemplate to update EmailTemplate
-func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate *models.EmailTemplate) (*model.EmailTemplate, error) {
+func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate *schemas.EmailTemplate) (*schemas.EmailTemplate, error) {
emailTemplate.UpdatedAt = time.Now().Unix()
bytes, err := json.Marshal(emailTemplate)
if err != nil {
@@ -71,76 +72,72 @@ func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate *model
updateFields = strings.Trim(updateFields, " ")
updateFields = strings.TrimSuffix(updateFields, ",")
- query := fmt.Sprintf("UPDATE %s SET %s WHERE id = '%s'", KeySpace+"."+models.Collections.EmailTemplate, updateFields, emailTemplate.ID)
+ query := fmt.Sprintf("UPDATE %s SET %s WHERE id = '%s'", KeySpace+"."+schemas.Collections.EmailTemplate, updateFields, emailTemplate.ID)
err = p.db.Query(query).Exec()
if err != nil {
return nil, err
}
- return emailTemplate.AsAPIEmailTemplate(), nil
+ return emailTemplate, nil
}
// ListEmailTemplates to list EmailTemplate
-func (p *provider) ListEmailTemplate(ctx context.Context, pagination *model.Pagination) (*model.EmailTemplates, error) {
- emailTemplates := []*model.EmailTemplate{}
+func (p *provider) ListEmailTemplate(ctx context.Context, pagination *model.Pagination) ([]*schemas.EmailTemplate, *model.Pagination, error) {
+ emailTemplates := []*schemas.EmailTemplate{}
paginationClone := pagination
- totalCountQuery := fmt.Sprintf(`SELECT COUNT(*) FROM %s`, KeySpace+"."+models.Collections.EmailTemplate)
+ totalCountQuery := fmt.Sprintf(`SELECT COUNT(*) FROM %s`, KeySpace+"."+schemas.Collections.EmailTemplate)
err := p.db.Query(totalCountQuery).Consistency(gocql.One).Scan(&paginationClone.Total)
if err != nil {
- return nil, err
+ return nil, nil, err
}
// there is no offset in cassandra
// so we fetch till limit + offset
// and return the results from offset to limit
- query := fmt.Sprintf("SELECT id, event_name, subject, design, template, created_at, updated_at FROM %s LIMIT %d", KeySpace+"."+models.Collections.EmailTemplate, pagination.Limit+pagination.Offset)
+ query := fmt.Sprintf("SELECT id, event_name, subject, design, template, created_at, updated_at FROM %s LIMIT %d", KeySpace+"."+schemas.Collections.EmailTemplate, pagination.Limit+pagination.Offset)
scanner := p.db.Query(query).Iter().Scanner()
counter := int64(0)
for scanner.Next() {
if counter >= pagination.Offset {
- var emailTemplate models.EmailTemplate
+ var emailTemplate schemas.EmailTemplate
err := scanner.Scan(&emailTemplate.ID, &emailTemplate.EventName, &emailTemplate.Subject, &emailTemplate.Design, &emailTemplate.Template, &emailTemplate.CreatedAt, &emailTemplate.UpdatedAt)
if err != nil {
- return nil, err
+ return nil, nil, err
}
- emailTemplates = append(emailTemplates, emailTemplate.AsAPIEmailTemplate())
+ emailTemplates = append(emailTemplates, &emailTemplate)
}
counter++
}
-
- return &model.EmailTemplates{
- Pagination: paginationClone,
- EmailTemplates: emailTemplates,
- }, nil
+ return emailTemplates, paginationClone, nil
}
// GetEmailTemplateByID to get EmailTemplate by id
-func (p *provider) GetEmailTemplateByID(ctx context.Context, emailTemplateID string) (*model.EmailTemplate, error) {
- var emailTemplate models.EmailTemplate
- query := fmt.Sprintf(`SELECT id, event_name, subject, design, template, created_at, updated_at FROM %s WHERE id = '%s' LIMIT 1`, KeySpace+"."+models.Collections.EmailTemplate, emailTemplateID)
+func (p *provider) GetEmailTemplateByID(ctx context.Context, emailTemplateID string) (*schemas.EmailTemplate, error) {
+ var emailTemplate schemas.EmailTemplate
+ query := fmt.Sprintf(`SELECT id, event_name, subject, design, template, created_at, updated_at FROM %s WHERE id = '%s' LIMIT 1`, KeySpace+"."+schemas.Collections.EmailTemplate, emailTemplateID)
err := p.db.Query(query).Consistency(gocql.One).Scan(&emailTemplate.ID, &emailTemplate.EventName, &emailTemplate.Subject, &emailTemplate.Design, &emailTemplate.Template, &emailTemplate.CreatedAt, &emailTemplate.UpdatedAt)
if err != nil {
return nil, err
}
- return emailTemplate.AsAPIEmailTemplate(), nil
+ return &emailTemplate, nil
}
// GetEmailTemplateByEventName to get EmailTemplate by event_name
-func (p *provider) GetEmailTemplateByEventName(ctx context.Context, eventName string) (*model.EmailTemplate, error) {
- var emailTemplate models.EmailTemplate
- query := fmt.Sprintf(`SELECT id, event_name, subject, design, template, created_at, updated_at FROM %s WHERE event_name = '%s' LIMIT 1 ALLOW FILTERING`, KeySpace+"."+models.Collections.EmailTemplate, eventName)
+func (p *provider) GetEmailTemplateByEventName(ctx context.Context, eventName string) (*schemas.EmailTemplate, error) {
+ var emailTemplate schemas.EmailTemplate
+ query := fmt.Sprintf(`SELECT id, event_name, subject, design, template, created_at, updated_at FROM %s WHERE event_name = '%s' LIMIT 1 ALLOW FILTERING`, KeySpace+"."+schemas.Collections.EmailTemplate, eventName)
err := p.db.Query(query).Consistency(gocql.One).Scan(&emailTemplate.ID, &emailTemplate.EventName, &emailTemplate.Subject, &emailTemplate.Design, &emailTemplate.Template, &emailTemplate.CreatedAt, &emailTemplate.UpdatedAt)
if err != nil {
return nil, err
}
- return emailTemplate.AsAPIEmailTemplate(), nil
+ return &emailTemplate, nil
}
// DeleteEmailTemplate to delete EmailTemplate
-func (p *provider) DeleteEmailTemplate(ctx context.Context, emailTemplate *model.EmailTemplate) error {
- query := fmt.Sprintf("DELETE FROM %s WHERE id = '%s'", KeySpace+"."+models.Collections.EmailTemplate, emailTemplate.ID)
+func (p *provider) DeleteEmailTemplate(ctx context.Context, emailTemplate *schemas.EmailTemplate) error {
+ query := fmt.Sprintf("DELETE FROM %s WHERE id = '%s'", KeySpace+"."+schemas.Collections.EmailTemplate, emailTemplate.ID)
err := p.db.Query(query).Exec()
if err != nil {
return err
diff --git a/server/db/providers/cassandradb/env.go b/internal/storage/db/cassandradb/env.go
similarity index 64%
rename from server/db/providers/cassandradb/env.go
rename to internal/storage/db/cassandradb/env.go
index 627403dcc..b8acdc469 100644
--- a/server/db/providers/cassandradb/env.go
+++ b/internal/storage/db/cassandradb/env.go
@@ -5,19 +5,20 @@ import (
"fmt"
"time"
- "github.com/authorizerdev/authorizer/server/db/models"
"github.com/gocql/gocql"
"github.com/google/uuid"
+
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
// AddEnv to save environment information in database
-func (p *provider) AddEnv(ctx context.Context, env *models.Env) (*models.Env, error) {
+func (p *provider) AddEnv(ctx context.Context, env *schemas.Env) (*schemas.Env, error) {
if env.ID == "" {
env.ID = uuid.New().String()
}
env.CreatedAt = time.Now().Unix()
env.UpdatedAt = time.Now().Unix()
- insertEnvQuery := fmt.Sprintf("INSERT INTO %s (id, env, hash, created_at, updated_at) VALUES ('%s', '%s', '%s', %d, %d)", KeySpace+"."+models.Collections.Env, env.ID, env.EnvData, env.Hash, env.CreatedAt, env.UpdatedAt)
+ insertEnvQuery := fmt.Sprintf("INSERT INTO %s (id, env, hash, created_at, updated_at) VALUES ('%s', '%s', '%s', %d, %d)", KeySpace+"."+schemas.Collections.Env, env.ID, env.EnvData, env.Hash, env.CreatedAt, env.UpdatedAt)
err := p.db.Query(insertEnvQuery).Exec()
if err != nil {
return nil, err
@@ -27,9 +28,9 @@ func (p *provider) AddEnv(ctx context.Context, env *models.Env) (*models.Env, er
}
// UpdateEnv to update environment information in database
-func (p *provider) UpdateEnv(ctx context.Context, env *models.Env) (*models.Env, error) {
+func (p *provider) UpdateEnv(ctx context.Context, env *schemas.Env) (*schemas.Env, error) {
env.UpdatedAt = time.Now().Unix()
- updateEnvQuery := fmt.Sprintf("UPDATE %s SET env = '%s', updated_at = %d WHERE id = '%s'", KeySpace+"."+models.Collections.Env, env.EnvData, env.UpdatedAt, env.ID)
+ updateEnvQuery := fmt.Sprintf("UPDATE %s SET env = '%s', updated_at = %d WHERE id = '%s'", KeySpace+"."+schemas.Collections.Env, env.EnvData, env.UpdatedAt, env.ID)
err := p.db.Query(updateEnvQuery).Exec()
if err != nil {
return nil, err
@@ -38,9 +39,9 @@ func (p *provider) UpdateEnv(ctx context.Context, env *models.Env) (*models.Env,
}
// GetEnv to get environment information from database
-func (p *provider) GetEnv(ctx context.Context) (*models.Env, error) {
- var env models.Env
- query := fmt.Sprintf("SELECT id, env, hash, created_at, updated_at FROM %s LIMIT 1", KeySpace+"."+models.Collections.Env)
+func (p *provider) GetEnv(ctx context.Context) (*schemas.Env, error) {
+ var env schemas.Env
+ query := fmt.Sprintf("SELECT id, env, hash, created_at, updated_at FROM %s LIMIT 1", KeySpace+"."+schemas.Collections.Env)
err := p.db.Query(query).Consistency(gocql.One).Scan(&env.ID, &env.EnvData, &env.Hash, &env.CreatedAt, &env.UpdatedAt)
if err != nil {
return nil, err
diff --git a/server/db/providers/cassandradb/otp.go b/internal/storage/db/cassandradb/otp.go
similarity index 70%
rename from server/db/providers/cassandradb/otp.go
rename to internal/storage/db/cassandradb/otp.go
index e4532426c..aa3a6f219 100644
--- a/server/db/providers/cassandradb/otp.go
+++ b/internal/storage/db/cassandradb/otp.go
@@ -6,23 +6,24 @@ import (
"fmt"
"time"
- "github.com/authorizerdev/authorizer/server/db/models"
"github.com/gocql/gocql"
"github.com/google/uuid"
+
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
// UpsertOTP to add or update otp
-func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models.OTP, error) {
+func (p *provider) UpsertOTP(ctx context.Context, otpParam *schemas.OTP) (*schemas.OTP, error) {
// check if email or phone number is present
if otpParam.Email == "" && otpParam.PhoneNumber == "" {
return nil, errors.New("email or phone_number is required")
}
- uniqueField := models.FieldNameEmail
+ uniqueField := schemas.FieldNameEmail
if otpParam.Email == "" && otpParam.PhoneNumber != "" {
- uniqueField = models.FieldNamePhoneNumber
+ uniqueField = schemas.FieldNamePhoneNumber
}
- var otp *models.OTP
- if uniqueField == models.FieldNameEmail {
+ var otp *schemas.OTP
+ if uniqueField == schemas.FieldNameEmail {
otp, _ = p.GetOTPByEmail(ctx, otpParam.Email)
} else {
otp, _ = p.GetOTPByPhoneNumber(ctx, otpParam.PhoneNumber)
@@ -30,7 +31,7 @@ func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models
shouldCreate := false
if otp == nil {
shouldCreate = true
- otp = &models.OTP{
+ otp = &schemas.OTP{
ID: uuid.NewString(),
Otp: otpParam.Otp,
Email: otpParam.Email,
@@ -47,9 +48,9 @@ func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models
otp.UpdatedAt = time.Now().Unix()
query := ""
if shouldCreate {
- query = fmt.Sprintf(`INSERT INTO %s (id, email, phone_number, otp, expires_at, created_at, updated_at) VALUES ('%s', '%s', '%s', '%s', %d, %d, %d)`, KeySpace+"."+models.Collections.OTP, otp.ID, otp.Email, otp.PhoneNumber, otp.Otp, otp.ExpiresAt, otp.CreatedAt, otp.UpdatedAt)
+ query = fmt.Sprintf(`INSERT INTO %s (id, email, phone_number, otp, expires_at, created_at, updated_at) VALUES ('%s', '%s', '%s', '%s', %d, %d, %d)`, KeySpace+"."+schemas.Collections.OTP, otp.ID, otp.Email, otp.PhoneNumber, otp.Otp, otp.ExpiresAt, otp.CreatedAt, otp.UpdatedAt)
} else {
- query = fmt.Sprintf(`UPDATE %s SET otp = '%s', expires_at = %d, updated_at = %d WHERE id = '%s'`, KeySpace+"."+models.Collections.OTP, otp.Otp, otp.ExpiresAt, otp.UpdatedAt, otp.ID)
+ query = fmt.Sprintf(`UPDATE %s SET otp = '%s', expires_at = %d, updated_at = %d WHERE id = '%s'`, KeySpace+"."+schemas.Collections.OTP, otp.Otp, otp.ExpiresAt, otp.UpdatedAt, otp.ID)
}
err := p.db.Query(query).Exec()
@@ -61,9 +62,9 @@ func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models
}
// GetOTPByEmail to get otp for a given email address
-func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*models.OTP, error) {
- var otp models.OTP
- query := fmt.Sprintf(`SELECT id, email, phone_number, otp, expires_at, created_at, updated_at FROM %s WHERE email = '%s' LIMIT 1 ALLOW FILTERING`, KeySpace+"."+models.Collections.OTP, emailAddress)
+func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*schemas.OTP, error) {
+ var otp schemas.OTP
+ query := fmt.Sprintf(`SELECT id, email, phone_number, otp, expires_at, created_at, updated_at FROM %s WHERE email = '%s' LIMIT 1 ALLOW FILTERING`, KeySpace+"."+schemas.Collections.OTP, emailAddress)
err := p.db.Query(query).Consistency(gocql.One).Scan(&otp.ID, &otp.Email, &otp.PhoneNumber, &otp.Otp, &otp.ExpiresAt, &otp.CreatedAt, &otp.UpdatedAt)
if err != nil {
return nil, err
@@ -72,9 +73,9 @@ func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*mod
}
// GetOTPByPhoneNumber to get otp for a given phone number
-func (p *provider) GetOTPByPhoneNumber(ctx context.Context, phoneNumber string) (*models.OTP, error) {
- var otp models.OTP
- query := fmt.Sprintf(`SELECT id, email, phone_number, otp, expires_at, created_at, updated_at FROM %s WHERE phone_number = '%s' LIMIT 1 ALLOW FILTERING`, KeySpace+"."+models.Collections.OTP, phoneNumber)
+func (p *provider) GetOTPByPhoneNumber(ctx context.Context, phoneNumber string) (*schemas.OTP, error) {
+ var otp schemas.OTP
+ query := fmt.Sprintf(`SELECT id, email, phone_number, otp, expires_at, created_at, updated_at FROM %s WHERE phone_number = '%s' LIMIT 1 ALLOW FILTERING`, KeySpace+"."+schemas.Collections.OTP, phoneNumber)
err := p.db.Query(query).Consistency(gocql.One).Scan(&otp.ID, &otp.Email, &otp.PhoneNumber, &otp.Otp, &otp.ExpiresAt, &otp.CreatedAt, &otp.UpdatedAt)
if err != nil {
return nil, err
@@ -83,8 +84,8 @@ func (p *provider) GetOTPByPhoneNumber(ctx context.Context, phoneNumber string)
}
// DeleteOTP to delete otp
-func (p *provider) DeleteOTP(ctx context.Context, otp *models.OTP) error {
- query := fmt.Sprintf("DELETE FROM %s WHERE id = '%s'", KeySpace+"."+models.Collections.OTP, otp.ID)
+func (p *provider) DeleteOTP(ctx context.Context, otp *schemas.OTP) error {
+ query := fmt.Sprintf("DELETE FROM %s WHERE id = '%s'", KeySpace+"."+schemas.Collections.OTP, otp.ID)
err := p.db.Query(query).Exec()
if err != nil {
return err
diff --git a/server/db/providers/cassandradb/provider.go b/internal/storage/db/cassandradb/provider.go
similarity index 72%
rename from server/db/providers/cassandradb/provider.go
rename to internal/storage/db/cassandradb/provider.go
index 431b8fe72..e1a142e76 100644
--- a/server/db/providers/cassandradb/provider.go
+++ b/internal/storage/db/cassandradb/provider.go
@@ -7,38 +7,44 @@ import (
"strings"
"time"
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/crypto"
- "github.com/authorizerdev/authorizer/server/db/models"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/gocql/gocql"
cansandraDriver "github.com/gocql/gocql"
- log "github.com/sirupsen/logrus"
+ "github.com/rs/zerolog"
+
+ "github.com/authorizerdev/authorizer/internal/config"
+ "github.com/authorizerdev/authorizer/internal/crypto"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
+// Dependencies struct the cassandradb data store provider
+type Dependencies struct {
+ Log *zerolog.Logger
+}
+
type provider struct {
- db *cansandraDriver.Session
+ config *config.Config
+ dependencies *Dependencies
+ db *cansandraDriver.Session
}
// KeySpace for the cassandra database
var KeySpace string
// NewProvider to initialize arangodb connection
-func NewProvider() (*provider, error) {
- dbURL := memorystore.RequiredEnvStoreObj.GetRequiredEnv().DatabaseURL
+func NewProvider(cfg *config.Config, deps *Dependencies) (*provider, error) {
+ dbURL := cfg.DatabaseURL
if dbURL == "" {
- dbHost := memorystore.RequiredEnvStoreObj.GetRequiredEnv().DatabaseHost
- dbPort := memorystore.RequiredEnvStoreObj.GetRequiredEnv().DatabasePort
- if dbPort != "" && dbHost != "" {
- dbURL = fmt.Sprintf("%s:%s", dbHost, dbPort)
+ dbHost := cfg.DatabaseHost
+ dbPort := cfg.DatabasePort
+ if dbPort != 0 && dbHost != "" {
+ dbURL = fmt.Sprintf("%s:%d", dbHost, dbPort)
} else if dbHost != "" {
dbURL = dbHost
}
}
- KeySpace = memorystore.RequiredEnvStoreObj.GetRequiredEnv().DatabaseName
+ KeySpace = cfg.DatabaseName
if KeySpace == "" {
- KeySpace = constants.EnvKeyDatabaseName
+ return nil, fmt.Errorf("database name is required for cassandra. It is used as keyspace in case of cassandra")
}
clusterURL := []string{}
if strings.Contains(dbURL, ",") {
@@ -47,8 +53,8 @@ func NewProvider() (*provider, error) {
clusterURL = append(clusterURL, dbURL)
}
cassandraClient := cansandraDriver.NewCluster(clusterURL...)
- dbUsername := memorystore.RequiredEnvStoreObj.GetRequiredEnv().DatabaseUsername
- dbPassword := memorystore.RequiredEnvStoreObj.GetRequiredEnv().DatabasePassword
+ dbUsername := cfg.DatabaseUsername
+ dbPassword := cfg.DatabasePassword
if dbUsername != "" && dbPassword != "" {
cassandraClient.Authenticator = &cansandraDriver.PasswordAuthenticator{
@@ -57,9 +63,9 @@ func NewProvider() (*provider, error) {
}
}
- dbCert := memorystore.RequiredEnvStoreObj.GetRequiredEnv().DatabaseCert
- dbCACert := memorystore.RequiredEnvStoreObj.GetRequiredEnv().DatabaseCACert
- dbCertKey := memorystore.RequiredEnvStoreObj.GetRequiredEnv().DatabaseCertKey
+ dbCert := cfg.DatabaseCert
+ dbCACert := cfg.DatabaseCACert
+ dbCertKey := cfg.DatabaseCertKey
if dbCert != "" && dbCACert != "" && dbCertKey != "" {
certString, err := crypto.DecryptB64(dbCert)
if err != nil {
@@ -97,7 +103,7 @@ func NewProvider() (*provider, error) {
cassandraClient.RetryPolicy = &cansandraDriver.SimpleRetryPolicy{
NumRetries: 3,
}
- cassandraClient.Consistency = gocql.LocalQuorum
+ cassandraClient.Consistency = cansandraDriver.LocalQuorum
cassandraClient.ConnectTimeout = 10 * time.Second
cassandraClient.ProtoVersion = 4
cassandraClient.Timeout = 30 * time.Minute // for large data
@@ -109,7 +115,7 @@ func NewProvider() (*provider, error) {
// Note for astra keyspaces can only be created from there console
// https://docs.datastax.com/en/astra/docs/datastax-astra-faq.html#_i_am_trying_to_create_a_keyspace_in_the_cql_shell_and_i_am_running_into_an_error_how_do_i_fix_this
- getKeyspaceQuery := fmt.Sprintf("SELECT keyspace_name FROM system_schema.keyspaces;")
+ getKeyspaceQuery := "SELECT keyspace_name FROM system_schema.keyspaces;"
scanner := session.Query(getKeyspaceQuery).Iter().Scanner()
hasAuthorizerKeySpace := false
for scanner.Next() {
@@ -134,154 +140,156 @@ func NewProvider() (*provider, error) {
// make sure collections are present
envCollectionQuery := fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s.%s (id text, env text, hash text, updated_at bigint, created_at bigint, PRIMARY KEY (id))",
- KeySpace, models.Collections.Env)
+ KeySpace, schemas.Collections.Env)
err = session.Query(envCollectionQuery).Exec()
if err != nil {
return nil, err
}
- sessionCollectionQuery := fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s.%s (id text, user_id text, user_agent text, ip text, updated_at bigint, created_at bigint, PRIMARY KEY (id))", KeySpace, models.Collections.Session)
+ sessionCollectionQuery := fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s.%s (id text, user_id text, user_agent text, ip text, updated_at bigint, created_at bigint, PRIMARY KEY (id))", KeySpace, schemas.Collections.Session)
err = session.Query(sessionCollectionQuery).Exec()
if err != nil {
return nil, err
}
- sessionIndexQuery := fmt.Sprintf("CREATE INDEX IF NOT EXISTS authorizer_session_user_id ON %s.%s (user_id)", KeySpace, models.Collections.Session)
+ sessionIndexQuery := fmt.Sprintf("CREATE INDEX IF NOT EXISTS authorizer_session_user_id ON %s.%s (user_id)", KeySpace, schemas.Collections.Session)
err = session.Query(sessionIndexQuery).Exec()
if err != nil {
return nil, err
}
- userCollectionQuery := fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s.%s (id text, email text, email_verified_at bigint, password text, signup_methods text, given_name text, family_name text, middle_name text, nickname text, gender text, birthdate text, phone_number text, phone_number_verified_at bigint, picture text, roles text, updated_at bigint, created_at bigint, revoked_timestamp bigint, PRIMARY KEY (id))", KeySpace, models.Collections.User)
+ userCollectionQuery := fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s.%s (id text, email text, email_verified_at bigint, password text, signup_methods text, given_name text, family_name text, middle_name text, nickname text, gender text, birthdate text, phone_number text, phone_number_verified_at bigint, picture text, roles text, updated_at bigint, created_at bigint, revoked_timestamp bigint, PRIMARY KEY (id))", KeySpace, schemas.Collections.User)
err = session.Query(userCollectionQuery).Exec()
if err != nil {
return nil, err
}
- userIndexQuery := fmt.Sprintf("CREATE INDEX IF NOT EXISTS authorizer_user_email ON %s.%s (email)", KeySpace, models.Collections.User)
+ userIndexQuery := fmt.Sprintf("CREATE INDEX IF NOT EXISTS authorizer_user_email ON %s.%s (email)", KeySpace, schemas.Collections.User)
err = session.Query(userIndexQuery).Exec()
if err != nil {
return nil, err
}
- userPhoneNumberIndexQuery := fmt.Sprintf("CREATE INDEX IF NOT EXISTS authorizer_user_phone_number ON %s.%s (phone_number)", KeySpace, models.Collections.User)
+ userPhoneNumberIndexQuery := fmt.Sprintf("CREATE INDEX IF NOT EXISTS authorizer_user_phone_number ON %s.%s (phone_number)", KeySpace, schemas.Collections.User)
err = session.Query(userPhoneNumberIndexQuery).Exec()
if err != nil {
return nil, err
}
// add is_multi_factor_auth_enabled on users table
- userTableAlterQuery := fmt.Sprintf(`ALTER TABLE %s.%s ADD is_multi_factor_auth_enabled boolean`, KeySpace, models.Collections.User)
+ userTableAlterQuery := fmt.Sprintf(`ALTER TABLE %s.%s ADD is_multi_factor_auth_enabled boolean`, KeySpace, schemas.Collections.User)
err = session.Query(userTableAlterQuery).Exec()
if err != nil {
- log.Debug("Failed to alter table as column exists: ", err)
- // return nil, err
+ deps.Log.Debug().Err(err).Msg("Failed to alter table as is_multi_factor_auth_enabled column exists")
+ // continue
}
// token is reserved keyword in cassandra, hence we need to use jwt_token
- verificationRequestCollectionQuery := fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s.%s (id text, jwt_token text, identifier text, expires_at bigint, email text, nonce text, redirect_uri text, created_at bigint, updated_at bigint, PRIMARY KEY (id))", KeySpace, models.Collections.VerificationRequest)
+ verificationRequestCollectionQuery := fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s.%s (id text, jwt_token text, identifier text, expires_at bigint, email text, nonce text, redirect_uri text, created_at bigint, updated_at bigint, PRIMARY KEY (id))", KeySpace, schemas.Collections.VerificationRequest)
err = session.Query(verificationRequestCollectionQuery).Exec()
if err != nil {
return nil, err
}
- verificationRequestIndexQuery := fmt.Sprintf("CREATE INDEX IF NOT EXISTS authorizer_verification_request_email ON %s.%s (email)", KeySpace, models.Collections.VerificationRequest)
+ verificationRequestIndexQuery := fmt.Sprintf("CREATE INDEX IF NOT EXISTS authorizer_verification_request_email ON %s.%s (email)", KeySpace, schemas.Collections.VerificationRequest)
err = session.Query(verificationRequestIndexQuery).Exec()
if err != nil {
return nil, err
}
- verificationRequestIndexQuery = fmt.Sprintf("CREATE INDEX IF NOT EXISTS authorizer_verification_request_identifier ON %s.%s (identifier)", KeySpace, models.Collections.VerificationRequest)
+ verificationRequestIndexQuery = fmt.Sprintf("CREATE INDEX IF NOT EXISTS authorizer_verification_request_identifier ON %s.%s (identifier)", KeySpace, schemas.Collections.VerificationRequest)
err = session.Query(verificationRequestIndexQuery).Exec()
if err != nil {
return nil, err
}
- verificationRequestIndexQuery = fmt.Sprintf("CREATE INDEX IF NOT EXISTS authorizer_verification_request_jwt_token ON %s.%s (jwt_token)", KeySpace, models.Collections.VerificationRequest)
+ verificationRequestIndexQuery = fmt.Sprintf("CREATE INDEX IF NOT EXISTS authorizer_verification_request_jwt_token ON %s.%s (jwt_token)", KeySpace, schemas.Collections.VerificationRequest)
err = session.Query(verificationRequestIndexQuery).Exec()
if err != nil {
return nil, err
}
- webhookCollectionQuery := fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s.%s (id text, event_name text, endpoint text, enabled boolean, headers text, updated_at bigint, created_at bigint, PRIMARY KEY (id))", KeySpace, models.Collections.Webhook)
+ webhookCollectionQuery := fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s.%s (id text, event_name text, endpoint text, enabled boolean, headers text, updated_at bigint, created_at bigint, PRIMARY KEY (id))", KeySpace, schemas.Collections.Webhook)
err = session.Query(webhookCollectionQuery).Exec()
if err != nil {
return nil, err
}
- webhookIndexQuery := fmt.Sprintf("CREATE INDEX IF NOT EXISTS authorizer_webhook_event_name ON %s.%s (event_name)", KeySpace, models.Collections.Webhook)
+ webhookIndexQuery := fmt.Sprintf("CREATE INDEX IF NOT EXISTS authorizer_webhook_event_name ON %s.%s (event_name)", KeySpace, schemas.Collections.Webhook)
err = session.Query(webhookIndexQuery).Exec()
if err != nil {
return nil, err
}
// add event_description to webhook table
- webhookAlterQuery := fmt.Sprintf(`ALTER TABLE %s.%s ADD (event_description text);`, KeySpace, models.Collections.Webhook)
+ webhookAlterQuery := fmt.Sprintf(`ALTER TABLE %s.%s ADD (event_description text);`, KeySpace, schemas.Collections.Webhook)
err = session.Query(webhookAlterQuery).Exec()
if err != nil {
- log.Debug("Failed to alter table as column exists: ", err)
+ deps.Log.Debug().Err(err).Msg("Failed to alter table as event_description column exists")
// continue
}
- webhookLogCollectionQuery := fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s.%s (id text, http_status bigint, response text, request text, webhook_id text,updated_at bigint, created_at bigint, PRIMARY KEY (id))", KeySpace, models.Collections.WebhookLog)
+ webhookLogCollectionQuery := fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s.%s (id text, http_status bigint, response text, request text, webhook_id text,updated_at bigint, created_at bigint, PRIMARY KEY (id))", KeySpace, schemas.Collections.WebhookLog)
err = session.Query(webhookLogCollectionQuery).Exec()
if err != nil {
return nil, err
}
- webhookLogIndexQuery := fmt.Sprintf("CREATE INDEX IF NOT EXISTS authorizer_webhook_log_webhook_id ON %s.%s (webhook_id)", KeySpace, models.Collections.WebhookLog)
+ webhookLogIndexQuery := fmt.Sprintf("CREATE INDEX IF NOT EXISTS authorizer_webhook_log_webhook_id ON %s.%s (webhook_id)", KeySpace, schemas.Collections.WebhookLog)
err = session.Query(webhookLogIndexQuery).Exec()
if err != nil {
return nil, err
}
- emailTemplateCollectionQuery := fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s.%s (id text, event_name text, template text, updated_at bigint, created_at bigint, PRIMARY KEY (id))", KeySpace, models.Collections.EmailTemplate)
+ emailTemplateCollectionQuery := fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s.%s (id text, event_name text, template text, updated_at bigint, created_at bigint, PRIMARY KEY (id))", KeySpace, schemas.Collections.EmailTemplate)
err = session.Query(emailTemplateCollectionQuery).Exec()
if err != nil {
return nil, err
}
- emailTemplateIndexQuery := fmt.Sprintf("CREATE INDEX IF NOT EXISTS authorizer_email_template_event_name ON %s.%s (event_name)", KeySpace, models.Collections.EmailTemplate)
+ emailTemplateIndexQuery := fmt.Sprintf("CREATE INDEX IF NOT EXISTS authorizer_email_template_event_name ON %s.%s (event_name)", KeySpace, schemas.Collections.EmailTemplate)
err = session.Query(emailTemplateIndexQuery).Exec()
if err != nil {
return nil, err
}
// add subject on email_templates table
- emailTemplateAlterQuery := fmt.Sprintf(`ALTER TABLE %s.%s ADD (subject text, design text);`, KeySpace, models.Collections.EmailTemplate)
+ emailTemplateAlterQuery := fmt.Sprintf(`ALTER TABLE %s.%s ADD (subject text, design text);`, KeySpace, schemas.Collections.EmailTemplate)
err = session.Query(emailTemplateAlterQuery).Exec()
if err != nil {
- log.Debug("Failed to alter table as column exists: ", err)
+ deps.Log.Debug().Err(err).Msg("Failed to alter table as subject & design column exists")
// continue
}
- otpCollection := fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s.%s (id text, email text, otp text, expires_at bigint, updated_at bigint, created_at bigint, PRIMARY KEY (id))", KeySpace, models.Collections.OTP)
+ otpCollection := fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s.%s (id text, email text, otp text, expires_at bigint, updated_at bigint, created_at bigint, PRIMARY KEY (id))", KeySpace, schemas.Collections.OTP)
err = session.Query(otpCollection).Exec()
if err != nil {
return nil, err
}
- otpIndexQuery := fmt.Sprintf("CREATE INDEX IF NOT EXISTS authorizer_otp_email ON %s.%s (email)", KeySpace, models.Collections.OTP)
+ otpIndexQuery := fmt.Sprintf("CREATE INDEX IF NOT EXISTS authorizer_otp_email ON %s.%s (email)", KeySpace, schemas.Collections.OTP)
err = session.Query(otpIndexQuery).Exec()
if err != nil {
return nil, err
}
// Add phone_number column to otp table
- otpAlterQuery := fmt.Sprintf(`ALTER TABLE %s.%s ADD (phone_number text);`, KeySpace, models.Collections.OTP)
+ otpAlterQuery := fmt.Sprintf(`ALTER TABLE %s.%s ADD (phone_number text);`, KeySpace, schemas.Collections.OTP)
err = session.Query(otpAlterQuery).Exec()
if err != nil {
- log.Debug("Failed to alter table as column exists: ", err)
+ deps.Log.Debug().Err(err).Msg("Failed to alter table as phone_number column exists")
// continue
}
// Add app_data column to users table
- appDataAlterQuery := fmt.Sprintf(`ALTER TABLE %s.%s ADD (app_data text);`, KeySpace, models.Collections.User)
+ appDataAlterQuery := fmt.Sprintf(`ALTER TABLE %s.%s ADD (app_data text);`, KeySpace, schemas.Collections.User)
err = session.Query(appDataAlterQuery).Exec()
if err != nil {
- log.Debug("Failed to alter user table as app_data column exists: ", err)
+ deps.Log.Debug().Err(err).Msg("Failed to alter table as app_data column exists")
// continue
}
// Add phone number index
- otpIndexQueryPhoneNumber := fmt.Sprintf("CREATE INDEX IF NOT EXISTS authorizer_otp_phone_number ON %s.%s (phone_number)", KeySpace, models.Collections.OTP)
+ otpIndexQueryPhoneNumber := fmt.Sprintf("CREATE INDEX IF NOT EXISTS authorizer_otp_phone_number ON %s.%s (phone_number)", KeySpace, schemas.Collections.OTP)
err = session.Query(otpIndexQueryPhoneNumber).Exec()
if err != nil {
return nil, err
}
// add authenticators table
- totpCollectionQuery := fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s.%s (id text, user_id text, method text, secret text, recovery_codes text, verified_at bigint, updated_at bigint, created_at bigint, PRIMARY KEY (id))", KeySpace, models.Collections.Authenticators)
+ totpCollectionQuery := fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s.%s (id text, user_id text, method text, secret text, recovery_codes text, verified_at bigint, updated_at bigint, created_at bigint, PRIMARY KEY (id))", KeySpace, schemas.Collections.Authenticators)
err = session.Query(totpCollectionQuery).Exec()
if err != nil {
return nil, err
}
return &provider{
- db: session,
+ config: cfg,
+ dependencies: deps,
+ db: session,
}, err
}
diff --git a/server/db/providers/cassandradb/session.go b/internal/storage/db/cassandradb/session.go
similarity index 67%
rename from server/db/providers/cassandradb/session.go
rename to internal/storage/db/cassandradb/session.go
index bdf205ce2..d2226a3f8 100644
--- a/server/db/providers/cassandradb/session.go
+++ b/internal/storage/db/cassandradb/session.go
@@ -5,18 +5,19 @@ import (
"fmt"
"time"
- "github.com/authorizerdev/authorizer/server/db/models"
"github.com/google/uuid"
+
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
// AddSession to save session information in database
-func (p *provider) AddSession(ctx context.Context, session *models.Session) error {
+func (p *provider) AddSession(ctx context.Context, session *schemas.Session) error {
if session.ID == "" {
session.ID = uuid.New().String()
}
session.CreatedAt = time.Now().Unix()
session.UpdatedAt = time.Now().Unix()
- insertSessionQuery := fmt.Sprintf("INSERT INTO %s (id, user_id, user_agent, ip, created_at, updated_at) VALUES ('%s', '%s', '%s', '%s', %d, %d)", KeySpace+"."+models.Collections.Session, session.ID, session.UserID, session.UserAgent, session.IP, session.CreatedAt, session.UpdatedAt)
+ insertSessionQuery := fmt.Sprintf("INSERT INTO %s (id, user_id, user_agent, ip, created_at, updated_at) VALUES ('%s', '%s', '%s', '%s', %d, %d)", KeySpace+"."+schemas.Collections.Session, session.ID, session.UserID, session.UserAgent, session.IP, session.CreatedAt, session.UpdatedAt)
err := p.db.Query(insertSessionQuery).Exec()
if err != nil {
return err
diff --git a/server/db/providers/cassandradb/user.go b/internal/storage/db/cassandradb/user.go
similarity index 84%
rename from server/db/providers/cassandradb/user.go
rename to internal/storage/db/cassandradb/user.go
index 7fb252981..d1e0ba22d 100644
--- a/server/db/providers/cassandradb/user.go
+++ b/internal/storage/db/cassandradb/user.go
@@ -8,27 +8,22 @@ import (
"strings"
"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/authorizerdev/authorizer/server/refs"
"github.com/gocql/gocql"
"github.com/google/uuid"
+
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/refs"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
// AddUser to save user information in database
-func (p *provider) AddUser(ctx context.Context, user *models.User) (*models.User, error) {
+func (p *provider) AddUser(ctx context.Context, user *schemas.User) (*schemas.User, error) {
if user.ID == "" {
user.ID = uuid.New().String()
}
if user.Roles == "" {
- defaultRoles, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyDefaultRoles)
- if err != nil {
- return nil, err
- }
- user.Roles = defaultRoles
+ user.Roles = strings.Join(p.config.DefaultRoles, ",")
}
if user.PhoneNumber != nil && strings.TrimSpace(refs.StringValue(user.PhoneNumber)) != "" {
@@ -80,7 +75,7 @@ func (p *provider) AddUser(ctx context.Context, user *models.User) (*models.User
fields = fields[:len(fields)-1] + ")"
values = values[:len(values)-1] + ")"
- query := fmt.Sprintf("INSERT INTO %s %s VALUES %s IF NOT EXISTS", KeySpace+"."+models.Collections.User, fields, values)
+ query := fmt.Sprintf("INSERT INTO %s %s VALUES %s IF NOT EXISTS", KeySpace+"."+schemas.Collections.User, fields, values)
err = p.db.Query(query).Exec()
if err != nil {
@@ -91,7 +86,7 @@ func (p *provider) AddUser(ctx context.Context, user *models.User) (*models.User
}
// UpdateUser to update user information in database
-func (p *provider) UpdateUser(ctx context.Context, user *models.User) (*models.User, error) {
+func (p *provider) UpdateUser(ctx context.Context, user *schemas.User) (*schemas.User, error) {
user.UpdatedAt = time.Now().Unix()
bytes, err := json.Marshal(user)
@@ -132,7 +127,7 @@ func (p *provider) UpdateUser(ctx context.Context, user *models.User) (*models.U
updateFields = strings.Trim(updateFields, " ")
updateFields = strings.TrimSuffix(updateFields, ",")
- query := fmt.Sprintf("UPDATE %s SET %s WHERE id = '%s'", KeySpace+"."+models.Collections.User, updateFields, user.ID)
+ query := fmt.Sprintf("UPDATE %s SET %s WHERE id = '%s'", KeySpace+"."+schemas.Collections.User, updateFields, user.ID)
err = p.db.Query(query).Exec()
if err != nil {
return nil, err
@@ -142,13 +137,13 @@ func (p *provider) UpdateUser(ctx context.Context, user *models.User) (*models.U
}
// DeleteUser to delete user information from database
-func (p *provider) DeleteUser(ctx context.Context, user *models.User) error {
- query := fmt.Sprintf("DELETE FROM %s WHERE id = '%s'", KeySpace+"."+models.Collections.User, user.ID)
+func (p *provider) DeleteUser(ctx context.Context, user *schemas.User) error {
+ query := fmt.Sprintf("DELETE FROM %s WHERE id = '%s'", KeySpace+"."+schemas.Collections.User, user.ID)
err := p.db.Query(query).Exec()
if err != nil {
return err
}
- getSessionsQuery := fmt.Sprintf("SELECT id FROM %s WHERE user_id = '%s' ALLOW FILTERING", KeySpace+"."+models.Collections.Session, user.ID)
+ getSessionsQuery := fmt.Sprintf("SELECT id FROM %s WHERE user_id = '%s' ALLOW FILTERING", KeySpace+"."+schemas.Collections.Session, user.ID)
scanner := p.db.Query(getSessionsQuery).Iter().Scanner()
sessionIDs := ""
for scanner.Next() {
@@ -160,7 +155,7 @@ func (p *provider) DeleteUser(ctx context.Context, user *models.User) error {
sessionIDs += fmt.Sprintf("'%s',", wlID)
}
sessionIDs = strings.TrimSuffix(sessionIDs, ",")
- deleteSessionQuery := fmt.Sprintf("DELETE FROM %s WHERE id IN (%s)", KeySpace+"."+models.Collections.Session, sessionIDs)
+ deleteSessionQuery := fmt.Sprintf("DELETE FROM %s WHERE id IN (%s)", KeySpace+"."+schemas.Collections.Session, sessionIDs)
err = p.db.Query(deleteSessionQuery).Exec()
if err != nil {
return err
@@ -170,46 +165,43 @@ func (p *provider) DeleteUser(ctx context.Context, user *models.User) error {
}
// ListUsers to get list of users from database
-func (p *provider) ListUsers(ctx context.Context, pagination *model.Pagination) (*model.Users, error) {
- responseUsers := []*model.User{}
+func (p *provider) ListUsers(ctx context.Context, pagination *model.Pagination) ([]*schemas.User, *model.Pagination, error) {
+ responseUsers := []*schemas.User{}
paginationClone := pagination
- totalCountQuery := fmt.Sprintf(`SELECT COUNT(*) FROM %s`, KeySpace+"."+models.Collections.User)
+ totalCountQuery := fmt.Sprintf(`SELECT COUNT(*) FROM %s`, KeySpace+"."+schemas.Collections.User)
err := p.db.Query(totalCountQuery).Consistency(gocql.One).Scan(&paginationClone.Total)
if err != nil {
- return nil, err
+ return nil, nil, err
}
// there is no offset in cassandra
// so we fetch till limit + offset
// and return the results from offset to limit
- query := fmt.Sprintf("SELECT id, email, email_verified_at, password, signup_methods, given_name, family_name, middle_name, nickname, birthdate, phone_number, phone_number_verified_at, picture, roles, revoked_timestamp, is_multi_factor_auth_enabled, app_data, created_at, updated_at FROM %s LIMIT %d", KeySpace+"."+models.Collections.User,
+ query := fmt.Sprintf("SELECT id, email, email_verified_at, password, signup_methods, given_name, family_name, middle_name, nickname, birthdate, phone_number, phone_number_verified_at, picture, roles, revoked_timestamp, is_multi_factor_auth_enabled, app_data, created_at, updated_at FROM %s LIMIT %d", KeySpace+"."+schemas.Collections.User,
pagination.Limit+pagination.Offset)
scanner := p.db.Query(query).Iter().Scanner()
counter := int64(0)
for scanner.Next() {
if counter >= pagination.Offset {
- var user models.User
+ var user schemas.User
err := scanner.Scan(&user.ID, &user.Email, &user.EmailVerifiedAt, &user.Password, &user.SignupMethods,
&user.GivenName, &user.FamilyName, &user.MiddleName, &user.Nickname, &user.Birthdate, &user.PhoneNumber,
&user.PhoneNumberVerifiedAt, &user.Picture, &user.Roles, &user.RevokedTimestamp, &user.IsMultiFactorAuthEnabled,
&user.AppData, &user.CreatedAt, &user.UpdatedAt)
if err != nil {
- return nil, err
+ return nil, nil, err
}
- responseUsers = append(responseUsers, user.AsAPIUser())
+ responseUsers = append(responseUsers, &user)
}
counter++
}
- return &model.Users{
- Pagination: paginationClone,
- Users: responseUsers,
- }, nil
+ return responseUsers, paginationClone, nil
}
// GetUserByEmail to get user information from database using email address
-func (p *provider) GetUserByEmail(ctx context.Context, email string) (*models.User, error) {
- var user models.User
- query := fmt.Sprintf("SELECT id, email, email_verified_at, password, signup_methods, given_name, family_name, middle_name, nickname, birthdate, phone_number, phone_number_verified_at, picture, roles, revoked_timestamp, is_multi_factor_auth_enabled, app_data, created_at, updated_at FROM %s WHERE email = '%s' LIMIT 1 ALLOW FILTERING", KeySpace+"."+models.Collections.User, email)
+func (p *provider) GetUserByEmail(ctx context.Context, email string) (*schemas.User, error) {
+ var user schemas.User
+ query := fmt.Sprintf("SELECT id, email, email_verified_at, password, signup_methods, given_name, family_name, middle_name, nickname, birthdate, phone_number, phone_number_verified_at, picture, roles, revoked_timestamp, is_multi_factor_auth_enabled, app_data, created_at, updated_at FROM %s WHERE email = '%s' LIMIT 1 ALLOW FILTERING", KeySpace+"."+schemas.Collections.User, email)
err := p.db.Query(query).Consistency(gocql.One).Scan(&user.ID, &user.Email, &user.EmailVerifiedAt, &user.Password, &user.SignupMethods, &user.GivenName, &user.FamilyName, &user.MiddleName, &user.Nickname, &user.Birthdate, &user.PhoneNumber, &user.PhoneNumberVerifiedAt, &user.Picture, &user.Roles, &user.RevokedTimestamp, &user.IsMultiFactorAuthEnabled, &user.AppData, &user.CreatedAt, &user.UpdatedAt)
if err != nil {
return nil, err
@@ -218,9 +210,9 @@ func (p *provider) GetUserByEmail(ctx context.Context, email string) (*models.Us
}
// GetUserByID to get user information from database using user ID
-func (p *provider) GetUserByID(ctx context.Context, id string) (*models.User, error) {
- var user models.User
- query := fmt.Sprintf("SELECT id, email, email_verified_at, password, signup_methods, given_name, family_name, middle_name, nickname, birthdate, phone_number, phone_number_verified_at, picture, roles, revoked_timestamp, is_multi_factor_auth_enabled, app_data, created_at, updated_at FROM %s WHERE id = '%s' LIMIT 1", KeySpace+"."+models.Collections.User, id)
+func (p *provider) GetUserByID(ctx context.Context, id string) (*schemas.User, error) {
+ var user schemas.User
+ query := fmt.Sprintf("SELECT id, email, email_verified_at, password, signup_methods, given_name, family_name, middle_name, nickname, birthdate, phone_number, phone_number_verified_at, picture, roles, revoked_timestamp, is_multi_factor_auth_enabled, app_data, created_at, updated_at FROM %s WHERE id = '%s' LIMIT 1", KeySpace+"."+schemas.Collections.User, id)
err := p.db.Query(query).Consistency(gocql.One).Scan(&user.ID, &user.Email, &user.EmailVerifiedAt, &user.Password, &user.SignupMethods, &user.GivenName, &user.FamilyName, &user.MiddleName, &user.Nickname, &user.Birthdate, &user.PhoneNumber, &user.PhoneNumberVerifiedAt, &user.Picture, &user.Roles, &user.RevokedTimestamp, &user.IsMultiFactorAuthEnabled, &user.AppData, &user.CreatedAt, &user.UpdatedAt)
if err != nil {
return nil, err
@@ -266,14 +258,14 @@ func (p *provider) UpdateUsers(ctx context.Context, data map[string]interface{},
}
idsString = strings.Trim(idsString, " ")
idsString = strings.TrimSuffix(idsString, ",")
- query = fmt.Sprintf("UPDATE %s SET %s WHERE id IN (%s)", KeySpace+"."+models.Collections.User, updateFields, idsString)
+ query = fmt.Sprintf("UPDATE %s SET %s WHERE id IN (%s)", KeySpace+"."+schemas.Collections.User, updateFields, idsString)
err := p.db.Query(query).Exec()
if err != nil {
return err
}
} else {
// get all ids
- getUserIDsQuery := fmt.Sprintf(`SELECT id FROM %s`, KeySpace+"."+models.Collections.User)
+ getUserIDsQuery := fmt.Sprintf(`SELECT id FROM %s`, KeySpace+"."+schemas.Collections.User)
scanner := p.db.Query(getUserIDsQuery).Iter().Scanner()
// only 100 ids are allowed in 1 query
// hence we need create multiple update queries
@@ -300,7 +292,7 @@ func (p *provider) UpdateUsers(ctx context.Context, data map[string]interface{},
for _, idStr := range idsStringArray {
idStr = strings.Trim(idStr, " ")
idStr = strings.TrimSuffix(idStr, ",")
- query = fmt.Sprintf("UPDATE %s SET %s WHERE id IN (%s)", KeySpace+"."+models.Collections.User, updateFields, idStr)
+ query = fmt.Sprintf("UPDATE %s SET %s WHERE id IN (%s)", KeySpace+"."+schemas.Collections.User, updateFields, idStr)
err := p.db.Query(query).Exec()
if err != nil {
return err
@@ -311,9 +303,9 @@ func (p *provider) UpdateUsers(ctx context.Context, data map[string]interface{},
}
// GetUserByPhoneNumber to get user information from database using phone number
-func (p *provider) GetUserByPhoneNumber(ctx context.Context, phoneNumber string) (*models.User, error) {
- var user models.User
- query := fmt.Sprintf("SELECT id, email, email_verified_at, password, signup_methods, given_name, family_name, middle_name, nickname, birthdate, phone_number, phone_number_verified_at, picture, roles, revoked_timestamp, is_multi_factor_auth_enabled, app_data, created_at, updated_at FROM %s WHERE phone_number = '%s' LIMIT 1 ALLOW FILTERING", KeySpace+"."+models.Collections.User, phoneNumber)
+func (p *provider) GetUserByPhoneNumber(ctx context.Context, phoneNumber string) (*schemas.User, error) {
+ var user schemas.User
+ query := fmt.Sprintf("SELECT id, email, email_verified_at, password, signup_methods, given_name, family_name, middle_name, nickname, birthdate, phone_number, phone_number_verified_at, picture, roles, revoked_timestamp, is_multi_factor_auth_enabled, app_data, created_at, updated_at FROM %s WHERE phone_number = '%s' LIMIT 1 ALLOW FILTERING", KeySpace+"."+schemas.Collections.User, phoneNumber)
err := p.db.Query(query).Consistency(gocql.One).Scan(&user.ID, &user.Email, &user.EmailVerifiedAt, &user.Password, &user.SignupMethods, &user.GivenName, &user.FamilyName, &user.MiddleName, &user.Nickname, &user.Birthdate, &user.PhoneNumber, &user.PhoneNumberVerifiedAt, &user.Picture, &user.Roles, &user.RevokedTimestamp, &user.IsMultiFactorAuthEnabled, &user.AppData, &user.CreatedAt, &user.UpdatedAt)
if err != nil {
return nil, err
diff --git a/server/db/providers/cassandradb/verification_requests.go b/internal/storage/db/cassandradb/verification_requests.go
similarity index 67%
rename from server/db/providers/cassandradb/verification_requests.go
rename to internal/storage/db/cassandradb/verification_requests.go
index e741c5dd8..7516fe958 100644
--- a/server/db/providers/cassandradb/verification_requests.go
+++ b/internal/storage/db/cassandradb/verification_requests.go
@@ -5,14 +5,15 @@ import (
"fmt"
"time"
- "github.com/authorizerdev/authorizer/server/db/models"
- "github.com/authorizerdev/authorizer/server/graph/model"
"github.com/gocql/gocql"
"github.com/google/uuid"
+
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
// AddVerification to save verification request in database
-func (p *provider) AddVerificationRequest(ctx context.Context, verificationRequest *models.VerificationRequest) (*models.VerificationRequest, error) {
+func (p *provider) AddVerificationRequest(ctx context.Context, verificationRequest *schemas.VerificationRequest) (*schemas.VerificationRequest, error) {
if verificationRequest.ID == "" {
verificationRequest.ID = uuid.New().String()
}
@@ -20,7 +21,7 @@ func (p *provider) AddVerificationRequest(ctx context.Context, verificationReque
verificationRequest.CreatedAt = time.Now().Unix()
verificationRequest.UpdatedAt = time.Now().Unix()
- query := fmt.Sprintf("INSERT INTO %s (id, jwt_token, identifier, expires_at, email, nonce, redirect_uri, created_at, updated_at) VALUES ('%s', '%s', '%s', %d, '%s', '%s', '%s', %d, %d)", KeySpace+"."+models.Collections.VerificationRequest, verificationRequest.ID, verificationRequest.Token, verificationRequest.Identifier, verificationRequest.ExpiresAt, verificationRequest.Email, verificationRequest.Nonce, verificationRequest.RedirectURI, verificationRequest.CreatedAt, verificationRequest.UpdatedAt)
+ query := fmt.Sprintf("INSERT INTO %s (id, jwt_token, identifier, expires_at, email, nonce, redirect_uri, created_at, updated_at) VALUES ('%s', '%s', '%s', %d, '%s', '%s', '%s', %d, %d)", KeySpace+"."+schemas.Collections.VerificationRequest, verificationRequest.ID, verificationRequest.Token, verificationRequest.Identifier, verificationRequest.ExpiresAt, verificationRequest.Email, verificationRequest.Nonce, verificationRequest.RedirectURI, verificationRequest.CreatedAt, verificationRequest.UpdatedAt)
err := p.db.Query(query).Exec()
if err != nil {
return nil, err
@@ -29,9 +30,9 @@ func (p *provider) AddVerificationRequest(ctx context.Context, verificationReque
}
// GetVerificationRequestByToken to get verification request from database using token
-func (p *provider) GetVerificationRequestByToken(ctx context.Context, token string) (*models.VerificationRequest, error) {
- var verificationRequest models.VerificationRequest
- query := fmt.Sprintf(`SELECT id, jwt_token, identifier, expires_at, email, nonce, redirect_uri, created_at, updated_at FROM %s WHERE jwt_token = '%s' LIMIT 1`, KeySpace+"."+models.Collections.VerificationRequest, token)
+func (p *provider) GetVerificationRequestByToken(ctx context.Context, token string) (*schemas.VerificationRequest, error) {
+ var verificationRequest schemas.VerificationRequest
+ query := fmt.Sprintf(`SELECT id, jwt_token, identifier, expires_at, email, nonce, redirect_uri, created_at, updated_at FROM %s WHERE jwt_token = '%s' LIMIT 1`, KeySpace+"."+schemas.Collections.VerificationRequest, token)
err := p.db.Query(query).Consistency(gocql.One).Scan(&verificationRequest.ID, &verificationRequest.Token, &verificationRequest.Identifier, &verificationRequest.ExpiresAt, &verificationRequest.Email, &verificationRequest.Nonce, &verificationRequest.RedirectURI, &verificationRequest.CreatedAt, &verificationRequest.UpdatedAt)
if err != nil {
@@ -41,9 +42,9 @@ func (p *provider) GetVerificationRequestByToken(ctx context.Context, token stri
}
// 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
- query := fmt.Sprintf(`SELECT id, jwt_token, identifier, expires_at, email, nonce, redirect_uri, created_at, updated_at FROM %s WHERE email = '%s' AND identifier = '%s' LIMIT 1 ALLOW FILTERING`, KeySpace+"."+models.Collections.VerificationRequest, email, identifier)
+func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email string, identifier string) (*schemas.VerificationRequest, error) {
+ var verificationRequest schemas.VerificationRequest
+ query := fmt.Sprintf(`SELECT id, jwt_token, identifier, expires_at, email, nonce, redirect_uri, created_at, updated_at FROM %s WHERE email = '%s' AND identifier = '%s' LIMIT 1 ALLOW FILTERING`, KeySpace+"."+schemas.Collections.VerificationRequest, email, identifier)
err := p.db.Query(query).Consistency(gocql.One).Scan(&verificationRequest.ID, &verificationRequest.Token, &verificationRequest.Identifier, &verificationRequest.ExpiresAt, &verificationRequest.Email, &verificationRequest.Nonce, &verificationRequest.RedirectURI, &verificationRequest.CreatedAt, &verificationRequest.UpdatedAt)
if err != nil {
@@ -54,42 +55,39 @@ func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email stri
}
// ListVerificationRequests to get list of verification requests from database
-func (p *provider) ListVerificationRequests(ctx context.Context, pagination *model.Pagination) (*model.VerificationRequests, error) {
- var verificationRequests []*model.VerificationRequest
+func (p *provider) ListVerificationRequests(ctx context.Context, pagination *model.Pagination) ([]*schemas.VerificationRequest, *model.Pagination, error) {
+ var verificationRequests []*schemas.VerificationRequest
paginationClone := pagination
- totalCountQuery := fmt.Sprintf(`SELECT COUNT(*) FROM %s`, KeySpace+"."+models.Collections.VerificationRequest)
+ totalCountQuery := fmt.Sprintf(`SELECT COUNT(*) FROM %s`, KeySpace+"."+schemas.Collections.VerificationRequest)
err := p.db.Query(totalCountQuery).Consistency(gocql.One).Scan(&paginationClone.Total)
if err != nil {
- return nil, err
+ return nil, nil, err
}
// there is no offset in cassandra
// so we fetch till limit + offset
// and return the results from offset to limit
- query := fmt.Sprintf(`SELECT id, jwt_token, identifier, expires_at, email, nonce, redirect_uri, created_at, updated_at FROM %s LIMIT %d`, KeySpace+"."+models.Collections.VerificationRequest, pagination.Limit+pagination.Offset)
+ query := fmt.Sprintf(`SELECT id, jwt_token, identifier, expires_at, email, nonce, redirect_uri, created_at, updated_at FROM %s LIMIT %d`, KeySpace+"."+schemas.Collections.VerificationRequest, pagination.Limit+pagination.Offset)
scanner := p.db.Query(query).Iter().Scanner()
counter := int64(0)
for scanner.Next() {
if counter >= pagination.Offset {
- var verificationRequest models.VerificationRequest
+ var verificationRequest schemas.VerificationRequest
err := scanner.Scan(&verificationRequest.ID, &verificationRequest.Token, &verificationRequest.Identifier, &verificationRequest.ExpiresAt, &verificationRequest.Email, &verificationRequest.Nonce, &verificationRequest.RedirectURI, &verificationRequest.CreatedAt, &verificationRequest.UpdatedAt)
if err != nil {
- return nil, err
+ return nil, nil, err
}
- verificationRequests = append(verificationRequests, verificationRequest.AsAPIVerificationRequest())
+ verificationRequests = append(verificationRequests, &verificationRequest)
}
counter++
}
- return &model.VerificationRequests{
- VerificationRequests: verificationRequests,
- Pagination: paginationClone,
- }, nil
+ return verificationRequests, paginationClone, nil
}
// DeleteVerificationRequest to delete verification request from database
-func (p *provider) DeleteVerificationRequest(ctx context.Context, verificationRequest *models.VerificationRequest) error {
- query := fmt.Sprintf("DELETE FROM %s WHERE id = '%s'", KeySpace+"."+models.Collections.VerificationRequest, verificationRequest.ID)
+func (p *provider) DeleteVerificationRequest(ctx context.Context, verificationRequest *schemas.VerificationRequest) error {
+ query := fmt.Sprintf("DELETE FROM %s WHERE id = '%s'", KeySpace+"."+schemas.Collections.VerificationRequest, verificationRequest.ID)
err := p.db.Query(query).Exec()
if err != nil {
return err
diff --git a/server/db/providers/cassandradb/webhook.go b/internal/storage/db/cassandradb/webhook.go
similarity index 72%
rename from server/db/providers/cassandradb/webhook.go
rename to internal/storage/db/cassandradb/webhook.go
index e80dfdd4b..0fe828be5 100644
--- a/server/db/providers/cassandradb/webhook.go
+++ b/internal/storage/db/cassandradb/webhook.go
@@ -8,14 +8,15 @@ import (
"strings"
"time"
- "github.com/authorizerdev/authorizer/server/db/models"
- "github.com/authorizerdev/authorizer/server/graph/model"
"github.com/gocql/gocql"
"github.com/google/uuid"
+
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
// AddWebhook to add webhook
-func (p *provider) AddWebhook(ctx context.Context, webhook *models.Webhook) (*model.Webhook, error) {
+func (p *provider) AddWebhook(ctx context.Context, webhook *schemas.Webhook) (*schemas.Webhook, error) {
if webhook.ID == "" {
webhook.ID = uuid.New().String()
}
@@ -24,16 +25,16 @@ func (p *provider) AddWebhook(ctx context.Context, webhook *models.Webhook) (*mo
webhook.UpdatedAt = time.Now().Unix()
// Add timestamp to make event name unique for legacy version
webhook.EventName = fmt.Sprintf("%s-%d", webhook.EventName, time.Now().Unix())
- insertQuery := fmt.Sprintf("INSERT INTO %s (id, event_description, event_name, endpoint, headers, enabled, created_at, updated_at) VALUES ('%s', '%s', '%s', '%s', '%s', %t, %d, %d)", KeySpace+"."+models.Collections.Webhook, webhook.ID, webhook.EventDescription, webhook.EventName, webhook.EndPoint, webhook.Headers, webhook.Enabled, webhook.CreatedAt, webhook.UpdatedAt)
+ insertQuery := fmt.Sprintf("INSERT INTO %s (id, event_description, event_name, endpoint, headers, enabled, created_at, updated_at) VALUES ('%s', '%s', '%s', '%s', '%s', %t, %d, %d)", KeySpace+"."+schemas.Collections.Webhook, webhook.ID, webhook.EventDescription, webhook.EventName, webhook.EndPoint, webhook.Headers, webhook.Enabled, webhook.CreatedAt, webhook.UpdatedAt)
err := p.db.Query(insertQuery).Exec()
if err != nil {
return nil, err
}
- return webhook.AsAPIWebhook(), nil
+ return webhook, nil
}
// UpdateWebhook to update webhook
-func (p *provider) UpdateWebhook(ctx context.Context, webhook *models.Webhook) (*model.Webhook, error) {
+func (p *provider) UpdateWebhook(ctx context.Context, webhook *schemas.Webhook) (*schemas.Webhook, error) {
webhook.UpdatedAt = time.Now().Unix()
// Event is changed
if !strings.Contains(webhook.EventName, "-") {
@@ -72,83 +73,80 @@ func (p *provider) UpdateWebhook(ctx context.Context, webhook *models.Webhook) (
}
updateFields = strings.Trim(updateFields, " ")
updateFields = strings.TrimSuffix(updateFields, ",")
- query := fmt.Sprintf("UPDATE %s SET %s WHERE id = '%s'", KeySpace+"."+models.Collections.Webhook, updateFields, webhook.ID)
+ query := fmt.Sprintf("UPDATE %s SET %s WHERE id = '%s'", KeySpace+"."+schemas.Collections.Webhook, updateFields, webhook.ID)
err = p.db.Query(query).Exec()
if err != nil {
return nil, err
}
- return webhook.AsAPIWebhook(), nil
+ return webhook, nil
}
// ListWebhooks to list webhook
-func (p *provider) ListWebhook(ctx context.Context, pagination *model.Pagination) (*model.Webhooks, error) {
- webhooks := []*model.Webhook{}
+func (p *provider) ListWebhook(ctx context.Context, pagination *model.Pagination) ([]*schemas.Webhook, *model.Pagination, error) {
+ webhooks := []*schemas.Webhook{}
paginationClone := pagination
- totalCountQuery := fmt.Sprintf(`SELECT COUNT(*) FROM %s`, KeySpace+"."+models.Collections.Webhook)
+ totalCountQuery := fmt.Sprintf(`SELECT COUNT(*) FROM %s`, KeySpace+"."+schemas.Collections.Webhook)
err := p.db.Query(totalCountQuery).Consistency(gocql.One).Scan(&paginationClone.Total)
if err != nil {
- return nil, err
+ return nil, nil, err
}
// there is no offset in cassandra
// so we fetch till limit + offset
// and return the results from offset to limit
- query := fmt.Sprintf("SELECT id, event_description, event_name, endpoint, headers, enabled, created_at, updated_at FROM %s LIMIT %d", KeySpace+"."+models.Collections.Webhook, pagination.Limit+pagination.Offset)
+ query := fmt.Sprintf("SELECT id, event_description, event_name, endpoint, headers, enabled, created_at, updated_at FROM %s LIMIT %d", KeySpace+"."+schemas.Collections.Webhook, pagination.Limit+pagination.Offset)
scanner := p.db.Query(query).Iter().Scanner()
counter := int64(0)
for scanner.Next() {
if counter >= pagination.Offset {
- var webhook models.Webhook
+ var webhook schemas.Webhook
err := scanner.Scan(&webhook.ID, &webhook.EventDescription, &webhook.EventName, &webhook.EndPoint, &webhook.Headers, &webhook.Enabled, &webhook.CreatedAt, &webhook.UpdatedAt)
if err != nil {
- return nil, err
+ return nil, nil, err
}
- webhooks = append(webhooks, webhook.AsAPIWebhook())
+ webhooks = append(webhooks, &webhook)
}
counter++
}
- return &model.Webhooks{
- Pagination: paginationClone,
- Webhooks: webhooks,
- }, nil
+ return webhooks, paginationClone, nil
}
// GetWebhookByID to get webhook by id
-func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*model.Webhook, error) {
- var webhook models.Webhook
- query := fmt.Sprintf(`SELECT id, event_description, event_name, endpoint, headers, enabled, created_at, updated_at FROM %s WHERE id = '%s' LIMIT 1`, KeySpace+"."+models.Collections.Webhook, webhookID)
+func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*schemas.Webhook, error) {
+ var webhook schemas.Webhook
+ query := fmt.Sprintf(`SELECT id, event_description, event_name, endpoint, headers, enabled, created_at, updated_at FROM %s WHERE id = '%s' LIMIT 1`, KeySpace+"."+schemas.Collections.Webhook, webhookID)
err := p.db.Query(query).Consistency(gocql.One).Scan(&webhook.ID, &webhook.EventDescription, &webhook.EventName, &webhook.EndPoint, &webhook.Headers, &webhook.Enabled, &webhook.CreatedAt, &webhook.UpdatedAt)
if err != nil {
return nil, err
}
- return webhook.AsAPIWebhook(), nil
+ return &webhook, nil
}
// GetWebhookByEventName to get webhook by event_name
-func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string) ([]*model.Webhook, error) {
- query := fmt.Sprintf(`SELECT id, event_description, event_name, endpoint, headers, enabled, created_at, updated_at FROM %s WHERE event_name LIKE '%s' ALLOW FILTERING`, KeySpace+"."+models.Collections.Webhook, eventName+"%")
+func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string) ([]*schemas.Webhook, error) {
+ query := fmt.Sprintf(`SELECT id, event_description, event_name, endpoint, headers, enabled, created_at, updated_at FROM %s WHERE event_name LIKE '%s' ALLOW FILTERING`, KeySpace+"."+schemas.Collections.Webhook, eventName+"%")
scanner := p.db.Query(query).Iter().Scanner()
- webhooks := []*model.Webhook{}
+ webhooks := []*schemas.Webhook{}
for scanner.Next() {
- var webhook models.Webhook
+ var webhook schemas.Webhook
err := scanner.Scan(&webhook.ID, &webhook.EventDescription, &webhook.EventName, &webhook.EndPoint, &webhook.Headers, &webhook.Enabled, &webhook.CreatedAt, &webhook.UpdatedAt)
if err != nil {
return nil, err
}
- webhooks = append(webhooks, webhook.AsAPIWebhook())
+ webhooks = append(webhooks, &webhook)
}
return webhooks, nil
}
// DeleteWebhook to delete webhook
-func (p *provider) DeleteWebhook(ctx context.Context, webhook *model.Webhook) error {
- query := fmt.Sprintf("DELETE FROM %s WHERE id = '%s'", KeySpace+"."+models.Collections.Webhook, webhook.ID)
+func (p *provider) DeleteWebhook(ctx context.Context, webhook *schemas.Webhook) error {
+ query := fmt.Sprintf("DELETE FROM %s WHERE id = '%s'", KeySpace+"."+schemas.Collections.Webhook, webhook.ID)
err := p.db.Query(query).Exec()
if err != nil {
return err
}
- getWebhookLogQuery := fmt.Sprintf("SELECT id FROM %s WHERE webhook_id = '%s' ALLOW FILTERING", KeySpace+"."+models.Collections.WebhookLog, webhook.ID)
+ getWebhookLogQuery := fmt.Sprintf("SELECT id FROM %s WHERE webhook_id = '%s' ALLOW FILTERING", KeySpace+"."+schemas.Collections.WebhookLog, webhook.ID)
scanner := p.db.Query(getWebhookLogQuery).Iter().Scanner()
webhookLogIDs := ""
for scanner.Next() {
@@ -160,7 +158,7 @@ func (p *provider) DeleteWebhook(ctx context.Context, webhook *model.Webhook) er
webhookLogIDs += fmt.Sprintf("'%s',", wlID)
}
webhookLogIDs = strings.TrimSuffix(webhookLogIDs, ",")
- query = fmt.Sprintf("DELETE FROM %s WHERE id IN (%s)", KeySpace+"."+models.Collections.WebhookLog, webhookLogIDs)
+ query = fmt.Sprintf("DELETE FROM %s WHERE id IN (%s)", KeySpace+"."+schemas.Collections.WebhookLog, webhookLogIDs)
err = p.db.Query(query).Exec()
return err
}
diff --git a/server/db/providers/cassandradb/webhook_log.go b/internal/storage/db/cassandradb/webhook_log.go
similarity index 61%
rename from server/db/providers/cassandradb/webhook_log.go
rename to internal/storage/db/cassandradb/webhook_log.go
index d587e026a..d01d4b323 100644
--- a/server/db/providers/cassandradb/webhook_log.go
+++ b/internal/storage/db/cassandradb/webhook_log.go
@@ -5,14 +5,15 @@ import (
"fmt"
"time"
- "github.com/authorizerdev/authorizer/server/db/models"
- "github.com/authorizerdev/authorizer/server/graph/model"
"github.com/gocql/gocql"
"github.com/google/uuid"
+
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
// AddWebhookLog to add webhook log
-func (p *provider) AddWebhookLog(ctx context.Context, webhookLog *models.WebhookLog) (*model.WebhookLog, error) {
+func (p *provider) AddWebhookLog(ctx context.Context, webhookLog *schemas.WebhookLog) (*schemas.WebhookLog, error) {
if webhookLog.ID == "" {
webhookLog.ID = uuid.New().String()
}
@@ -21,49 +22,46 @@ func (p *provider) AddWebhookLog(ctx context.Context, webhookLog *models.Webhook
webhookLog.CreatedAt = time.Now().Unix()
webhookLog.UpdatedAt = time.Now().Unix()
- insertQuery := fmt.Sprintf("INSERT INTO %s (id, http_status, response, request, webhook_id, created_at, updated_at) VALUES ('%s', %d,'%s', '%s', '%s', %d, %d)", KeySpace+"."+models.Collections.WebhookLog, webhookLog.ID, webhookLog.HttpStatus, webhookLog.Response, webhookLog.Request, webhookLog.WebhookID, webhookLog.CreatedAt, webhookLog.UpdatedAt)
+ insertQuery := fmt.Sprintf("INSERT INTO %s (id, http_status, response, request, webhook_id, created_at, updated_at) VALUES ('%s', %d,'%s', '%s', '%s', %d, %d)", KeySpace+"."+schemas.Collections.WebhookLog, webhookLog.ID, webhookLog.HttpStatus, webhookLog.Response, webhookLog.Request, webhookLog.WebhookID, webhookLog.CreatedAt, webhookLog.UpdatedAt)
err := p.db.Query(insertQuery).Exec()
if err != nil {
return nil, err
}
- return webhookLog.AsAPIWebhookLog(), nil
+ return webhookLog, nil
}
// ListWebhookLogs to list webhook logs
-func (p *provider) ListWebhookLogs(ctx context.Context, pagination *model.Pagination, webhookID string) (*model.WebhookLogs, error) {
- webhookLogs := []*model.WebhookLog{}
+func (p *provider) ListWebhookLogs(ctx context.Context, pagination *model.Pagination, webhookID string) ([]*schemas.WebhookLog, *model.Pagination, error) {
+ webhookLogs := []*schemas.WebhookLog{}
paginationClone := pagination
- totalCountQuery := fmt.Sprintf(`SELECT COUNT(*) FROM %s`, KeySpace+"."+models.Collections.WebhookLog)
+ totalCountQuery := fmt.Sprintf(`SELECT COUNT(*) FROM %s`, KeySpace+"."+schemas.Collections.WebhookLog)
// there is no offset in cassandra
// so we fetch till limit + offset
// and return the results from offset to limit
- query := fmt.Sprintf("SELECT id, http_status, response, request, webhook_id, created_at, updated_at FROM %s LIMIT %d", KeySpace+"."+models.Collections.WebhookLog, pagination.Limit+pagination.Offset)
+ query := fmt.Sprintf("SELECT id, http_status, response, request, webhook_id, created_at, updated_at FROM %s LIMIT %d", KeySpace+"."+schemas.Collections.WebhookLog, pagination.Limit+pagination.Offset)
if webhookID != "" {
- totalCountQuery = fmt.Sprintf(`SELECT COUNT(*) FROM %s WHERE webhook_id='%s' ALLOW FILTERING`, KeySpace+"."+models.Collections.WebhookLog, webhookID)
- query = fmt.Sprintf("SELECT id, http_status, response, request, webhook_id, created_at, updated_at FROM %s WHERE webhook_id = '%s' LIMIT %d ALLOW FILTERING", KeySpace+"."+models.Collections.WebhookLog, webhookID, pagination.Limit+pagination.Offset)
+ totalCountQuery = fmt.Sprintf(`SELECT COUNT(*) FROM %s WHERE webhook_id='%s' ALLOW FILTERING`, KeySpace+"."+schemas.Collections.WebhookLog, webhookID)
+ query = fmt.Sprintf("SELECT id, http_status, response, request, webhook_id, created_at, updated_at FROM %s WHERE webhook_id = '%s' LIMIT %d ALLOW FILTERING", KeySpace+"."+schemas.Collections.WebhookLog, webhookID, pagination.Limit+pagination.Offset)
}
err := p.db.Query(totalCountQuery).Consistency(gocql.One).Scan(&paginationClone.Total)
if err != nil {
- return nil, err
+ return nil, nil, err
}
scanner := p.db.Query(query).Iter().Scanner()
counter := int64(0)
for scanner.Next() {
if counter >= pagination.Offset {
- var webhookLog models.WebhookLog
+ var webhookLog schemas.WebhookLog
err := scanner.Scan(&webhookLog.ID, &webhookLog.HttpStatus, &webhookLog.Response, &webhookLog.Request, &webhookLog.WebhookID, &webhookLog.CreatedAt, &webhookLog.UpdatedAt)
if err != nil {
- return nil, err
+ return nil, nil, err
}
- webhookLogs = append(webhookLogs, webhookLog.AsAPIWebhookLog())
+ webhookLogs = append(webhookLogs, &webhookLog)
}
counter++
}
- return &model.WebhookLogs{
- Pagination: paginationClone,
- WebhookLogs: webhookLogs,
- }, nil
+ return webhookLogs, paginationClone, nil
}
diff --git a/server/db/providers/couchbase/authenticator.go b/internal/storage/db/couchbase/authenticator.go
similarity index 77%
rename from server/db/providers/couchbase/authenticator.go
rename to internal/storage/db/couchbase/authenticator.go
index dc81cb9da..9662679da 100644
--- a/server/db/providers/couchbase/authenticator.go
+++ b/internal/storage/db/couchbase/authenticator.go
@@ -10,10 +10,10 @@ import (
"github.com/couchbase/gocb/v2"
"github.com/google/uuid"
- "github.com/authorizerdev/authorizer/server/db/models"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
-func (p *provider) AddAuthenticator(ctx context.Context, authenticators *models.Authenticator) (*models.Authenticator, error) {
+func (p *provider) AddAuthenticator(ctx context.Context, authenticators *schemas.Authenticator) (*schemas.Authenticator, error) {
exists, _ := p.GetAuthenticatorDetailsByUserId(ctx, authenticators.UserID, authenticators.Method)
if exists != nil {
return authenticators, nil
@@ -28,14 +28,14 @@ func (p *provider) AddAuthenticator(ctx context.Context, authenticators *models.
insertOpt := gocb.InsertOptions{
Context: ctx,
}
- _, err := p.db.Collection(models.Collections.Authenticators).Insert(authenticators.ID, authenticators, &insertOpt)
+ _, err := p.db.Collection(schemas.Collections.Authenticators).Insert(authenticators.ID, authenticators, &insertOpt)
if err != nil {
return nil, err
}
return authenticators, nil
}
-func (p *provider) UpdateAuthenticator(ctx context.Context, authenticators *models.Authenticator) (*models.Authenticator, error) {
+func (p *provider) UpdateAuthenticator(ctx context.Context, authenticators *schemas.Authenticator) (*schemas.Authenticator, error) {
authenticators.UpdatedAt = time.Now().Unix()
bytes, err := json.Marshal(authenticators)
if err != nil {
@@ -50,7 +50,7 @@ func (p *provider) UpdateAuthenticator(ctx context.Context, authenticators *mode
return nil, err
}
updateFields, params := GetSetFields(authenticator)
- query := fmt.Sprintf("UPDATE %s.%s SET %s WHERE _id = '%s'", p.scopeName, models.Collections.Authenticators, updateFields, authenticators.ID)
+ query := fmt.Sprintf("UPDATE %s.%s SET %s WHERE _id = '%s'", p.scopeName, schemas.Collections.Authenticators, updateFields, authenticators.ID)
_, err = p.db.Query(query, &gocb.QueryOptions{
Context: ctx,
ScanConsistency: gocb.QueryScanConsistencyRequestPlus,
@@ -62,9 +62,9 @@ func (p *provider) UpdateAuthenticator(ctx context.Context, authenticators *mode
return authenticators, nil
}
-func (p *provider) GetAuthenticatorDetailsByUserId(ctx context.Context, userId string, authenticatorType string) (*models.Authenticator, error) {
- var authenticators *models.Authenticator
- query := fmt.Sprintf("SELECT _id, user_id, method, secret, recovery_code, verified_at, created_at, updated_at FROM %s.%s WHERE user_id = $1 AND method = $2 LIMIT 1", p.scopeName, models.Collections.Authenticators)
+func (p *provider) GetAuthenticatorDetailsByUserId(ctx context.Context, userId string, authenticatorType string) (*schemas.Authenticator, error) {
+ var authenticators *schemas.Authenticator
+ query := fmt.Sprintf("SELECT _id, user_id, method, secret, recovery_code, verified_at, created_at, updated_at FROM %s.%s WHERE user_id = $1 AND method = $2 LIMIT 1", p.scopeName, schemas.Collections.Authenticators)
q, err := p.db.Query(query, &gocb.QueryOptions{
ScanConsistency: gocb.QueryScanConsistencyRequestPlus,
Context: ctx,
diff --git a/server/db/providers/couchbase/email_template.go b/internal/storage/db/couchbase/email_template.go
similarity index 68%
rename from server/db/providers/couchbase/email_template.go
rename to internal/storage/db/couchbase/email_template.go
index 14f5ba940..deebfac15 100644
--- a/server/db/providers/couchbase/email_template.go
+++ b/internal/storage/db/couchbase/email_template.go
@@ -8,14 +8,15 @@ import (
"strings"
"time"
- "github.com/authorizerdev/authorizer/server/db/models"
- "github.com/authorizerdev/authorizer/server/graph/model"
"github.com/couchbase/gocb/v2"
"github.com/google/uuid"
+
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
// AddEmailTemplate to add EmailTemplate
-func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate *models.EmailTemplate) (*model.EmailTemplate, error) {
+func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate *schemas.EmailTemplate) (*schemas.EmailTemplate, error) {
if emailTemplate.ID == "" {
emailTemplate.ID = uuid.New().String()
@@ -28,16 +29,16 @@ func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate *models.E
Context: ctx,
}
- _, err := p.db.Collection(models.Collections.EmailTemplate).Insert(emailTemplate.ID, emailTemplate, &insertOpt)
+ _, err := p.db.Collection(schemas.Collections.EmailTemplate).Insert(emailTemplate.ID, emailTemplate, &insertOpt)
if err != nil {
- return emailTemplate.AsAPIEmailTemplate(), err
+ return nil, err
}
- return emailTemplate.AsAPIEmailTemplate(), nil
+ return emailTemplate, nil
}
// UpdateEmailTemplate to update EmailTemplate
-func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate *models.EmailTemplate) (*model.EmailTemplate, error) {
+func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate *schemas.EmailTemplate) (*schemas.EmailTemplate, error) {
bytes, err := json.Marshal(emailTemplate)
if err != nil {
return nil, err
@@ -54,7 +55,7 @@ func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate *model
updateFields, params := GetSetFields(emailTemplateMap)
params["emailId"] = emailTemplate.ID
- query := fmt.Sprintf("UPDATE %s.%s SET %s WHERE _id = $emailId", p.scopeName, models.Collections.EmailTemplate, updateFields)
+ query := fmt.Sprintf("UPDATE %s.%s SET %s WHERE _id = $emailId", p.scopeName, schemas.Collections.EmailTemplate, updateFields)
_, err = p.db.Query(query, &gocb.QueryOptions{
Context: ctx,
@@ -63,19 +64,19 @@ func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate *model
if err != nil {
return nil, err
}
- return emailTemplate.AsAPIEmailTemplate(), nil
+ return emailTemplate, nil
}
// ListEmailTemplates to list EmailTemplate
-func (p *provider) ListEmailTemplate(ctx context.Context, pagination *model.Pagination) (*model.EmailTemplates, error) {
- emailTemplates := []*model.EmailTemplate{}
+func (p *provider) ListEmailTemplate(ctx context.Context, pagination *model.Pagination) ([]*schemas.EmailTemplate, *model.Pagination, error) {
+ emailTemplates := []*schemas.EmailTemplate{}
paginationClone := pagination
- total, err := p.GetTotalDocs(ctx, models.Collections.EmailTemplate)
+ total, err := p.GetTotalDocs(ctx, schemas.Collections.EmailTemplate)
if err != nil {
- return nil, err
+ return nil, nil, err
}
paginationClone.Total = total
- userQuery := fmt.Sprintf("SELECT _id, event_name, subject, design, template, created_at, updated_at FROM %s.%s ORDER BY _id OFFSET $1 LIMIT $2", p.scopeName, models.Collections.EmailTemplate)
+ userQuery := fmt.Sprintf("SELECT _id, event_name, subject, design, template, created_at, updated_at FROM %s.%s ORDER BY _id OFFSET $1 LIMIT $2", p.scopeName, schemas.Collections.EmailTemplate)
queryResult, err := p.db.Query(userQuery, &gocb.QueryOptions{
Context: ctx,
@@ -84,33 +85,30 @@ func (p *provider) ListEmailTemplate(ctx context.Context, pagination *model.Pagi
})
if err != nil {
- return nil, err
+ return nil, nil, err
}
for queryResult.Next() {
- var emailTemplate *models.EmailTemplate
+ var emailTemplate *schemas.EmailTemplate
err := queryResult.Row(&emailTemplate)
if err != nil {
log.Fatal(err)
}
- emailTemplates = append(emailTemplates, emailTemplate.AsAPIEmailTemplate())
+ emailTemplates = append(emailTemplates, emailTemplate)
}
if err := queryResult.Err(); err != nil {
- return nil, err
+ return nil, nil, err
}
- return &model.EmailTemplates{
- Pagination: paginationClone,
- EmailTemplates: emailTemplates,
- }, nil
+ return emailTemplates, paginationClone, nil
}
// GetEmailTemplateByID to get EmailTemplate by id
-func (p *provider) GetEmailTemplateByID(ctx context.Context, emailTemplateID string) (*model.EmailTemplate, error) {
- var emailTemplate *models.EmailTemplate
- query := fmt.Sprintf(`SELECT _id, event_name, subject, design, template, created_at, updated_at FROM %s.%s WHERE _id = $1 LIMIT 1`, p.scopeName, models.Collections.EmailTemplate)
+func (p *provider) GetEmailTemplateByID(ctx context.Context, emailTemplateID string) (*schemas.EmailTemplate, error) {
+ var emailTemplate *schemas.EmailTemplate
+ query := fmt.Sprintf(`SELECT _id, event_name, subject, design, template, created_at, updated_at FROM %s.%s WHERE _id = $1 LIMIT 1`, p.scopeName, schemas.Collections.EmailTemplate)
q, err := p.db.Query(query, &gocb.QueryOptions{
Context: ctx,
ScanConsistency: gocb.QueryScanConsistencyRequestPlus,
@@ -123,13 +121,13 @@ func (p *provider) GetEmailTemplateByID(ctx context.Context, emailTemplateID str
if err != nil {
return nil, err
}
- return emailTemplate.AsAPIEmailTemplate(), nil
+ return emailTemplate, nil
}
// GetEmailTemplateByEventName to get EmailTemplate by event_name
-func (p *provider) GetEmailTemplateByEventName(ctx context.Context, eventName string) (*model.EmailTemplate, error) {
- var emailTemplate models.EmailTemplate
- query := fmt.Sprintf("SELECT _id, event_name, subject, design, template, created_at, updated_at FROM %s.%s WHERE event_name=$1 LIMIT 1", p.scopeName, models.Collections.EmailTemplate)
+func (p *provider) GetEmailTemplateByEventName(ctx context.Context, eventName string) (*schemas.EmailTemplate, error) {
+ var emailTemplate schemas.EmailTemplate
+ query := fmt.Sprintf("SELECT _id, event_name, subject, design, template, created_at, updated_at FROM %s.%s WHERE event_name=$1 LIMIT 1", p.scopeName, schemas.Collections.EmailTemplate)
q, err := p.db.Query(query, &gocb.QueryOptions{
Context: ctx,
ScanConsistency: gocb.QueryScanConsistencyRequestPlus,
@@ -142,15 +140,15 @@ func (p *provider) GetEmailTemplateByEventName(ctx context.Context, eventName st
if err != nil {
return nil, err
}
- return emailTemplate.AsAPIEmailTemplate(), nil
+ return &emailTemplate, nil
}
// DeleteEmailTemplate to delete EmailTemplate
-func (p *provider) DeleteEmailTemplate(ctx context.Context, emailTemplate *model.EmailTemplate) error {
+func (p *provider) DeleteEmailTemplate(ctx context.Context, emailTemplate *schemas.EmailTemplate) error {
removeOpt := gocb.RemoveOptions{
Context: ctx,
}
- _, err := p.db.Collection(models.Collections.EmailTemplate).Remove(emailTemplate.ID, &removeOpt)
+ _, err := p.db.Collection(schemas.Collections.EmailTemplate).Remove(emailTemplate.ID, &removeOpt)
if err != nil {
return err
}
diff --git a/server/db/providers/couchbase/env.go b/internal/storage/db/couchbase/env.go
similarity index 69%
rename from server/db/providers/couchbase/env.go
rename to internal/storage/db/couchbase/env.go
index 7c08e7f4f..14b20ef2a 100644
--- a/server/db/providers/couchbase/env.go
+++ b/internal/storage/db/couchbase/env.go
@@ -5,13 +5,14 @@ import (
"fmt"
"time"
- "github.com/authorizerdev/authorizer/server/db/models"
"github.com/couchbase/gocb/v2"
"github.com/google/uuid"
+
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
// AddEnv to save environment information in database
-func (p *provider) AddEnv(ctx context.Context, env *models.Env) (*models.Env, error) {
+func (p *provider) AddEnv(ctx context.Context, env *schemas.Env) (*schemas.Env, error) {
if env.ID == "" {
env.ID = uuid.New().String()
}
@@ -22,7 +23,7 @@ func (p *provider) AddEnv(ctx context.Context, env *models.Env) (*models.Env, er
insertOpt := gocb.InsertOptions{
Context: ctx,
}
- _, err := p.db.Collection(models.Collections.Env).Insert(env.ID, env, &insertOpt)
+ _, err := p.db.Collection(schemas.Collections.Env).Insert(env.ID, env, &insertOpt)
if err != nil {
return nil, err
}
@@ -30,11 +31,11 @@ func (p *provider) AddEnv(ctx context.Context, env *models.Env) (*models.Env, er
}
// UpdateEnv to update environment information in database
-func (p *provider) UpdateEnv(ctx context.Context, env *models.Env) (*models.Env, error) {
+func (p *provider) UpdateEnv(ctx context.Context, env *schemas.Env) (*schemas.Env, error) {
env.UpdatedAt = time.Now().Unix()
env.EncryptionKey = env.Hash
- updateEnvQuery := fmt.Sprintf("UPDATE %s.%s SET env = $1, updated_at = $2 WHERE _id = $3", p.scopeName, models.Collections.Env)
+ updateEnvQuery := fmt.Sprintf("UPDATE %s.%s SET env = $1, updated_at = $2 WHERE _id = $3", p.scopeName, schemas.Collections.Env)
_, err := p.db.Query(updateEnvQuery, &gocb.QueryOptions{
Context: ctx,
PositionalParameters: []interface{}{env.EnvData, env.UpdatedAt, env.UpdatedAt, env.ID},
@@ -46,10 +47,10 @@ func (p *provider) UpdateEnv(ctx context.Context, env *models.Env) (*models.Env,
}
// GetEnv to get environment information from database
-func (p *provider) GetEnv(ctx context.Context) (*models.Env, error) {
- var env *models.Env
+func (p *provider) GetEnv(ctx context.Context) (*schemas.Env, error) {
+ var env *schemas.Env
- query := fmt.Sprintf("SELECT _id, env, encryption_key, created_at, updated_at FROM %s.%s LIMIT 1", p.scopeName, models.Collections.Env)
+ query := fmt.Sprintf("SELECT _id, env, encryption_key, created_at, updated_at FROM %s.%s LIMIT 1", p.scopeName, schemas.Collections.Env)
q, err := p.db.Query(query, &gocb.QueryOptions{
Context: ctx,
ScanConsistency: gocb.QueryScanConsistencyRequestPlus,
diff --git a/server/db/providers/couchbase/otp.go b/internal/storage/db/couchbase/otp.go
similarity index 74%
rename from server/db/providers/couchbase/otp.go
rename to internal/storage/db/couchbase/otp.go
index 2980b94e0..1e9261043 100644
--- a/server/db/providers/couchbase/otp.go
+++ b/internal/storage/db/couchbase/otp.go
@@ -6,23 +6,24 @@ import (
"fmt"
"time"
- "github.com/authorizerdev/authorizer/server/db/models"
"github.com/couchbase/gocb/v2"
"github.com/google/uuid"
+
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
// UpsertOTP to add or update otp
-func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models.OTP, error) {
+func (p *provider) UpsertOTP(ctx context.Context, otpParam *schemas.OTP) (*schemas.OTP, error) {
// check if email or phone number is present
if otpParam.Email == "" && otpParam.PhoneNumber == "" {
return nil, errors.New("email or phone_number is required")
}
- uniqueField := models.FieldNameEmail
+ uniqueField := schemas.FieldNameEmail
if otpParam.Email == "" && otpParam.PhoneNumber != "" {
- uniqueField = models.FieldNamePhoneNumber
+ uniqueField = schemas.FieldNamePhoneNumber
}
- var otp *models.OTP
- if uniqueField == models.FieldNameEmail {
+ var otp *schemas.OTP
+ if uniqueField == schemas.FieldNameEmail {
otp, _ = p.GetOTPByEmail(ctx, otpParam.Email)
} else {
otp, _ = p.GetOTPByPhoneNumber(ctx, otpParam.PhoneNumber)
@@ -30,7 +31,7 @@ func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models
shouldCreate := false
if otp == nil {
shouldCreate = true
- otp = &models.OTP{
+ otp = &schemas.OTP{
ID: uuid.NewString(),
Otp: otpParam.Otp,
Email: otpParam.Email,
@@ -48,12 +49,12 @@ func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models
insertOpt := gocb.InsertOptions{
Context: ctx,
}
- _, err := p.db.Collection(models.Collections.OTP).Insert(otp.ID, otp, &insertOpt)
+ _, err := p.db.Collection(schemas.Collections.OTP).Insert(otp.ID, otp, &insertOpt)
if err != nil {
return nil, err
}
} else {
- query := fmt.Sprintf(`UPDATE %s.%s SET otp=$1, expires_at=$2, updated_at=$3 WHERE _id=$4`, p.scopeName, models.Collections.OTP)
+ query := fmt.Sprintf(`UPDATE %s.%s SET otp=$1, expires_at=$2, updated_at=$3 WHERE _id=$4`, p.scopeName, schemas.Collections.OTP)
_, err := p.db.Query(query, &gocb.QueryOptions{
PositionalParameters: []interface{}{otp.Otp, otp.ExpiresAt, otp.UpdatedAt, otp.ID},
})
@@ -65,9 +66,9 @@ func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models
}
// GetOTPByEmail to get otp for a given email address
-func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*models.OTP, error) {
- otp := models.OTP{}
- query := fmt.Sprintf(`SELECT _id, email, phone_number, otp, expires_at, created_at, updated_at FROM %s.%s WHERE email = $1 LIMIT 1`, p.scopeName, models.Collections.OTP)
+func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*schemas.OTP, error) {
+ otp := schemas.OTP{}
+ query := fmt.Sprintf(`SELECT _id, email, phone_number, otp, expires_at, created_at, updated_at FROM %s.%s WHERE email = $1 LIMIT 1`, p.scopeName, schemas.Collections.OTP)
q, err := p.db.Query(query, &gocb.QueryOptions{
ScanConsistency: gocb.QueryScanConsistencyRequestPlus,
PositionalParameters: []interface{}{emailAddress},
@@ -83,9 +84,9 @@ func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*mod
}
// GetOTPByPhoneNumber to get otp for a given phone number
-func (p *provider) GetOTPByPhoneNumber(ctx context.Context, phoneNumber string) (*models.OTP, error) {
- otp := models.OTP{}
- query := fmt.Sprintf(`SELECT _id, email, phone_number, otp, expires_at, created_at, updated_at FROM %s.%s WHERE phone_number = $1 LIMIT 1`, p.scopeName, models.Collections.OTP)
+func (p *provider) GetOTPByPhoneNumber(ctx context.Context, phoneNumber string) (*schemas.OTP, error) {
+ otp := schemas.OTP{}
+ query := fmt.Sprintf(`SELECT _id, email, phone_number, otp, expires_at, created_at, updated_at FROM %s.%s WHERE phone_number = $1 LIMIT 1`, p.scopeName, schemas.Collections.OTP)
q, err := p.db.Query(query, &gocb.QueryOptions{
ScanConsistency: gocb.QueryScanConsistencyRequestPlus,
PositionalParameters: []interface{}{phoneNumber},
@@ -101,11 +102,11 @@ func (p *provider) GetOTPByPhoneNumber(ctx context.Context, phoneNumber string)
}
// DeleteOTP to delete otp
-func (p *provider) DeleteOTP(ctx context.Context, otp *models.OTP) error {
+func (p *provider) DeleteOTP(ctx context.Context, otp *schemas.OTP) error {
removeOpt := gocb.RemoveOptions{
Context: ctx,
}
- _, err := p.db.Collection(models.Collections.OTP).Remove(otp.ID, &removeOpt)
+ _, err := p.db.Collection(schemas.Collections.OTP).Remove(otp.ID, &removeOpt)
if err != nil {
return err
}
diff --git a/server/db/providers/couchbase/provider.go b/internal/storage/db/couchbase/provider.go
similarity index 58%
rename from server/db/providers/couchbase/provider.go
rename to internal/storage/db/couchbase/provider.go
index 7eef85da0..270893c2f 100644
--- a/server/db/providers/couchbase/provider.go
+++ b/internal/storage/db/couchbase/provider.go
@@ -10,28 +10,38 @@ import (
"time"
"github.com/couchbase/gocb/v2"
+ "github.com/rs/zerolog"
- "github.com/authorizerdev/authorizer/server/db/models"
- "github.com/authorizerdev/authorizer/server/memorystore"
+ "github.com/authorizerdev/authorizer/internal/config"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
+// Dependencies struct the couchbase data store provider
+type Dependencies struct {
+ Log *zerolog.Logger
+}
+
const (
defaultBucketName = "authorizer"
defaultScope = "_default"
)
type provider struct {
+ config *config.Config
+ dependencies *Dependencies
+
db *gocb.Scope
scopeName string
}
// NewProvider returns a new Couchbase provider
-func NewProvider() (*provider, error) {
- bucketName := memorystore.RequiredEnvStoreObj.GetRequiredEnv().CouchbaseBucket
- scopeName := memorystore.RequiredEnvStoreObj.GetRequiredEnv().CouchbaseScope
- dbURL := memorystore.RequiredEnvStoreObj.GetRequiredEnv().DatabaseURL
- userName := memorystore.RequiredEnvStoreObj.GetRequiredEnv().DatabaseUsername
- password := memorystore.RequiredEnvStoreObj.GetRequiredEnv().DatabasePassword
+func NewProvider(config *config.Config, deps *Dependencies) (*provider, error) {
+ bucketName := config.CouchBaseBucket
+ ramQuota := config.CouchBaseRamQuota
+ scopeName := config.CouchBaseScope
+ dbURL := config.DatabaseURL
+ userName := config.DatabaseUsername
+ password := config.DatabasePassword
opts := gocb.ClusterOptions{
Username: userName,
Password: password,
@@ -46,14 +56,19 @@ func NewProvider() (*provider, error) {
if err != nil {
return nil, err
}
+ // Wait until the cluster is ready
+ err = cluster.WaitUntilReady(30*time.Second, nil)
+ if err != nil {
+ return nil, err
+ }
// To create the bucket and scope if not exist
- bucket, err := CreateBucketAndScope(cluster, bucketName, scopeName)
+ bucket, err := createBucketAndScope(cluster, bucketName, scopeName, ramQuota)
if err != nil {
return nil, err
}
scope := bucket.Scope(scopeName)
scopeIdentifier := fmt.Sprintf("%s.%s", bucketName, scopeName)
- v := reflect.ValueOf(models.Collections)
+ v := reflect.ValueOf(schemas.Collections)
for i := 0; i < v.NumField(); i++ {
collectionName := v.Field(i)
user := gocb.CollectionSpec{
@@ -77,7 +92,7 @@ func NewProvider() (*provider, error) {
}
}
- indices := GetIndex(scopeIdentifier)
+ indices := getIndex(scopeIdentifier)
for i := 0; i < v.NumField(); i++ {
field := v.Field(i)
for _, indexQuery := range indices[field.String()] {
@@ -85,17 +100,18 @@ func NewProvider() (*provider, error) {
}
}
return &provider{
- db: scope,
- scopeName: scopeIdentifier,
+ config: config,
+ dependencies: deps,
+ db: scope,
+ scopeName: scopeIdentifier,
}, nil
}
-func CreateBucketAndScope(cluster *gocb.Cluster, bucketName string, scopeName string) (*gocb.Bucket, error) {
- bucketRAMQuotaMB := memorystore.RequiredEnvStoreObj.GetRequiredEnv().CouchbaseBucketRAMQuotaMB
- if bucketRAMQuotaMB == "" {
- bucketRAMQuotaMB = "1000"
+func createBucketAndScope(cluster *gocb.Cluster, bucketName string, scopeName string, ramQuota string) (*gocb.Bucket, error) {
+ if ramQuota == "" {
+ ramQuota = "1000"
}
- bucketRAMQuota, err := strconv.ParseInt(bucketRAMQuotaMB, 10, 64)
+ bucketRAMQuota, err := strconv.ParseInt(ramQuota, 10, 64)
if err != nil {
return nil, err
}
@@ -124,6 +140,11 @@ func CreateBucketAndScope(cluster *gocb.Cluster, bucketName string, scopeName st
}
}
bucket := cluster.Bucket(bucketName)
+ // Wait until bucket is ready
+ err = bucket.WaitUntilReady(30*time.Second, nil)
+ if err != nil {
+ return nil, err
+ }
if scopeName != defaultScope {
err = bucket.Collections().CreateScope(scopeName, nil)
if err != nil && !errors.Is(err, gocb.ErrScopeExists) {
@@ -133,42 +154,42 @@ func CreateBucketAndScope(cluster *gocb.Cluster, bucketName string, scopeName st
return bucket, nil
}
-func GetIndex(scopeName string) map[string][]string {
+func getIndex(scopeName string) map[string][]string {
indices := make(map[string][]string)
// User Index
- userIndex1 := fmt.Sprintf("CREATE INDEX userEmailIndex ON %s.%s(email)", scopeName, models.Collections.User)
- userIndex2 := fmt.Sprintf("CREATE INDEX userPhoneIndex ON %s.%s(phone_number)", scopeName, models.Collections.User)
- indices[models.Collections.User] = []string{userIndex1, userIndex2}
+ userIndex1 := fmt.Sprintf("CREATE INDEX userEmailIndex ON %s.%s(email)", scopeName, schemas.Collections.User)
+ userIndex2 := fmt.Sprintf("CREATE INDEX userPhoneIndex ON %s.%s(phone_number)", scopeName, schemas.Collections.User)
+ indices[schemas.Collections.User] = []string{userIndex1, userIndex2}
// VerificationRequest
- verificationIndex1 := fmt.Sprintf("CREATE INDEX verificationRequestTokenIndex ON %s.%s(token)", scopeName, models.Collections.VerificationRequest)
- verificationIndex2 := fmt.Sprintf("CREATE INDEX verificationRequestEmailAndIdentifierIndex ON %s.%s(email,identifier)", scopeName, models.Collections.VerificationRequest)
- indices[models.Collections.VerificationRequest] = []string{verificationIndex1, verificationIndex2}
+ verificationIndex1 := fmt.Sprintf("CREATE INDEX verificationRequestTokenIndex ON %s.%s(token)", scopeName, schemas.Collections.VerificationRequest)
+ verificationIndex2 := fmt.Sprintf("CREATE INDEX verificationRequestEmailAndIdentifierIndex ON %s.%s(email,identifier)", scopeName, schemas.Collections.VerificationRequest)
+ indices[schemas.Collections.VerificationRequest] = []string{verificationIndex1, verificationIndex2}
// Session index
- sessionIndex1 := fmt.Sprintf("CREATE INDEX SessionUserIdIndex ON %s.%s(user_id)", scopeName, models.Collections.Session)
- indices[models.Collections.Session] = []string{sessionIndex1}
+ sessionIndex1 := fmt.Sprintf("CREATE INDEX SessionUserIdIndex ON %s.%s(user_id)", scopeName, schemas.Collections.Session)
+ indices[schemas.Collections.Session] = []string{sessionIndex1}
// Webhook index
- webhookIndex1 := fmt.Sprintf("CREATE INDEX webhookEventNameIndex ON %s.%s(event_name)", scopeName, models.Collections.Webhook)
- indices[models.Collections.Webhook] = []string{webhookIndex1}
+ webhookIndex1 := fmt.Sprintf("CREATE INDEX webhookEventNameIndex ON %s.%s(event_name)", scopeName, schemas.Collections.Webhook)
+ indices[schemas.Collections.Webhook] = []string{webhookIndex1}
// WebhookLog index
- webhookLogIndex1 := fmt.Sprintf("CREATE INDEX webhookLogIdIndex ON %s.%s(webhook_id)", scopeName, models.Collections.WebhookLog)
- indices[models.Collections.Webhook] = []string{webhookLogIndex1}
+ webhookLogIndex1 := fmt.Sprintf("CREATE INDEX webhookLogIdIndex ON %s.%s(webhook_id)", scopeName, schemas.Collections.WebhookLog)
+ indices[schemas.Collections.Webhook] = []string{webhookLogIndex1}
// WebhookLog index
- emailTempIndex1 := fmt.Sprintf("CREATE INDEX EmailTemplateEventNameIndex ON %s.%s(event_name)", scopeName, models.Collections.EmailTemplate)
- indices[models.Collections.EmailTemplate] = []string{emailTempIndex1}
+ emailTempIndex1 := fmt.Sprintf("CREATE INDEX EmailTemplateEventNameIndex ON %s.%s(event_name)", scopeName, schemas.Collections.EmailTemplate)
+ indices[schemas.Collections.EmailTemplate] = []string{emailTempIndex1}
// OTP index
- otpIndex1 := fmt.Sprintf("CREATE INDEX OTPEmailIndex ON %s.%s(email)", scopeName, models.Collections.OTP)
- indices[models.Collections.OTP] = []string{otpIndex1}
+ otpIndex1 := fmt.Sprintf("CREATE INDEX OTPEmailIndex ON %s.%s(email)", scopeName, schemas.Collections.OTP)
+ indices[schemas.Collections.OTP] = []string{otpIndex1}
// OTP index
- otpIndex2 := fmt.Sprintf("CREATE INDEX OTPPhoneNumberIndex ON %s.%s(phone_number)", scopeName, models.Collections.OTP)
- indices[models.Collections.OTP] = []string{otpIndex2}
+ otpIndex2 := fmt.Sprintf("CREATE INDEX OTPPhoneNumberIndex ON %s.%s(phone_number)", scopeName, schemas.Collections.OTP)
+ indices[schemas.Collections.OTP] = []string{otpIndex2}
return indices
}
diff --git a/server/db/providers/couchbase/session.go b/internal/storage/db/couchbase/session.go
similarity index 59%
rename from server/db/providers/couchbase/session.go
rename to internal/storage/db/couchbase/session.go
index a3b991576..74531a34c 100644
--- a/server/db/providers/couchbase/session.go
+++ b/internal/storage/db/couchbase/session.go
@@ -4,22 +4,24 @@ import (
"context"
"time"
- "github.com/authorizerdev/authorizer/server/db/models"
"github.com/couchbase/gocb/v2"
"github.com/google/uuid"
+
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
// AddSession to save session information in database
-func (p *provider) AddSession(ctx context.Context, session *models.Session) error {
+func (p *provider) AddSession(ctx context.Context, session *schemas.Session) error {
if session.ID == "" {
session.ID = uuid.New().String()
+ session.CreatedAt = time.Now().Unix()
+
+ session.UpdatedAt = time.Now().Unix()
}
- session.CreatedAt = time.Now().Unix()
- session.UpdatedAt = time.Now().Unix()
insertOpt := gocb.InsertOptions{
Context: ctx,
}
- _, err := p.db.Collection(models.Collections.Session).Insert(session.ID, session, &insertOpt)
+ _, err := p.db.Collection(schemas.Collections.Session).Insert(session.ID, session, &insertOpt)
if err != nil {
return err
}
diff --git a/server/db/providers/couchbase/shared.go b/internal/storage/db/couchbase/shared.go
similarity index 93%
rename from server/db/providers/couchbase/shared.go
rename to internal/storage/db/couchbase/shared.go
index a97ac6d97..cc770c9b7 100644
--- a/server/db/providers/couchbase/shared.go
+++ b/internal/storage/db/couchbase/shared.go
@@ -9,6 +9,7 @@ import (
"github.com/couchbase/gocb/v2"
)
+// GetSetFields to get set fields
func GetSetFields(webhookMap map[string]interface{}) (string, map[string]interface{}) {
params := make(map[string]interface{}, 1)
updateFields := ""
@@ -39,6 +40,7 @@ func GetSetFields(webhookMap map[string]interface{}) (string, map[string]interfa
return updateFields, params
}
+// GetTotalDocs to get total documents in a collection
func (p *provider) GetTotalDocs(ctx context.Context, collection string) (int64, error) {
totalDocs := TotalDocs{}
countQuery := fmt.Sprintf("SELECT COUNT(*) as Total FROM %s.%s", p.scopeName, collection)
diff --git a/server/db/providers/couchbase/user.go b/internal/storage/db/couchbase/user.go
similarity index 76%
rename from server/db/providers/couchbase/user.go
rename to internal/storage/db/couchbase/user.go
index ec80b7d66..84e6a2101 100644
--- a/server/db/providers/couchbase/user.go
+++ b/internal/storage/db/couchbase/user.go
@@ -7,27 +7,22 @@ import (
"strings"
"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/authorizerdev/authorizer/server/refs"
"github.com/couchbase/gocb/v2"
"github.com/google/uuid"
+
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/refs"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
// AddUser to save user information in database
-func (p *provider) AddUser(ctx context.Context, user *models.User) (*models.User, error) {
+func (p *provider) AddUser(ctx context.Context, user *schemas.User) (*schemas.User, error) {
if user.ID == "" {
user.ID = uuid.New().String()
}
if user.Roles == "" {
- defaultRoles, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyDefaultRoles)
- if err != nil {
- return nil, err
- }
- user.Roles = defaultRoles
+ user.Roles = strings.Join(p.config.DefaultRoles, ",")
}
if user.PhoneNumber != nil && strings.TrimSpace(refs.StringValue(user.PhoneNumber)) != "" {
@@ -45,7 +40,7 @@ func (p *provider) AddUser(ctx context.Context, user *models.User) (*models.User
insertOpt := gocb.InsertOptions{
Context: ctx,
}
- _, err := p.db.Collection(models.Collections.User).Insert(user.ID, user, &insertOpt)
+ _, err := p.db.Collection(schemas.Collections.User).Insert(user.ID, user, &insertOpt)
if err != nil {
return nil, err
}
@@ -53,12 +48,12 @@ func (p *provider) AddUser(ctx context.Context, user *models.User) (*models.User
}
// UpdateUser to update user information in database
-func (p *provider) UpdateUser(ctx context.Context, user *models.User) (*models.User, error) {
+func (p *provider) UpdateUser(ctx context.Context, user *schemas.User) (*schemas.User, error) {
user.UpdatedAt = time.Now().Unix()
upsertOpt := gocb.UpsertOptions{
Context: ctx,
}
- _, err := p.db.Collection(models.Collections.User).Upsert(user.ID, user, &upsertOpt)
+ _, err := p.db.Collection(schemas.Collections.User).Upsert(user.ID, user, &upsertOpt)
if err != nil {
return nil, err
}
@@ -66,11 +61,11 @@ func (p *provider) UpdateUser(ctx context.Context, user *models.User) (*models.U
}
// DeleteUser to delete user information from database
-func (p *provider) DeleteUser(ctx context.Context, user *models.User) error {
+func (p *provider) DeleteUser(ctx context.Context, user *schemas.User) error {
removeOpt := gocb.RemoveOptions{
Context: ctx,
}
- _, err := p.db.Collection(models.Collections.User).Remove(user.ID, &removeOpt)
+ _, err := p.db.Collection(schemas.Collections.User).Remove(user.ID, &removeOpt)
if err != nil {
return err
}
@@ -78,44 +73,41 @@ func (p *provider) DeleteUser(ctx context.Context, user *models.User) error {
}
// ListUsers to get list of users from database
-func (p *provider) ListUsers(ctx context.Context, pagination *model.Pagination) (*model.Users, error) {
- users := []*model.User{}
+func (p *provider) ListUsers(ctx context.Context, pagination *model.Pagination) ([]*schemas.User, *model.Pagination, error) {
+ users := []*schemas.User{}
paginationClone := pagination
- userQuery := fmt.Sprintf("SELECT _id, email, email_verified_at, `password`, signup_methods, given_name, family_name, middle_name, nickname, birthdate, phone_number, phone_number_verified_at, picture, roles, revoked_timestamp, is_multi_factor_auth_enabled, app_data, created_at, updated_at FROM %s.%s ORDER BY id OFFSET $1 LIMIT $2", p.scopeName, models.Collections.User)
+ userQuery := fmt.Sprintf("SELECT _id, email, email_verified_at, `password`, signup_methods, given_name, family_name, middle_name, nickname, birthdate, phone_number, phone_number_verified_at, picture, roles, revoked_timestamp, is_multi_factor_auth_enabled, app_data, created_at, updated_at FROM %s.%s ORDER BY id OFFSET $1 LIMIT $2", p.scopeName, schemas.Collections.User)
queryResult, err := p.db.Query(userQuery, &gocb.QueryOptions{
ScanConsistency: gocb.QueryScanConsistencyRequestPlus,
Context: ctx,
PositionalParameters: []interface{}{paginationClone.Offset, paginationClone.Limit},
})
if err != nil {
- return nil, err
+ return nil, nil, err
}
- total, err := p.GetTotalDocs(ctx, models.Collections.User)
+ total, err := p.GetTotalDocs(ctx, schemas.Collections.User)
if err != nil {
- return nil, err
+ return nil, nil, err
}
paginationClone.Total = total
for queryResult.Next() {
- var user models.User
+ var user schemas.User
err := queryResult.Row(&user)
if err != nil {
log.Fatal(err)
}
- users = append(users, user.AsAPIUser())
+ users = append(users, &user)
}
if err := queryResult.Err(); err != nil {
- return nil, err
+ return nil, nil, err
}
- return &model.Users{
- Pagination: paginationClone,
- Users: users,
- }, nil
+ return users, paginationClone, nil
}
// GetUserByEmail to get user information from database using email address
-func (p *provider) GetUserByEmail(ctx context.Context, email string) (*models.User, error) {
- var user *models.User
- query := fmt.Sprintf("SELECT _id, email, email_verified_at, `password`, signup_methods, given_name, family_name, middle_name, nickname, birthdate, phone_number, phone_number_verified_at, picture, roles, revoked_timestamp, is_multi_factor_auth_enabled, app_data, created_at, updated_at FROM %s.%s WHERE email = $1 LIMIT 1", p.scopeName, models.Collections.User)
+func (p *provider) GetUserByEmail(ctx context.Context, email string) (*schemas.User, error) {
+ var user *schemas.User
+ query := fmt.Sprintf("SELECT _id, email, email_verified_at, `password`, signup_methods, given_name, family_name, middle_name, nickname, birthdate, phone_number, phone_number_verified_at, picture, roles, revoked_timestamp, is_multi_factor_auth_enabled, app_data, created_at, updated_at FROM %s.%s WHERE email = $1 LIMIT 1", p.scopeName, schemas.Collections.User)
q, err := p.db.Query(query, &gocb.QueryOptions{
ScanConsistency: gocb.QueryScanConsistencyRequestPlus,
Context: ctx,
@@ -132,9 +124,9 @@ func (p *provider) GetUserByEmail(ctx context.Context, email string) (*models.Us
}
// GetUserByID to get user information from database using user ID
-func (p *provider) GetUserByID(ctx context.Context, id string) (*models.User, error) {
- var user *models.User
- query := fmt.Sprintf("SELECT _id, email, email_verified_at, `password`, signup_methods, given_name, family_name, middle_name, nickname, birthdate, phone_number, phone_number_verified_at, picture, roles, revoked_timestamp, is_multi_factor_auth_enabled, app_data, created_at, updated_at FROM %s.%s WHERE _id = $1 LIMIT 1", p.scopeName, models.Collections.User)
+func (p *provider) GetUserByID(ctx context.Context, id string) (*schemas.User, error) {
+ var user *schemas.User
+ query := fmt.Sprintf("SELECT _id, email, email_verified_at, `password`, signup_methods, given_name, family_name, middle_name, nickname, birthdate, phone_number, phone_number_verified_at, picture, roles, revoked_timestamp, is_multi_factor_auth_enabled, app_data, created_at, updated_at FROM %s.%s WHERE _id = $1 LIMIT 1", p.scopeName, schemas.Collections.User)
q, err := p.db.Query(query, &gocb.QueryOptions{
ScanConsistency: gocb.QueryScanConsistencyRequestPlus,
Context: ctx,
@@ -159,7 +151,7 @@ func (p *provider) UpdateUsers(ctx context.Context, data map[string]interface{},
if len(ids) > 0 {
for _, id := range ids {
params["id"] = id
- userQuery := fmt.Sprintf("UPDATE %s.%s SET %s WHERE _id = $id", p.scopeName, models.Collections.User, updateFields)
+ userQuery := fmt.Sprintf("UPDATE %s.%s SET %s WHERE _id = $id", p.scopeName, schemas.Collections.User, updateFields)
_, err := p.db.Query(userQuery, &gocb.QueryOptions{
ScanConsistency: gocb.QueryScanConsistencyRequestPlus,
@@ -171,7 +163,7 @@ func (p *provider) UpdateUsers(ctx context.Context, data map[string]interface{},
}
}
} else {
- userQuery := fmt.Sprintf("UPDATE %s.%s SET %s WHERE _id IS NOT NULL", p.scopeName, models.Collections.User, updateFields)
+ userQuery := fmt.Sprintf("UPDATE %s.%s SET %s WHERE _id IS NOT NULL", p.scopeName, schemas.Collections.User, updateFields)
_, err := p.db.Query(userQuery, &gocb.QueryOptions{
ScanConsistency: gocb.QueryScanConsistencyRequestPlus,
Context: ctx,
@@ -185,9 +177,9 @@ func (p *provider) UpdateUsers(ctx context.Context, data map[string]interface{},
}
// GetUserByPhoneNumber to get user information from database using phone number
-func (p *provider) GetUserByPhoneNumber(ctx context.Context, phoneNumber string) (*models.User, error) {
- var user *models.User
- query := fmt.Sprintf("SELECT _id, email, email_verified_at, `password`, signup_methods, given_name, family_name, middle_name, nickname, birthdate, phone_number, phone_number_verified_at, picture, roles, revoked_timestamp, is_multi_factor_auth_enabled, app_data, created_at, updated_at FROM %s.%s WHERE phone_number = $1 LIMIT 1", p.scopeName, models.Collections.User)
+func (p *provider) GetUserByPhoneNumber(ctx context.Context, phoneNumber string) (*schemas.User, error) {
+ var user *schemas.User
+ query := fmt.Sprintf("SELECT _id, email, email_verified_at, `password`, signup_methods, given_name, family_name, middle_name, nickname, birthdate, phone_number, phone_number_verified_at, picture, roles, revoked_timestamp, is_multi_factor_auth_enabled, app_data, created_at, updated_at FROM %s.%s WHERE phone_number = $1 LIMIT 1", p.scopeName, schemas.Collections.User)
q, err := p.db.Query(query, &gocb.QueryOptions{
ScanConsistency: gocb.QueryScanConsistencyRequestPlus,
Context: ctx,
diff --git a/server/db/providers/couchbase/verification_requests.go b/internal/storage/db/couchbase/verification_requests.go
similarity index 65%
rename from server/db/providers/couchbase/verification_requests.go
rename to internal/storage/db/couchbase/verification_requests.go
index 4448eab74..582af178b 100644
--- a/server/db/providers/couchbase/verification_requests.go
+++ b/internal/storage/db/couchbase/verification_requests.go
@@ -6,14 +6,15 @@ import (
"log"
"time"
- "github.com/authorizerdev/authorizer/server/db/models"
- "github.com/authorizerdev/authorizer/server/graph/model"
"github.com/couchbase/gocb/v2"
"github.com/google/uuid"
+
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
// AddVerification to save verification request in database
-func (p *provider) AddVerificationRequest(ctx context.Context, verificationRequest *models.VerificationRequest) (*models.VerificationRequest, error) {
+func (p *provider) AddVerificationRequest(ctx context.Context, verificationRequest *schemas.VerificationRequest) (*schemas.VerificationRequest, error) {
if verificationRequest.ID == "" {
verificationRequest.ID = uuid.New().String()
}
@@ -23,7 +24,7 @@ func (p *provider) AddVerificationRequest(ctx context.Context, verificationReque
insertOpt := gocb.InsertOptions{
Context: ctx,
}
- _, err := p.db.Collection(models.Collections.VerificationRequest).Insert(verificationRequest.ID, verificationRequest, &insertOpt)
+ _, err := p.db.Collection(schemas.Collections.VerificationRequest).Insert(verificationRequest.ID, verificationRequest, &insertOpt)
if err != nil {
return nil, err
}
@@ -31,11 +32,11 @@ func (p *provider) AddVerificationRequest(ctx context.Context, verificationReque
}
// GetVerificationRequestByToken to get verification request from database using token
-func (p *provider) GetVerificationRequestByToken(ctx context.Context, token string) (*models.VerificationRequest, error) {
- var verificationRequest *models.VerificationRequest
+func (p *provider) GetVerificationRequestByToken(ctx context.Context, token string) (*schemas.VerificationRequest, error) {
+ var verificationRequest *schemas.VerificationRequest
params := make(map[string]interface{}, 1)
params["token"] = token
- query := fmt.Sprintf("SELECT _id, token, identifier, expires_at, email, nonce, redirect_uri, created_at, updated_at FROM %s.%s WHERE token=$1 LIMIT 1", p.scopeName, models.Collections.VerificationRequest)
+ query := fmt.Sprintf("SELECT _id, token, identifier, expires_at, email, nonce, redirect_uri, created_at, updated_at FROM %s.%s WHERE token=$1 LIMIT 1", p.scopeName, schemas.Collections.VerificationRequest)
queryResult, err := p.db.Query(query, &gocb.QueryOptions{
Context: ctx,
@@ -55,9 +56,9 @@ func (p *provider) GetVerificationRequestByToken(ctx context.Context, token stri
}
// GetVerificationRequestByEmail to get verification request by email from database
-func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email string, identifier string) (*models.VerificationRequest, error) {
+func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email string, identifier string) (*schemas.VerificationRequest, error) {
- query := fmt.Sprintf("SELECT _id, identifier, token, expires_at, email, nonce, redirect_uri, created_at, updated_at FROM %s.%s WHERE email=$1 AND identifier=$2 LIMIT 1", p.scopeName, models.Collections.VerificationRequest)
+ query := fmt.Sprintf("SELECT _id, identifier, token, expires_at, email, nonce, redirect_uri, created_at, updated_at FROM %s.%s WHERE email=$1 AND identifier=$2 LIMIT 1", p.scopeName, schemas.Collections.VerificationRequest)
queryResult, err := p.db.Query(query, &gocb.QueryOptions{
Context: ctx,
PositionalParameters: []interface{}{email, identifier},
@@ -66,7 +67,7 @@ func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email stri
if err != nil {
return nil, err
}
- var verificationRequest *models.VerificationRequest
+ var verificationRequest *schemas.VerificationRequest
err = queryResult.One(&verificationRequest)
if err != nil {
return nil, err
@@ -75,47 +76,44 @@ func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email stri
}
// ListVerificationRequests to get list of verification requests from database
-func (p *provider) ListVerificationRequests(ctx context.Context, pagination *model.Pagination) (*model.VerificationRequests, error) {
- var verificationRequests []*model.VerificationRequest
+func (p *provider) ListVerificationRequests(ctx context.Context, pagination *model.Pagination) ([]*schemas.VerificationRequest, *model.Pagination, error) {
+ var verificationRequests []*schemas.VerificationRequest
paginationClone := pagination
- total, err := p.GetTotalDocs(ctx, models.Collections.VerificationRequest)
+ total, err := p.GetTotalDocs(ctx, schemas.Collections.VerificationRequest)
if err != nil {
- return nil, err
+ return nil, nil, err
}
paginationClone.Total = total
- query := fmt.Sprintf("SELECT _id, env, created_at, updated_at FROM %s.%s OFFSET $1 LIMIT $2", p.scopeName, models.Collections.VerificationRequest)
+ query := fmt.Sprintf("SELECT _id, env, created_at, updated_at FROM %s.%s OFFSET $1 LIMIT $2", p.scopeName, schemas.Collections.VerificationRequest)
queryResult, err := p.db.Query(query, &gocb.QueryOptions{
Context: ctx,
ScanConsistency: gocb.QueryScanConsistencyRequestPlus,
PositionalParameters: []interface{}{paginationClone.Offset, paginationClone.Limit},
})
if err != nil {
- return nil, err
+ return nil, nil, err
}
for queryResult.Next() {
- var verificationRequest models.VerificationRequest
+ var verificationRequest schemas.VerificationRequest
err := queryResult.Row(&verificationRequest)
if err != nil {
log.Fatal(err)
}
- verificationRequests = append(verificationRequests, verificationRequest.AsAPIVerificationRequest())
+ verificationRequests = append(verificationRequests, &verificationRequest)
}
if err := queryResult.Err(); err != nil {
- return nil, err
+ return nil, nil, err
}
- return &model.VerificationRequests{
- VerificationRequests: verificationRequests,
- Pagination: paginationClone,
- }, nil
+ return verificationRequests, paginationClone, nil
}
// DeleteVerificationRequest to delete verification request from database
-func (p *provider) DeleteVerificationRequest(ctx context.Context, verificationRequest *models.VerificationRequest) error {
+func (p *provider) DeleteVerificationRequest(ctx context.Context, verificationRequest *schemas.VerificationRequest) error {
removeOpt := gocb.RemoveOptions{
Context: ctx,
}
- _, err := p.db.Collection(models.Collections.VerificationRequest).Remove(verificationRequest.ID, &removeOpt)
+ _, err := p.db.Collection(schemas.Collections.VerificationRequest).Remove(verificationRequest.ID, &removeOpt)
if err != nil {
return err
}
diff --git a/server/db/providers/couchbase/webhook.go b/internal/storage/db/couchbase/webhook.go
similarity index 71%
rename from server/db/providers/couchbase/webhook.go
rename to internal/storage/db/couchbase/webhook.go
index 23dea5e9e..14d12aa54 100644
--- a/server/db/providers/couchbase/webhook.go
+++ b/internal/storage/db/couchbase/webhook.go
@@ -8,14 +8,15 @@ import (
"strings"
"time"
- "github.com/authorizerdev/authorizer/server/db/models"
- "github.com/authorizerdev/authorizer/server/graph/model"
"github.com/couchbase/gocb/v2"
"github.com/google/uuid"
+
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
// AddWebhook to add webhook
-func (p *provider) AddWebhook(ctx context.Context, webhook *models.Webhook) (*model.Webhook, error) {
+func (p *provider) AddWebhook(ctx context.Context, webhook *schemas.Webhook) (*schemas.Webhook, error) {
if webhook.ID == "" {
webhook.ID = uuid.New().String()
}
@@ -27,15 +28,15 @@ func (p *provider) AddWebhook(ctx context.Context, webhook *models.Webhook) (*mo
insertOpt := gocb.InsertOptions{
Context: ctx,
}
- _, err := p.db.Collection(models.Collections.Webhook).Insert(webhook.ID, webhook, &insertOpt)
+ _, err := p.db.Collection(schemas.Collections.Webhook).Insert(webhook.ID, webhook, &insertOpt)
if err != nil {
return nil, err
}
- return webhook.AsAPIWebhook(), nil
+ return webhook, nil
}
// UpdateWebhook to update webhook
-func (p *provider) UpdateWebhook(ctx context.Context, webhook *models.Webhook) (*model.Webhook, error) {
+func (p *provider) UpdateWebhook(ctx context.Context, webhook *schemas.Webhook) (*schemas.Webhook, error) {
webhook.UpdatedAt = time.Now().Unix()
// Event is changed
if !strings.Contains(webhook.EventName, "-") {
@@ -54,7 +55,7 @@ func (p *provider) UpdateWebhook(ctx context.Context, webhook *models.Webhook) (
return nil, err
}
updateFields, params := GetSetFields(webhookMap)
- query := fmt.Sprintf(`UPDATE %s.%s SET %s WHERE _id='%s'`, p.scopeName, models.Collections.Webhook, updateFields, webhook.ID)
+ query := fmt.Sprintf(`UPDATE %s.%s SET %s WHERE _id='%s'`, p.scopeName, schemas.Collections.Webhook, updateFields, webhook.ID)
_, err = p.db.Query(query, &gocb.QueryOptions{
Context: ctx,
ScanConsistency: gocb.QueryScanConsistencyRequestPlus,
@@ -64,53 +65,50 @@ func (p *provider) UpdateWebhook(ctx context.Context, webhook *models.Webhook) (
return nil, err
}
- return webhook.AsAPIWebhook(), nil
+ return webhook, nil
}
// ListWebhooks to list webhook
-func (p *provider) ListWebhook(ctx context.Context, pagination *model.Pagination) (*model.Webhooks, error) {
- webhooks := []*model.Webhook{}
+func (p *provider) ListWebhook(ctx context.Context, pagination *model.Pagination) ([]*schemas.Webhook, *model.Pagination, error) {
+ webhooks := []*schemas.Webhook{}
paginationClone := pagination
params := make(map[string]interface{}, 1)
params["offset"] = paginationClone.Offset
params["limit"] = paginationClone.Limit
- total, err := p.GetTotalDocs(ctx, models.Collections.Webhook)
+ total, err := p.GetTotalDocs(ctx, schemas.Collections.Webhook)
if err != nil {
- return nil, err
+ return nil, nil, err
}
paginationClone.Total = total
- query := fmt.Sprintf("SELECT _id, event_description, event_name, endpoint, headers, enabled, created_at, updated_at FROM %s.%s OFFSET $offset LIMIT $limit", p.scopeName, models.Collections.Webhook)
+ query := fmt.Sprintf("SELECT _id, event_description, event_name, endpoint, headers, enabled, created_at, updated_at FROM %s.%s OFFSET $offset LIMIT $limit", p.scopeName, schemas.Collections.Webhook)
queryResult, err := p.db.Query(query, &gocb.QueryOptions{
Context: ctx,
ScanConsistency: gocb.QueryScanConsistencyRequestPlus,
NamedParameters: params,
})
if err != nil {
- return nil, err
+ return nil, nil, err
}
for queryResult.Next() {
- var webhook models.Webhook
+ var webhook schemas.Webhook
err := queryResult.Row(&webhook)
if err != nil {
log.Fatal(err)
}
- webhooks = append(webhooks, webhook.AsAPIWebhook())
+ webhooks = append(webhooks, &webhook)
}
if err := queryResult.Err(); err != nil {
- return nil, err
+ return nil, nil, err
}
- return &model.Webhooks{
- Pagination: paginationClone,
- Webhooks: webhooks,
- }, nil
+ return webhooks, paginationClone, nil
}
// GetWebhookByID to get webhook by id
-func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*model.Webhook, error) {
- var webhook *models.Webhook
+func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*schemas.Webhook, error) {
+ var webhook *schemas.Webhook
params := make(map[string]interface{}, 1)
params["_id"] = webhookID
- query := fmt.Sprintf(`SELECT _id, event_description, event_name, endpoint, headers, enabled, created_at, updated_at FROM %s.%s WHERE _id=$_id LIMIT 1`, p.scopeName, models.Collections.Webhook)
+ query := fmt.Sprintf(`SELECT _id, event_description, event_name, endpoint, headers, enabled, created_at, updated_at FROM %s.%s WHERE _id=$_id LIMIT 1`, p.scopeName, schemas.Collections.Webhook)
q, err := p.db.Query(query, &gocb.QueryOptions{
Context: ctx,
ScanConsistency: gocb.QueryScanConsistencyRequestPlus,
@@ -123,14 +121,14 @@ func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*model
if err != nil {
return nil, err
}
- return webhook.AsAPIWebhook(), nil
+ return webhook, nil
}
// GetWebhookByEventName to get webhook by event_name
-func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string) ([]*model.Webhook, error) {
+func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string) ([]*schemas.Webhook, error) {
params := make(map[string]interface{}, 1)
// params["event_name"] = eventName + "%"
- query := fmt.Sprintf(`SELECT _id, event_description, event_name, endpoint, headers, enabled, created_at, updated_at FROM %s.%s WHERE event_name LIKE '%s'`, p.scopeName, models.Collections.Webhook, eventName+"%")
+ query := fmt.Sprintf(`SELECT _id, event_description, event_name, endpoint, headers, enabled, created_at, updated_at FROM %s.%s WHERE event_name LIKE '%s'`, p.scopeName, schemas.Collections.Webhook, eventName+"%")
queryResult, err := p.db.Query(query, &gocb.QueryOptions{
Context: ctx,
ScanConsistency: gocb.QueryScanConsistencyRequestPlus,
@@ -139,14 +137,14 @@ func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string)
if err != nil {
return nil, err
}
- webhooks := []*model.Webhook{}
+ webhooks := []*schemas.Webhook{}
for queryResult.Next() {
- var webhook *models.Webhook
+ var webhook *schemas.Webhook
err := queryResult.Row(&webhook)
if err != nil {
log.Fatal(err)
}
- webhooks = append(webhooks, webhook.AsAPIWebhook())
+ webhooks = append(webhooks, webhook)
}
if err := queryResult.Err(); err != nil {
return nil, err
@@ -155,17 +153,17 @@ func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string)
}
// DeleteWebhook to delete webhook
-func (p *provider) DeleteWebhook(ctx context.Context, webhook *model.Webhook) error {
+func (p *provider) DeleteWebhook(ctx context.Context, webhook *schemas.Webhook) error {
params := make(map[string]interface{}, 1)
params["webhook_id"] = webhook.ID
removeOpt := gocb.RemoveOptions{
Context: ctx,
}
- _, err := p.db.Collection(models.Collections.Webhook).Remove(webhook.ID, &removeOpt)
+ _, err := p.db.Collection(schemas.Collections.Webhook).Remove(webhook.ID, &removeOpt)
if err != nil {
return err
}
- query := fmt.Sprintf(`DELETE FROM %s.%s WHERE webhook_id=$webhook_id`, p.scopeName, models.Collections.WebhookLog)
+ query := fmt.Sprintf(`DELETE FROM %s.%s WHERE webhook_id=$webhook_id`, p.scopeName, schemas.Collections.WebhookLog)
_, err = p.db.Query(query, &gocb.QueryOptions{
Context: ctx,
ScanConsistency: gocb.QueryScanConsistencyRequestPlus,
diff --git a/server/db/providers/couchbase/webhook_log.go b/internal/storage/db/couchbase/webhook_log.go
similarity index 64%
rename from server/db/providers/couchbase/webhook_log.go
rename to internal/storage/db/couchbase/webhook_log.go
index fb1d08a92..883347c34 100644
--- a/server/db/providers/couchbase/webhook_log.go
+++ b/internal/storage/db/couchbase/webhook_log.go
@@ -6,14 +6,15 @@ import (
"log"
"time"
- "github.com/authorizerdev/authorizer/server/db/models"
- "github.com/authorizerdev/authorizer/server/graph/model"
"github.com/couchbase/gocb/v2"
"github.com/google/uuid"
+
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
// AddWebhookLog to add webhook log
-func (p *provider) AddWebhookLog(ctx context.Context, webhookLog *models.WebhookLog) (*model.WebhookLog, error) {
+func (p *provider) AddWebhookLog(ctx context.Context, webhookLog *schemas.WebhookLog) (*schemas.WebhookLog, error) {
if webhookLog.ID == "" {
webhookLog.ID = uuid.New().String()
}
@@ -23,32 +24,32 @@ func (p *provider) AddWebhookLog(ctx context.Context, webhookLog *models.Webhook
insertOpt := gocb.InsertOptions{
Context: ctx,
}
- _, err := p.db.Collection(models.Collections.WebhookLog).Insert(webhookLog.ID, webhookLog, &insertOpt)
+ _, err := p.db.Collection(schemas.Collections.WebhookLog).Insert(webhookLog.ID, webhookLog, &insertOpt)
if err != nil {
return nil, err
}
- return webhookLog.AsAPIWebhookLog(), nil
+ return webhookLog, nil
}
// ListWebhookLogs to list webhook logs
-func (p *provider) ListWebhookLogs(ctx context.Context, pagination *model.Pagination, webhookID string) (*model.WebhookLogs, error) {
+func (p *provider) ListWebhookLogs(ctx context.Context, pagination *model.Pagination, webhookID string) ([]*schemas.WebhookLog, *model.Pagination, error) {
var query string
var err error
- webhookLogs := []*model.WebhookLog{}
+ webhookLogs := []*schemas.WebhookLog{}
params := make(map[string]interface{}, 1)
paginationClone := pagination
params["webhookID"] = webhookID
params["offset"] = paginationClone.Offset
params["limit"] = paginationClone.Limit
- total, err := p.GetTotalDocs(ctx, models.Collections.WebhookLog)
+ total, err := p.GetTotalDocs(ctx, schemas.Collections.WebhookLog)
if err != nil {
- return nil, err
+ return nil, nil, err
}
paginationClone.Total = total
if webhookID != "" {
- query = fmt.Sprintf(`SELECT _id, http_status, response, request, webhook_id, created_at, updated_at FROM %s.%s WHERE webhook_id=$webhookID`, p.scopeName, models.Collections.WebhookLog)
+ query = fmt.Sprintf(`SELECT _id, http_status, response, request, webhook_id, created_at, updated_at FROM %s.%s WHERE webhook_id=$webhookID`, p.scopeName, schemas.Collections.WebhookLog)
} else {
- query = fmt.Sprintf("SELECT _id, http_status, response, request, webhook_id, created_at, updated_at FROM %s.%s OFFSET $offset LIMIT $limit", p.scopeName, models.Collections.WebhookLog)
+ query = fmt.Sprintf("SELECT _id, http_status, response, request, webhook_id, created_at, updated_at FROM %s.%s OFFSET $offset LIMIT $limit", p.scopeName, schemas.Collections.WebhookLog)
}
queryResult, err := p.db.Query(query, &gocb.QueryOptions{
Context: ctx,
@@ -56,22 +57,19 @@ func (p *provider) ListWebhookLogs(ctx context.Context, pagination *model.Pagina
NamedParameters: params,
})
if err != nil {
- return nil, err
+ return nil, nil, err
}
for queryResult.Next() {
- var webhookLog models.WebhookLog
+ var webhookLog schemas.WebhookLog
err := queryResult.Row(&webhookLog)
if err != nil {
log.Fatal(err)
}
- webhookLogs = append(webhookLogs, webhookLog.AsAPIWebhookLog())
+ webhookLogs = append(webhookLogs, &webhookLog)
}
if err := queryResult.Err(); err != nil {
- return nil, err
+ return nil, nil, err
}
- return &model.WebhookLogs{
- Pagination: paginationClone,
- WebhookLogs: webhookLogs,
- }, nil
+ return webhookLogs, paginationClone, nil
}
diff --git a/server/db/providers/dynamodb/authenticator.go b/internal/storage/db/dynamodb/authenticator.go
similarity index 70%
rename from server/db/providers/dynamodb/authenticator.go
rename to internal/storage/db/dynamodb/authenticator.go
index 56ffea156..88e349ade 100644
--- a/server/db/providers/dynamodb/authenticator.go
+++ b/internal/storage/db/dynamodb/authenticator.go
@@ -6,16 +6,16 @@ import (
"github.com/google/uuid"
- "github.com/authorizerdev/authorizer/server/db/models"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
-func (p *provider) AddAuthenticator(ctx context.Context, authenticators *models.Authenticator) (*models.Authenticator, error) {
+func (p *provider) AddAuthenticator(ctx context.Context, authenticators *schemas.Authenticator) (*schemas.Authenticator, error) {
exists, _ := p.GetAuthenticatorDetailsByUserId(ctx, authenticators.UserID, authenticators.Method)
if exists != nil {
return authenticators, nil
}
- collection := p.db.Table(models.Collections.Authenticators)
+ collection := p.db.Table(schemas.Collections.Authenticators)
if authenticators.ID == "" {
authenticators.ID = uuid.New().String()
}
@@ -29,8 +29,8 @@ func (p *provider) AddAuthenticator(ctx context.Context, authenticators *models.
return authenticators, nil
}
-func (p *provider) UpdateAuthenticator(ctx context.Context, authenticators *models.Authenticator) (*models.Authenticator, error) {
- collection := p.db.Table(models.Collections.Authenticators)
+func (p *provider) UpdateAuthenticator(ctx context.Context, authenticators *schemas.Authenticator) (*schemas.Authenticator, error) {
+ collection := p.db.Table(schemas.Collections.Authenticators)
if authenticators.ID != "" {
authenticators.UpdatedAt = time.Now().Unix()
err := UpdateByHashKey(collection, "id", authenticators.ID, authenticators)
@@ -42,9 +42,9 @@ func (p *provider) UpdateAuthenticator(ctx context.Context, authenticators *mode
}
-func (p *provider) GetAuthenticatorDetailsByUserId(ctx context.Context, userId string, authenticatorType string) (*models.Authenticator, error) {
- var authenticators *models.Authenticator
- collection := p.db.Table(models.Collections.Authenticators)
+func (p *provider) GetAuthenticatorDetailsByUserId(ctx context.Context, userId string, authenticatorType string) (*schemas.Authenticator, error) {
+ var authenticators *schemas.Authenticator
+ collection := p.db.Table(schemas.Collections.Authenticators)
iter := collection.Scan().Filter("'user_id' = ?", userId).Filter("'method' = ?", authenticatorType).Iter()
for iter.NextWithContext(ctx, &authenticators) {
return authenticators, nil
diff --git a/server/db/providers/dynamodb/email_template.go b/internal/storage/db/dynamodb/email_template.go
similarity index 58%
rename from server/db/providers/dynamodb/email_template.go
rename to internal/storage/db/dynamodb/email_template.go
index 7355bbb82..4dfe25e1c 100644
--- a/server/db/providers/dynamodb/email_template.go
+++ b/internal/storage/db/dynamodb/email_template.go
@@ -5,15 +5,16 @@ import (
"errors"
"time"
- "github.com/authorizerdev/authorizer/server/db/models"
- "github.com/authorizerdev/authorizer/server/graph/model"
"github.com/google/uuid"
"github.com/guregu/dynamo"
+
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
// AddEmailTemplate to add EmailTemplate
-func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate *models.EmailTemplate) (*model.EmailTemplate, error) {
- collection := p.db.Table(models.Collections.EmailTemplate)
+func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate *schemas.EmailTemplate) (*schemas.EmailTemplate, error) {
+ collection := p.db.Table(schemas.Collections.EmailTemplate)
if emailTemplate.ID == "" {
emailTemplate.ID = uuid.New().String()
}
@@ -24,86 +25,82 @@ func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate *models.E
err := collection.Put(emailTemplate).RunWithContext(ctx)
if err != nil {
- return emailTemplate.AsAPIEmailTemplate(), err
+ return nil, err
}
- return emailTemplate.AsAPIEmailTemplate(), nil
+ return emailTemplate, 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)
+func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate *schemas.EmailTemplate) (*schemas.EmailTemplate, error) {
+ collection := p.db.Table(schemas.Collections.EmailTemplate)
emailTemplate.UpdatedAt = time.Now().Unix()
err := UpdateByHashKey(collection, "id", emailTemplate.ID, emailTemplate)
if err != nil {
- return emailTemplate.AsAPIEmailTemplate(), err
+ return nil, err
}
- return emailTemplate.AsAPIEmailTemplate(), nil
+ return emailTemplate, nil
}
// ListEmailTemplates to list EmailTemplate
-func (p *provider) ListEmailTemplate(ctx context.Context, pagination *model.Pagination) (*model.EmailTemplates, error) {
- var emailTemplate *models.EmailTemplate
+func (p *provider) ListEmailTemplate(ctx context.Context, pagination *model.Pagination) ([]*schemas.EmailTemplate, *model.Pagination, error) {
+ var emailTemplate *schemas.EmailTemplate
var iter dynamo.PagingIter
var lastEval dynamo.PagingKey
var iteration int64 = 0
- collection := p.db.Table(models.Collections.EmailTemplate)
- emailTemplates := []*model.EmailTemplate{}
+ collection := p.db.Table(schemas.Collections.EmailTemplate)
+ emailTemplates := []*schemas.EmailTemplate{}
paginationClone := pagination
scanner := collection.Scan()
count, err := scanner.Count()
if err != nil {
- return nil, err
+ return nil, 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())
+ emailTemplates = append(emailTemplates, emailTemplate)
}
}
lastEval = iter.LastEvaluatedKey()
iteration += paginationClone.Limit
}
paginationClone.Total = count
- return &model.EmailTemplates{
- Pagination: paginationClone,
- EmailTemplates: emailTemplates,
- }, nil
+ return emailTemplates, paginationClone, 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
+func (p *provider) GetEmailTemplateByID(ctx context.Context, emailTemplateID string) (*schemas.EmailTemplate, error) {
+ collection := p.db.Table(schemas.Collections.EmailTemplate)
+ var emailTemplate *schemas.EmailTemplate
err := collection.Get("id", emailTemplateID).OneWithContext(ctx, &emailTemplate)
if err != nil {
return nil, err
}
- return emailTemplate.AsAPIEmailTemplate(), nil
+ return emailTemplate, 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
+func (p *provider) GetEmailTemplateByEventName(ctx context.Context, eventName string) (*schemas.EmailTemplate, error) {
+ collection := p.db.Table(schemas.Collections.EmailTemplate)
+ var emailTemplates []*schemas.EmailTemplate
+ var emailTemplate *schemas.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 {
+ if len(emailTemplates) == 0 {
return nil, errors.New("no record found")
- }
+ }
+ emailTemplate = emailTemplates[0]
+ return emailTemplate, nil
}
// DeleteEmailTemplate to delete EmailTemplate
-func (p *provider) DeleteEmailTemplate(ctx context.Context, emailTemplate *model.EmailTemplate) error {
- collection := p.db.Table(models.Collections.EmailTemplate)
+func (p *provider) DeleteEmailTemplate(ctx context.Context, emailTemplate *schemas.EmailTemplate) error {
+ collection := p.db.Table(schemas.Collections.EmailTemplate)
err := collection.Delete("id", emailTemplate.ID).RunWithContext(ctx)
if err != nil {
return err
diff --git a/server/db/providers/dynamodb/env.go b/internal/storage/db/dynamodb/env.go
similarity index 63%
rename from server/db/providers/dynamodb/env.go
rename to internal/storage/db/dynamodb/env.go
index 2c788a799..7d0318c1b 100644
--- a/server/db/providers/dynamodb/env.go
+++ b/internal/storage/db/dynamodb/env.go
@@ -6,13 +6,14 @@ import (
"fmt"
"time"
- "github.com/authorizerdev/authorizer/server/db/models"
"github.com/google/uuid"
+
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
// 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)
+func (p *provider) AddEnv(ctx context.Context, env *schemas.Env) (*schemas.Env, error) {
+ collection := p.db.Table(schemas.Collections.Env)
if env.ID == "" {
env.ID = uuid.New().String()
}
@@ -27,8 +28,8 @@ func (p *provider) AddEnv(ctx context.Context, env *models.Env) (*models.Env, er
}
// 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)
+func (p *provider) UpdateEnv(ctx context.Context, env *schemas.Env) (*schemas.Env, error) {
+ collection := p.db.Table(schemas.Collections.Env)
env.UpdatedAt = time.Now().Unix()
err := UpdateByHashKey(collection, "id", env.ID, env)
if err != nil {
@@ -38,10 +39,10 @@ func (p *provider) UpdateEnv(ctx context.Context, env *models.Env) (*models.Env,
}
// 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.
+func (p *provider) GetEnv(ctx context.Context) (*schemas.Env, error) {
+ var env *schemas.Env
+ collection := p.db.Table(schemas.Collections.Env)
+ // As there is no Find one supported.
iter := collection.Scan().Limit(1).Iter()
for iter.NextWithContext(ctx, &env) {
if env == nil {
diff --git a/server/db/providers/dynamodb/otp.go b/internal/storage/db/dynamodb/otp.go
similarity index 71%
rename from server/db/providers/dynamodb/otp.go
rename to internal/storage/db/dynamodb/otp.go
index 23273e26e..5e82eaf02 100644
--- a/server/db/providers/dynamodb/otp.go
+++ b/internal/storage/db/dynamodb/otp.go
@@ -5,22 +5,23 @@ import (
"errors"
"time"
- "github.com/authorizerdev/authorizer/server/db/models"
"github.com/google/uuid"
+
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
// UpsertOTP to add or update otp
-func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models.OTP, error) {
+func (p *provider) UpsertOTP(ctx context.Context, otpParam *schemas.OTP) (*schemas.OTP, error) {
// check if email or phone number is present
if otpParam.Email == "" && otpParam.PhoneNumber == "" {
return nil, errors.New("email or phone_number is required")
}
- uniqueField := models.FieldNameEmail
+ uniqueField := schemas.FieldNameEmail
if otpParam.Email == "" && otpParam.PhoneNumber != "" {
- uniqueField = models.FieldNamePhoneNumber
+ uniqueField = schemas.FieldNamePhoneNumber
}
- var otp *models.OTP
- if uniqueField == models.FieldNameEmail {
+ var otp *schemas.OTP
+ if uniqueField == schemas.FieldNameEmail {
otp, _ = p.GetOTPByEmail(ctx, otpParam.Email)
} else {
otp, _ = p.GetOTPByPhoneNumber(ctx, otpParam.PhoneNumber)
@@ -28,7 +29,7 @@ func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models
shouldCreate := false
if otp == nil {
id := uuid.NewString()
- otp = &models.OTP{
+ otp = &schemas.OTP{
ID: id,
Key: id,
Otp: otpParam.Otp,
@@ -42,7 +43,7 @@ func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models
otp.Otp = otpParam.Otp
otp.ExpiresAt = otpParam.ExpiresAt
}
- collection := p.db.Table(models.Collections.OTP)
+ collection := p.db.Table(schemas.Collections.OTP)
otp.UpdatedAt = time.Now().Unix()
var err error
if shouldCreate {
@@ -57,10 +58,10 @@ func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models
}
// 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)
+func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*schemas.OTP, error) {
+ var otps []schemas.OTP
+ var otp schemas.OTP
+ collection := p.db.Table(schemas.Collections.OTP)
err := collection.Scan().Index("email").Filter("'email' = ?", emailAddress).Limit(1).AllWithContext(ctx, &otps)
if err != nil {
return nil, err
@@ -73,10 +74,10 @@ func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*mod
}
// GetOTPByPhoneNumber to get otp for a given phone number
-func (p *provider) GetOTPByPhoneNumber(ctx context.Context, phoneNumber string) (*models.OTP, error) {
- var otps []models.OTP
- var otp models.OTP
- collection := p.db.Table(models.Collections.OTP)
+func (p *provider) GetOTPByPhoneNumber(ctx context.Context, phoneNumber string) (*schemas.OTP, error) {
+ var otps []schemas.OTP
+ var otp schemas.OTP
+ collection := p.db.Table(schemas.Collections.OTP)
err := collection.Scan().Filter("'phone_number' = ?", phoneNumber).Limit(1).AllWithContext(ctx, &otps)
if err != nil {
return nil, err
@@ -89,8 +90,8 @@ func (p *provider) GetOTPByPhoneNumber(ctx context.Context, phoneNumber string)
}
// DeleteOTP to delete otp
-func (p *provider) DeleteOTP(ctx context.Context, otp *models.OTP) error {
- collection := p.db.Table(models.Collections.OTP)
+func (p *provider) DeleteOTP(ctx context.Context, otp *schemas.OTP) error {
+ collection := p.db.Table(schemas.Collections.OTP)
if otp.ID != "" {
err := collection.Delete("id", otp.ID).RunWithContext(ctx)
if err != nil {
diff --git a/internal/storage/db/dynamodb/provider.go b/internal/storage/db/dynamodb/provider.go
new file mode 100644
index 000000000..ac4a00bd7
--- /dev/null
+++ b/internal/storage/db/dynamodb/provider.go
@@ -0,0 +1,67 @@
+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"
+ "github.com/rs/zerolog"
+
+ "github.com/authorizerdev/authorizer/internal/config"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
+)
+
+// Dependencies struct the dynamodb data store provider
+type Dependencies struct {
+ Log *zerolog.Logger
+}
+
+type provider struct {
+ config *config.Config
+ dependencies *Dependencies
+ db *dynamo.DB
+}
+
+// NewProvider returns a new Dynamo provider
+func NewProvider(cfg *config.Config, deps *Dependencies) (*provider, error) {
+ dbURL := cfg.DatabaseURL
+ awsRegion := cfg.AWSRegion
+ awsAccessKeyID := cfg.AWSAccessKeyID
+ awsSecretAccessKey := cfg.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 != "" {
+ deps.Log.Info().Msg("Using DB URL for dynamodb")
+ // static config in case of testing or local-setup
+ config.Credentials = credentials.NewStaticCredentials("key", "key", "")
+ config.Endpoint = aws.String(dbURL)
+ } else {
+ deps.Log.Info().Msg("Using default AWS credentials config from system for dynamodb")
+ }
+ session := session.Must(session.NewSession(&config))
+ db := dynamo.New(session)
+ db.CreateTable(schemas.Collections.User, schemas.User{}).Wait()
+ db.CreateTable(schemas.Collections.Session, schemas.Session{}).Wait()
+ db.CreateTable(schemas.Collections.EmailTemplate, schemas.EmailTemplate{}).Wait()
+ db.CreateTable(schemas.Collections.Env, schemas.Env{}).Wait()
+ db.CreateTable(schemas.Collections.OTP, schemas.OTP{}).Wait()
+ db.CreateTable(schemas.Collections.VerificationRequest, schemas.VerificationRequest{}).Wait()
+ db.CreateTable(schemas.Collections.Webhook, schemas.Webhook{}).Wait()
+ db.CreateTable(schemas.Collections.WebhookLog, schemas.WebhookLog{}).Wait()
+ db.CreateTable(schemas.Collections.Authenticators, schemas.Authenticator{}).Wait()
+ return &provider{
+ db: db,
+ config: cfg,
+ dependencies: deps,
+ }, nil
+}
diff --git a/server/db/providers/dynamodb/session.go b/internal/storage/db/dynamodb/session.go
similarity index 70%
rename from server/db/providers/dynamodb/session.go
rename to internal/storage/db/dynamodb/session.go
index d65da9a7f..3a06ae406 100644
--- a/server/db/providers/dynamodb/session.go
+++ b/internal/storage/db/dynamodb/session.go
@@ -4,13 +4,14 @@ import (
"context"
"time"
- "github.com/authorizerdev/authorizer/server/db/models"
"github.com/google/uuid"
+
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
// 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)
+func (p *provider) AddSession(ctx context.Context, session *schemas.Session) error {
+ collection := p.db.Table(schemas.Collections.Session)
if session.ID == "" {
session.ID = uuid.New().String()
}
diff --git a/server/db/providers/dynamodb/shared.go b/internal/storage/db/dynamodb/shared.go
similarity index 100%
rename from server/db/providers/dynamodb/shared.go
rename to internal/storage/db/dynamodb/shared.go
diff --git a/server/db/providers/dynamodb/user.go b/internal/storage/db/dynamodb/user.go
similarity index 70%
rename from server/db/providers/dynamodb/user.go
rename to internal/storage/db/dynamodb/user.go
index faa5badb4..da517e4bf 100644
--- a/server/db/providers/dynamodb/user.go
+++ b/internal/storage/db/dynamodb/user.go
@@ -7,28 +7,22 @@ import (
"strings"
"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/authorizerdev/authorizer/server/refs"
"github.com/google/uuid"
"github.com/guregu/dynamo"
- log "github.com/sirupsen/logrus"
+
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/refs"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
// 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)
+func (p *provider) AddUser(ctx context.Context, user *schemas.User) (*schemas.User, error) {
+ collection := p.db.Table(schemas.Collections.User)
if user.ID == "" {
user.ID = uuid.New().String()
}
if user.Roles == "" {
- defaultRoles, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyDefaultRoles)
- if err != nil {
- return nil, err
- }
- user.Roles = defaultRoles
+ user.Roles = strings.Join(p.config.DefaultRoles, ",")
}
if user.PhoneNumber != nil && strings.TrimSpace(refs.StringValue(user.PhoneNumber)) != "" {
if u, _ := p.GetUserByPhoneNumber(ctx, refs.StringValue(user.PhoneNumber)); u != nil && u.ID != user.ID {
@@ -49,8 +43,8 @@ func (p *provider) AddUser(ctx context.Context, user *models.User) (*models.User
}
// 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)
+func (p *provider) UpdateUser(ctx context.Context, user *schemas.User) (*schemas.User, error) {
+ collection := p.db.Table(schemas.Collections.User)
if user.ID != "" {
user.UpdatedAt = time.Now().Unix()
err := UpdateByHashKey(collection, "id", user.ID, user)
@@ -62,9 +56,9 @@ func (p *provider) UpdateUser(ctx context.Context, user *models.User) (*models.U
}
// 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)
+func (p *provider) DeleteUser(ctx context.Context, user *schemas.User) error {
+ collection := p.db.Table(schemas.Collections.User)
+ sessionCollection := p.db.Table(schemas.Collections.Session)
if user.ID != "" {
err := collection.Delete("id", user.ID).Run()
if err != nil {
@@ -79,24 +73,24 @@ func (p *provider) DeleteUser(ctx context.Context, user *models.User) error {
}
// 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
+func (p *provider) ListUsers(ctx context.Context, pagination *model.Pagination) ([]*schemas.User, *model.Pagination, error) {
+ var user *schemas.User
var lastEval dynamo.PagingKey
var iter dynamo.PagingIter
var iteration int64 = 0
- collection := p.db.Table(models.Collections.User)
- users := []*model.User{}
+ collection := p.db.Table(schemas.Collections.User)
+ var users []*schemas.User
paginationClone := pagination
scanner := collection.Scan()
count, err := scanner.Count()
if err != nil {
- return nil, err
+ return nil, 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())
+ users = append(users, user)
}
}
lastEval = iter.LastEvaluatedKey()
@@ -104,20 +98,17 @@ func (p *provider) ListUsers(ctx context.Context, pagination *model.Pagination)
}
err = iter.Err()
if err != nil {
- return nil, err
+ return nil, nil, err
}
paginationClone.Total = count
- return &model.Users{
- Pagination: paginationClone,
- Users: users,
- }, nil
+ return users, paginationClone, 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)
+func (p *provider) GetUserByEmail(ctx context.Context, email string) (*schemas.User, error) {
+ var users []*schemas.User
+ var user *schemas.User
+ collection := p.db.Table(schemas.Collections.User)
err := collection.Scan().Index("email").Filter("'email' = ?", email).AllWithContext(ctx, &users)
if err != nil {
return user, nil
@@ -131,9 +122,9 @@ func (p *provider) GetUserByEmail(ctx context.Context, email string) (*models.Us
}
// 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
+func (p *provider) GetUserByID(ctx context.Context, id string) (*schemas.User, error) {
+ collection := p.db.Table(schemas.Collections.User)
+ var user *schemas.User
err := collection.Get("id", id).OneWithContext(ctx, &user)
if err != nil {
if refs.StringValue(user.Email) == "" {
@@ -149,8 +140,8 @@ func (p *provider) GetUserByID(ctx context.Context, id string) (*models.User, er
// 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
+ userCollection := p.db.Table(schemas.Collections.User)
+ var allUsers []schemas.User
var res int64 = 0
var err error
if len(ids) > 0 {
@@ -170,16 +161,16 @@ func (p *provider) UpdateUsers(ctx context.Context, data map[string]interface{},
if err != nil {
return err
} else {
- log.Info("Updated users: ", res)
+ p.dependencies.Log.Info().Int64("modified_count", res).Msg("users updated")
}
return nil
}
// GetUserByPhoneNumber to get user information from database using phone number
-func (p *provider) GetUserByPhoneNumber(ctx context.Context, phoneNumber string) (*models.User, error) {
- var users []*models.User
- var user *models.User
- collection := p.db.Table(models.Collections.User)
+func (p *provider) GetUserByPhoneNumber(ctx context.Context, phoneNumber string) (*schemas.User, error) {
+ var users []*schemas.User
+ var user *schemas.User
+ collection := p.db.Table(schemas.Collections.User)
err := collection.Scan().Filter("'phone_number' = ?", phoneNumber).AllWithContext(ctx, &users)
if err != nil {
return nil, err
diff --git a/server/db/providers/dynamodb/verification_requests.go b/internal/storage/db/dynamodb/verification_requests.go
similarity index 67%
rename from server/db/providers/dynamodb/verification_requests.go
rename to internal/storage/db/dynamodb/verification_requests.go
index 32bceb28d..c44dd52e6 100644
--- a/server/db/providers/dynamodb/verification_requests.go
+++ b/internal/storage/db/dynamodb/verification_requests.go
@@ -4,15 +4,16 @@ 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"
+
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
// 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)
+func (p *provider) AddVerificationRequest(ctx context.Context, verificationRequest *schemas.VerificationRequest) (*schemas.VerificationRequest, error) {
+ collection := p.db.Table(schemas.Collections.VerificationRequest)
if verificationRequest.ID == "" {
verificationRequest.ID = uuid.New().String()
verificationRequest.CreatedAt = time.Now().Unix()
@@ -26,9 +27,9 @@ func (p *provider) AddVerificationRequest(ctx context.Context, verificationReque
}
// 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
+func (p *provider) GetVerificationRequestByToken(ctx context.Context, token string) (*schemas.VerificationRequest, error) {
+ collection := p.db.Table(schemas.Collections.VerificationRequest)
+ var verificationRequest *schemas.VerificationRequest
iter := collection.Scan().Filter("'token' = ?", token).Iter()
for iter.NextWithContext(ctx, &verificationRequest) {
return verificationRequest, nil
@@ -41,9 +42,9 @@ func (p *provider) GetVerificationRequestByToken(ctx context.Context, token stri
}
// 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)
+func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email string, identifier string) (*schemas.VerificationRequest, error) {
+ var verificationRequest *schemas.VerificationRequest
+ collection := p.db.Table(schemas.Collections.VerificationRequest)
iter := collection.Scan().Filter("'email' = ?", email).Filter("'identifier' = ?", identifier).Iter()
for iter.NextWithContext(ctx, &verificationRequest) {
return verificationRequest, nil
@@ -56,43 +57,40 @@ func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email stri
}
// 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
+func (p *provider) ListVerificationRequests(ctx context.Context, pagination *model.Pagination) ([]*schemas.VerificationRequest, *model.Pagination, error) {
+ var verificationRequests []*schemas.VerificationRequest
+ var verificationRequest *schemas.VerificationRequest
var lastEval dynamo.PagingKey
var iter dynamo.PagingIter
var iteration int64 = 0
- collection := p.db.Table(models.Collections.VerificationRequest)
+ collection := p.db.Table(schemas.Collections.VerificationRequest)
paginationClone := pagination
scanner := collection.Scan()
count, err := scanner.Count()
if err != nil {
- return nil, err
+ return nil, 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())
+ verificationRequests = append(verificationRequests, verificationRequest)
}
}
err = iter.Err()
if err != nil {
- return nil, err
+ return nil, nil, err
}
lastEval = iter.LastEvaluatedKey()
iteration += paginationClone.Limit
}
paginationClone.Total = count
- return &model.VerificationRequests{
- VerificationRequests: verificationRequests,
- Pagination: paginationClone,
- }, nil
+ return verificationRequests, 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)
+func (p *provider) DeleteVerificationRequest(ctx context.Context, verificationRequest *schemas.VerificationRequest) error {
+ collection := p.db.Table(schemas.Collections.VerificationRequest)
if verificationRequest != nil {
err := collection.Delete("id", verificationRequest.ID).RunWithContext(ctx)
diff --git a/server/db/providers/dynamodb/webhook.go b/internal/storage/db/dynamodb/webhook.go
similarity index 56%
rename from server/db/providers/dynamodb/webhook.go
rename to internal/storage/db/dynamodb/webhook.go
index ca47b71d3..e85ef9640 100644
--- a/server/db/providers/dynamodb/webhook.go
+++ b/internal/storage/db/dynamodb/webhook.go
@@ -10,13 +10,13 @@ import (
"github.com/google/uuid"
"github.com/guregu/dynamo"
- "github.com/authorizerdev/authorizer/server/db/models"
- "github.com/authorizerdev/authorizer/server/graph/model"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
// AddWebhook to add webhook
-func (p *provider) AddWebhook(ctx context.Context, webhook *models.Webhook) (*model.Webhook, error) {
- collection := p.db.Table(models.Collections.Webhook)
+func (p *provider) AddWebhook(ctx context.Context, webhook *schemas.Webhook) (*schemas.Webhook, error) {
+ collection := p.db.Table(schemas.Collections.Webhook)
if webhook.ID == "" {
webhook.ID = uuid.New().String()
}
@@ -29,109 +29,104 @@ func (p *provider) AddWebhook(ctx context.Context, webhook *models.Webhook) (*mo
if err != nil {
return nil, err
}
- return webhook.AsAPIWebhook(), nil
+ return webhook, nil
}
// UpdateWebhook to update webhook
-func (p *provider) UpdateWebhook(ctx context.Context, webhook *models.Webhook) (*model.Webhook, error) {
+func (p *provider) UpdateWebhook(ctx context.Context, webhook *schemas.Webhook) (*schemas.Webhook, error) {
webhook.UpdatedAt = time.Now().Unix()
// Event is changed
if !strings.Contains(webhook.EventName, "-") {
webhook.EventName = fmt.Sprintf("%s-%d", webhook.EventName, time.Now().Unix())
}
- collection := p.db.Table(models.Collections.Webhook)
+ collection := p.db.Table(schemas.Collections.Webhook)
err := UpdateByHashKey(collection, "id", webhook.ID, webhook)
if err != nil {
return nil, err
}
- return webhook.AsAPIWebhook(), nil
+ return webhook, 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
+func (p *provider) ListWebhook(ctx context.Context, pagination *model.Pagination) ([]*schemas.Webhook, *model.Pagination, error) {
+ webhooks := []*schemas.Webhook{}
+ var webhook *schemas.Webhook
var lastEval dynamo.PagingKey
var iter dynamo.PagingIter
var iteration int64 = 0
- collection := p.db.Table(models.Collections.Webhook)
+ collection := p.db.Table(schemas.Collections.Webhook)
paginationClone := pagination
scanner := collection.Scan()
count, err := scanner.Count()
if err != nil {
- return nil, err
+ return nil, 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())
+ webhooks = append(webhooks, webhook)
}
}
err = iter.Err()
if err != nil {
- return nil, err
+ return nil, nil, err
}
lastEval = iter.LastEvaluatedKey()
iteration += paginationClone.Limit
}
paginationClone.Total = count
- return &model.Webhooks{
- Pagination: paginationClone,
- Webhooks: webhooks,
- }, nil
+ return webhooks, paginationClone, 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
+func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*schemas.Webhook, error) {
+ collection := p.db.Table(schemas.Collections.Webhook)
+ var webhook *schemas.Webhook
err := collection.Get("id", webhookID).OneWithContext(ctx, &webhook)
if err != nil {
return nil, err
}
if webhook.ID == "" {
- return nil, errors.New("no documets found")
+ return nil, errors.New("no document found")
}
- return webhook.AsAPIWebhook(), nil
+ return webhook, nil
}
// GetWebhookByEventName to get webhook by event_name
-func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string) ([]*model.Webhook, error) {
- webhooks := []models.Webhook{}
- collection := p.db.Table(models.Collections.Webhook)
+func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string) ([]*schemas.Webhook, error) {
+ webhooks := []*schemas.Webhook{}
+ collection := p.db.Table(schemas.Collections.Webhook)
err := collection.Scan().Index("event_name").Filter("contains(event_name, ?)", eventName).AllWithContext(ctx, &webhooks)
if err != nil {
return nil, err
}
- resWebhooks := []*model.Webhook{}
- for _, w := range webhooks {
- resWebhooks = append(resWebhooks, w.AsAPIWebhook())
- }
- return resWebhooks, nil
+ return webhooks, nil
}
// DeleteWebhook to delete webhook
-func (p *provider) DeleteWebhook(ctx context.Context, webhook *model.Webhook) error {
+func (p *provider) DeleteWebhook(ctx context.Context, webhook *schemas.Webhook) error {
// Also delete webhook logs for given webhook id
if webhook != nil {
- webhookCollection := p.db.Table(models.Collections.Webhook)
- webhookLogCollection := p.db.Table(models.Collections.WebhookLog)
+ webhookCollection := p.db.Table(schemas.Collections.Webhook)
+ webhookLogCollection := p.db.Table(schemas.Collections.WebhookLog)
err := webhookCollection.Delete("id", webhook.ID).RunWithContext(ctx)
if err != nil {
return err
}
pagination := &model.Pagination{}
- 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
+ webhookLogs, _, err := p.ListWebhookLogs(ctx, pagination, webhook.ID)
+ if err != nil {
+ p.dependencies.Log.Debug().Err(err).Msg("failed to list webhook logs")
+ } else {
+ for _, webhookLog := range webhookLogs {
+ err = webhookLogCollection.Delete("id", webhookLog.ID).RunWithContext(ctx)
+ if err != nil {
+ p.dependencies.Log.Debug().Err(err).Msg("failed to delete webhook log")
+ // continue
+ }
}
}
- if errIs != nil {
- return errIs
- }
}
return nil
}
diff --git a/server/db/providers/dynamodb/webhook_log.go b/internal/storage/db/dynamodb/webhook_log.go
similarity index 66%
rename from server/db/providers/dynamodb/webhook_log.go
rename to internal/storage/db/dynamodb/webhook_log.go
index 18ba2613d..2092b1d18 100644
--- a/server/db/providers/dynamodb/webhook_log.go
+++ b/internal/storage/db/dynamodb/webhook_log.go
@@ -4,15 +4,16 @@ 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"
+
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
// 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)
+func (p *provider) AddWebhookLog(ctx context.Context, webhookLog *schemas.WebhookLog) (*schemas.WebhookLog, error) {
+ collection := p.db.Table(schemas.Collections.WebhookLog)
if webhookLog.ID == "" {
webhookLog.ID = uuid.New().String()
}
@@ -23,42 +24,42 @@ func (p *provider) AddWebhookLog(ctx context.Context, webhookLog *models.Webhook
if err != nil {
return nil, err
}
- return webhookLog.AsAPIWebhookLog(), nil
+ return webhookLog, 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
+func (p *provider) ListWebhookLogs(ctx context.Context, pagination *model.Pagination, webhookID string) ([]*schemas.WebhookLog, *model.Pagination, error) {
+ webhookLogs := []*schemas.WebhookLog{}
+ var webhookLog *schemas.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)
+ collection := p.db.Table(schemas.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())
+ webhookLogs = append(webhookLogs, webhookLog)
}
err = iter.Err()
if err != nil {
- return nil, err
+ return nil, 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())
+ webhookLogs = append(webhookLogs, webhookLog)
}
}
err = iter.Err()
if err != nil {
- return nil, err
+ return nil, nil, err
}
lastEval = iter.LastEvaluatedKey()
iteration += paginationClone.Limit
@@ -66,8 +67,5 @@ func (p *provider) ListWebhookLogs(ctx context.Context, pagination *model.Pagina
}
paginationClone.Total = count
// paginationClone.Cursor = iter.LastEvaluatedKey()
- return &model.WebhookLogs{
- Pagination: paginationClone,
- WebhookLogs: webhookLogs,
- }, nil
+ return webhookLogs, paginationClone, nil
}
diff --git a/server/db/providers/mongodb/authenticator.go b/internal/storage/db/mongodb/authenticator.go
similarity index 66%
rename from server/db/providers/mongodb/authenticator.go
rename to internal/storage/db/mongodb/authenticator.go
index 7dae455b0..edb1c4cb1 100644
--- a/server/db/providers/mongodb/authenticator.go
+++ b/internal/storage/db/mongodb/authenticator.go
@@ -8,10 +8,10 @@ import (
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo/options"
- "github.com/authorizerdev/authorizer/server/db/models"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
-func (p *provider) AddAuthenticator(ctx context.Context, authenticators *models.Authenticator) (*models.Authenticator, error) {
+func (p *provider) AddAuthenticator(ctx context.Context, authenticators *schemas.Authenticator) (*schemas.Authenticator, error) {
exists, _ := p.GetAuthenticatorDetailsByUserId(ctx, authenticators.UserID, authenticators.Method)
if exists != nil {
return authenticators, nil
@@ -23,7 +23,7 @@ func (p *provider) AddAuthenticator(ctx context.Context, authenticators *models.
authenticators.CreatedAt = time.Now().Unix()
authenticators.UpdatedAt = time.Now().Unix()
authenticators.Key = authenticators.ID
- authenticatorsCollection := p.db.Collection(models.Collections.Authenticators, options.Collection())
+ authenticatorsCollection := p.db.Collection(schemas.Collections.Authenticators, options.Collection())
_, err := authenticatorsCollection.InsertOne(ctx, authenticators)
if err != nil {
return nil, err
@@ -31,9 +31,9 @@ func (p *provider) AddAuthenticator(ctx context.Context, authenticators *models.
return authenticators, nil
}
-func (p *provider) UpdateAuthenticator(ctx context.Context, authenticators *models.Authenticator) (*models.Authenticator, error) {
+func (p *provider) UpdateAuthenticator(ctx context.Context, authenticators *schemas.Authenticator) (*schemas.Authenticator, error) {
authenticators.UpdatedAt = time.Now().Unix()
- authenticatorsCollection := p.db.Collection(models.Collections.Authenticators, options.Collection())
+ authenticatorsCollection := p.db.Collection(schemas.Collections.Authenticators, options.Collection())
_, err := authenticatorsCollection.UpdateOne(ctx, bson.M{"_id": bson.M{"$eq": authenticators.ID}}, bson.M{"$set": authenticators})
if err != nil {
return nil, err
@@ -41,9 +41,9 @@ func (p *provider) UpdateAuthenticator(ctx context.Context, authenticators *mode
return authenticators, nil
}
-func (p *provider) GetAuthenticatorDetailsByUserId(ctx context.Context, userId string, authenticatorType string) (*models.Authenticator, error) {
- var authenticators *models.Authenticator
- authenticatorsCollection := p.db.Collection(models.Collections.Authenticators, options.Collection())
+func (p *provider) GetAuthenticatorDetailsByUserId(ctx context.Context, userId string, authenticatorType string) (*schemas.Authenticator, error) {
+ var authenticators *schemas.Authenticator
+ authenticatorsCollection := p.db.Collection(schemas.Collections.Authenticators, options.Collection())
err := authenticatorsCollection.FindOne(ctx, bson.M{"user_id": userId, "method": authenticatorType}).Decode(&authenticators)
if err != nil {
return nil, err
diff --git a/server/db/providers/mongodb/email_template.go b/internal/storage/db/mongodb/email_template.go
similarity index 56%
rename from server/db/providers/mongodb/email_template.go
rename to internal/storage/db/mongodb/email_template.go
index c3fa31b01..ed4b3a1b0 100644
--- a/server/db/providers/mongodb/email_template.go
+++ b/internal/storage/db/mongodb/email_template.go
@@ -4,99 +4,97 @@ import (
"context"
"time"
- "github.com/authorizerdev/authorizer/server/db/models"
- "github.com/authorizerdev/authorizer/server/graph/model"
"github.com/google/uuid"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo/options"
+
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
// AddEmailTemplate to add EmailTemplate
-func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate *models.EmailTemplate) (*model.EmailTemplate, error) {
+func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate *schemas.EmailTemplate) (*schemas.EmailTemplate, error) {
if emailTemplate.ID == "" {
emailTemplate.ID = uuid.New().String()
}
emailTemplate.Key = emailTemplate.ID
emailTemplate.CreatedAt = time.Now().Unix()
emailTemplate.UpdatedAt = time.Now().Unix()
- emailTemplateCollection := p.db.Collection(models.Collections.EmailTemplate, options.Collection())
+ emailTemplateCollection := p.db.Collection(schemas.Collections.EmailTemplate, options.Collection())
_, err := emailTemplateCollection.InsertOne(ctx, emailTemplate)
if err != nil {
return nil, err
}
- return emailTemplate.AsAPIEmailTemplate(), nil
+ return emailTemplate, nil
}
// UpdateEmailTemplate to update EmailTemplate
-func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate *models.EmailTemplate) (*model.EmailTemplate, error) {
+func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate *schemas.EmailTemplate) (*schemas.EmailTemplate, error) {
emailTemplate.UpdatedAt = time.Now().Unix()
- emailTemplateCollection := p.db.Collection(models.Collections.EmailTemplate, options.Collection())
+ emailTemplateCollection := p.db.Collection(schemas.Collections.EmailTemplate, options.Collection())
_, err := emailTemplateCollection.UpdateOne(ctx, bson.M{"_id": bson.M{"$eq": emailTemplate.ID}}, bson.M{"$set": emailTemplate}, options.MergeUpdateOptions())
if err != nil {
return nil, err
}
- return emailTemplate.AsAPIEmailTemplate(), nil
+ return emailTemplate, nil
}
// ListEmailTemplates to list EmailTemplate
-func (p *provider) ListEmailTemplate(ctx context.Context, pagination *model.Pagination) (*model.EmailTemplates, error) {
- var emailTemplates []*model.EmailTemplate
+func (p *provider) ListEmailTemplate(ctx context.Context, pagination *model.Pagination) ([]*schemas.EmailTemplate, *model.Pagination, error) {
+ var emailTemplates []*schemas.EmailTemplate
opts := options.Find()
opts.SetLimit(pagination.Limit)
opts.SetSkip(pagination.Offset)
opts.SetSort(bson.M{"created_at": -1})
paginationClone := pagination
- emailTemplateCollection := p.db.Collection(models.Collections.EmailTemplate, options.Collection())
+ emailTemplateCollection := p.db.Collection(schemas.Collections.EmailTemplate, options.Collection())
count, err := emailTemplateCollection.CountDocuments(ctx, bson.M{}, options.Count())
if err != nil {
- return nil, err
+ return nil, nil, err
}
paginationClone.Total = count
cursor, err := emailTemplateCollection.Find(ctx, bson.M{}, opts)
if err != nil {
- return nil, err
+ return nil, nil, err
}
defer cursor.Close(ctx)
for cursor.Next(ctx) {
- var emailTemplate *models.EmailTemplate
+ var emailTemplate *schemas.EmailTemplate
err := cursor.Decode(&emailTemplate)
if err != nil {
- return nil, err
+ return nil, nil, err
}
- emailTemplates = append(emailTemplates, emailTemplate.AsAPIEmailTemplate())
+ emailTemplates = append(emailTemplates, emailTemplate)
}
- return &model.EmailTemplates{
- Pagination: paginationClone,
- EmailTemplates: emailTemplates,
- }, nil
+ return emailTemplates, paginationClone, nil
}
// GetEmailTemplateByID to get EmailTemplate by id
-func (p *provider) GetEmailTemplateByID(ctx context.Context, emailTemplateID string) (*model.EmailTemplate, error) {
- var emailTemplate *models.EmailTemplate
- emailTemplateCollection := p.db.Collection(models.Collections.EmailTemplate, options.Collection())
+func (p *provider) GetEmailTemplateByID(ctx context.Context, emailTemplateID string) (*schemas.EmailTemplate, error) {
+ var emailTemplate *schemas.EmailTemplate
+ emailTemplateCollection := p.db.Collection(schemas.Collections.EmailTemplate, options.Collection())
err := emailTemplateCollection.FindOne(ctx, bson.M{"_id": emailTemplateID}).Decode(&emailTemplate)
if err != nil {
return nil, err
}
- return emailTemplate.AsAPIEmailTemplate(), nil
+ return emailTemplate, nil
}
// GetEmailTemplateByEventName to get EmailTemplate by event_name
-func (p *provider) GetEmailTemplateByEventName(ctx context.Context, eventName string) (*model.EmailTemplate, error) {
- var emailTemplate *models.EmailTemplate
- emailTemplateCollection := p.db.Collection(models.Collections.EmailTemplate, options.Collection())
+func (p *provider) GetEmailTemplateByEventName(ctx context.Context, eventName string) (*schemas.EmailTemplate, error) {
+ var emailTemplate *schemas.EmailTemplate
+ emailTemplateCollection := p.db.Collection(schemas.Collections.EmailTemplate, options.Collection())
err := emailTemplateCollection.FindOne(ctx, bson.M{"event_name": eventName}).Decode(&emailTemplate)
if err != nil {
return nil, err
}
- return emailTemplate.AsAPIEmailTemplate(), nil
+ return emailTemplate, nil
}
// DeleteEmailTemplate to delete EmailTemplate
-func (p *provider) DeleteEmailTemplate(ctx context.Context, emailTemplate *model.EmailTemplate) error {
- emailTemplateCollection := p.db.Collection(models.Collections.EmailTemplate, options.Collection())
- _, err := emailTemplateCollection.DeleteOne(nil, bson.M{"_id": emailTemplate.ID}, options.Delete())
+func (p *provider) DeleteEmailTemplate(ctx context.Context, emailTemplate *schemas.EmailTemplate) error {
+ emailTemplateCollection := p.db.Collection(schemas.Collections.EmailTemplate, options.Collection())
+ _, err := emailTemplateCollection.DeleteOne(ctx, bson.M{"_id": emailTemplate.ID}, options.Delete())
if err != nil {
return err
}
diff --git a/server/db/providers/mongodb/env.go b/internal/storage/db/mongodb/env.go
similarity index 63%
rename from server/db/providers/mongodb/env.go
rename to internal/storage/db/mongodb/env.go
index f88163a5e..d07a6ff67 100644
--- a/server/db/providers/mongodb/env.go
+++ b/internal/storage/db/mongodb/env.go
@@ -5,21 +5,22 @@ import (
"fmt"
"time"
- "github.com/authorizerdev/authorizer/server/db/models"
"github.com/google/uuid"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo/options"
+
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
// AddEnv to save environment information in database
-func (p *provider) AddEnv(ctx context.Context, env *models.Env) (*models.Env, error) {
+func (p *provider) AddEnv(ctx context.Context, env *schemas.Env) (*schemas.Env, error) {
if env.ID == "" {
env.ID = uuid.New().String()
}
env.CreatedAt = time.Now().Unix()
env.UpdatedAt = time.Now().Unix()
env.Key = env.ID
- configCollection := p.db.Collection(models.Collections.Env, options.Collection())
+ configCollection := p.db.Collection(schemas.Collections.Env, options.Collection())
_, err := configCollection.InsertOne(ctx, env)
if err != nil {
return nil, err
@@ -28,9 +29,9 @@ func (p *provider) AddEnv(ctx context.Context, env *models.Env) (*models.Env, er
}
// UpdateEnv to update environment information in database
-func (p *provider) UpdateEnv(ctx context.Context, env *models.Env) (*models.Env, error) {
+func (p *provider) UpdateEnv(ctx context.Context, env *schemas.Env) (*schemas.Env, error) {
env.UpdatedAt = time.Now().Unix()
- configCollection := p.db.Collection(models.Collections.Env, options.Collection())
+ configCollection := p.db.Collection(schemas.Collections.Env, options.Collection())
_, err := configCollection.UpdateOne(ctx, bson.M{"_id": bson.M{"$eq": env.ID}}, bson.M{"$set": env}, options.MergeUpdateOptions())
if err != nil {
return nil, err
@@ -39,15 +40,15 @@ func (p *provider) UpdateEnv(ctx context.Context, env *models.Env) (*models.Env,
}
// GetEnv to get environment information from database
-func (p *provider) GetEnv(ctx context.Context) (*models.Env, error) {
- var env *models.Env
- configCollection := p.db.Collection(models.Collections.Env, options.Collection())
+func (p *provider) GetEnv(ctx context.Context) (*schemas.Env, error) {
+ var env *schemas.Env
+ configCollection := p.db.Collection(schemas.Collections.Env, options.Collection())
cursor, err := configCollection.Find(ctx, bson.M{}, options.Find())
if err != nil {
return nil, err
}
defer cursor.Close(ctx)
- for cursor.Next(nil) {
+ for cursor.Next(ctx) {
err := cursor.Decode(&env)
if err != nil {
return nil, err
diff --git a/server/db/providers/mongodb/otp.go b/internal/storage/db/mongodb/otp.go
similarity index 66%
rename from server/db/providers/mongodb/otp.go
rename to internal/storage/db/mongodb/otp.go
index d70818d18..9f7684392 100644
--- a/server/db/providers/mongodb/otp.go
+++ b/internal/storage/db/mongodb/otp.go
@@ -5,24 +5,25 @@ import (
"errors"
"time"
- "github.com/authorizerdev/authorizer/server/db/models"
"github.com/google/uuid"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo/options"
+
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
// UpsertOTP to add or update otp
-func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models.OTP, error) {
+func (p *provider) UpsertOTP(ctx context.Context, otpParam *schemas.OTP) (*schemas.OTP, error) {
// check if email or phone number is present
if otpParam.Email == "" && otpParam.PhoneNumber == "" {
return nil, errors.New("email or phone_number is required")
}
- uniqueField := models.FieldNameEmail
+ uniqueField := schemas.FieldNameEmail
if otpParam.Email == "" && otpParam.PhoneNumber != "" {
- uniqueField = models.FieldNamePhoneNumber
+ uniqueField = schemas.FieldNamePhoneNumber
}
- var otp *models.OTP
- if uniqueField == models.FieldNameEmail {
+ var otp *schemas.OTP
+ if uniqueField == schemas.FieldNameEmail {
otp, _ = p.GetOTPByEmail(ctx, otpParam.Email)
} else {
otp, _ = p.GetOTPByPhoneNumber(ctx, otpParam.PhoneNumber)
@@ -30,7 +31,7 @@ func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models
shouldCreate := false
if otp == nil {
id := uuid.NewString()
- otp = &models.OTP{
+ otp = &schemas.OTP{
ID: id,
Key: id,
Otp: otpParam.Otp,
@@ -45,7 +46,7 @@ func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models
otp.ExpiresAt = otpParam.ExpiresAt
}
otp.UpdatedAt = time.Now().Unix()
- otpCollection := p.db.Collection(models.Collections.OTP, options.Collection())
+ otpCollection := p.db.Collection(schemas.Collections.OTP, options.Collection())
var err error
if shouldCreate {
@@ -60,9 +61,9 @@ func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models
}
// GetOTPByEmail to get otp for a given email address
-func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*models.OTP, error) {
- var otp models.OTP
- otpCollection := p.db.Collection(models.Collections.OTP, options.Collection())
+func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*schemas.OTP, error) {
+ var otp schemas.OTP
+ otpCollection := p.db.Collection(schemas.Collections.OTP, options.Collection())
err := otpCollection.FindOne(ctx, bson.M{"email": emailAddress}).Decode(&otp)
if err != nil {
return nil, err
@@ -71,9 +72,9 @@ func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*mod
}
// GetOTPByPhoneNumber to get otp for a given phone number
-func (p *provider) GetOTPByPhoneNumber(ctx context.Context, phoneNumber string) (*models.OTP, error) {
- var otp models.OTP
- otpCollection := p.db.Collection(models.Collections.OTP, options.Collection())
+func (p *provider) GetOTPByPhoneNumber(ctx context.Context, phoneNumber string) (*schemas.OTP, error) {
+ var otp schemas.OTP
+ otpCollection := p.db.Collection(schemas.Collections.OTP, options.Collection())
err := otpCollection.FindOne(ctx, bson.M{"phone_number": phoneNumber}).Decode(&otp)
if err != nil {
return nil, err
@@ -82,9 +83,9 @@ func (p *provider) GetOTPByPhoneNumber(ctx context.Context, phoneNumber string)
}
// DeleteOTP to delete otp
-func (p *provider) DeleteOTP(ctx context.Context, otp *models.OTP) error {
- otpCollection := p.db.Collection(models.Collections.OTP, options.Collection())
- _, err := otpCollection.DeleteOne(nil, bson.M{"_id": otp.ID}, options.Delete())
+func (p *provider) DeleteOTP(ctx context.Context, otp *schemas.OTP) error {
+ otpCollection := p.db.Collection(schemas.Collections.OTP, options.Collection())
+ _, err := otpCollection.DeleteOne(ctx, bson.M{"_id": otp.ID}, options.Delete())
if err != nil {
return err
}
diff --git a/server/db/providers/mongodb/provider.go b/internal/storage/db/mongodb/provider.go
similarity index 56%
rename from server/db/providers/mongodb/provider.go
rename to internal/storage/db/mongodb/provider.go
index 1f174e3dd..9a5144656 100644
--- a/server/db/providers/mongodb/provider.go
+++ b/internal/storage/db/mongodb/provider.go
@@ -2,32 +2,38 @@ package mongodb
import (
"context"
+ "fmt"
"time"
- "github.com/authorizerdev/authorizer/server/db/models"
- "github.com/authorizerdev/authorizer/server/memorystore"
+ "github.com/rs/zerolog"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"go.mongodb.org/mongo-driver/mongo/readpref"
+
+ "github.com/authorizerdev/authorizer/internal/config"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
+// Dependencies struct the mongodb data store provider
+type Dependencies struct {
+ Log *zerolog.Logger
+}
+
type provider struct {
- db *mongo.Database
+ config *config.Config
+ dependencies *Dependencies
+ db *mongo.Database
}
// NewProvider to initialize mongodb connection
-func NewProvider() (*provider, error) {
- dbURL := memorystore.RequiredEnvStoreObj.GetRequiredEnv().DatabaseURL
+func NewProvider(config *config.Config, deps *Dependencies) (*provider, error) {
+ dbURL := config.DatabaseURL
mongodbOptions := options.Client().ApplyURI(dbURL)
maxWait := time.Duration(5 * time.Second)
mongodbOptions.ConnectTimeout = &maxWait
- mongoClient, err := mongo.NewClient(mongodbOptions)
- if err != nil {
- return nil, err
- }
ctx, _ := context.WithTimeout(context.Background(), 30*time.Second)
- err = mongoClient.Connect(ctx)
+ mongoClient, err := mongo.Connect(ctx, mongodbOptions)
if err != nil {
return nil, err
}
@@ -37,11 +43,14 @@ func NewProvider() (*provider, error) {
return nil, err
}
- dbName := memorystore.RequiredEnvStoreObj.GetRequiredEnv().DatabaseName
+ dbName := config.DatabaseName
+ if dbName == "" {
+ return nil, fmt.Errorf("database name is required for mongodb")
+ }
mongodb := mongoClient.Database(dbName, options.Database())
- mongodb.CreateCollection(ctx, models.Collections.User, options.CreateCollection())
- userCollection := mongodb.Collection(models.Collections.User, options.Collection())
+ mongodb.CreateCollection(ctx, schemas.Collections.User, options.CreateCollection())
+ userCollection := mongodb.Collection(schemas.Collections.User, options.Collection())
userCollection.Indexes().CreateMany(ctx, []mongo.IndexModel{
{
Keys: bson.M{"email": 1},
@@ -54,8 +63,8 @@ func NewProvider() (*provider, error) {
}),
},
}, options.CreateIndexes())
- mongodb.CreateCollection(ctx, models.Collections.VerificationRequest, options.CreateCollection())
- verificationRequestCollection := mongodb.Collection(models.Collections.VerificationRequest, options.Collection())
+ mongodb.CreateCollection(ctx, schemas.Collections.VerificationRequest, options.CreateCollection())
+ verificationRequestCollection := mongodb.Collection(schemas.Collections.VerificationRequest, options.Collection())
verificationRequestCollection.Indexes().CreateMany(ctx, []mongo.IndexModel{
{
Keys: bson.M{"email": 1, "identifier": 1},
@@ -69,8 +78,8 @@ func NewProvider() (*provider, error) {
},
}, options.CreateIndexes())
- mongodb.CreateCollection(ctx, models.Collections.Session, options.CreateCollection())
- sessionCollection := mongodb.Collection(models.Collections.Session, options.Collection())
+ mongodb.CreateCollection(ctx, schemas.Collections.Session, options.CreateCollection())
+ sessionCollection := mongodb.Collection(schemas.Collections.Session, options.Collection())
sessionCollection.Indexes().CreateMany(ctx, []mongo.IndexModel{
{
Keys: bson.M{"user_id": 1},
@@ -78,10 +87,10 @@ func NewProvider() (*provider, error) {
},
}, options.CreateIndexes())
- mongodb.CreateCollection(ctx, models.Collections.Env, options.CreateCollection())
+ mongodb.CreateCollection(ctx, schemas.Collections.Env, options.CreateCollection())
- mongodb.CreateCollection(ctx, models.Collections.Webhook, options.CreateCollection())
- webhookCollection := mongodb.Collection(models.Collections.Webhook, options.Collection())
+ mongodb.CreateCollection(ctx, schemas.Collections.Webhook, options.CreateCollection())
+ webhookCollection := mongodb.Collection(schemas.Collections.Webhook, options.Collection())
webhookCollection.Indexes().CreateMany(ctx, []mongo.IndexModel{
{
Keys: bson.M{"event_name": 1},
@@ -89,8 +98,8 @@ func NewProvider() (*provider, error) {
},
}, options.CreateIndexes())
- mongodb.CreateCollection(ctx, models.Collections.WebhookLog, options.CreateCollection())
- webhookLogCollection := mongodb.Collection(models.Collections.WebhookLog, options.Collection())
+ mongodb.CreateCollection(ctx, schemas.Collections.WebhookLog, options.CreateCollection())
+ webhookLogCollection := mongodb.Collection(schemas.Collections.WebhookLog, options.Collection())
webhookLogCollection.Indexes().CreateMany(ctx, []mongo.IndexModel{
{
Keys: bson.M{"webhook_id": 1},
@@ -98,8 +107,8 @@ func NewProvider() (*provider, error) {
},
}, options.CreateIndexes())
- mongodb.CreateCollection(ctx, models.Collections.EmailTemplate, options.CreateCollection())
- emailTemplateCollection := mongodb.Collection(models.Collections.EmailTemplate, options.Collection())
+ mongodb.CreateCollection(ctx, schemas.Collections.EmailTemplate, options.CreateCollection())
+ emailTemplateCollection := mongodb.Collection(schemas.Collections.EmailTemplate, options.Collection())
emailTemplateCollection.Indexes().CreateMany(ctx, []mongo.IndexModel{
{
Keys: bson.M{"event_name": 1},
@@ -107,8 +116,8 @@ func NewProvider() (*provider, error) {
},
}, options.CreateIndexes())
- mongodb.CreateCollection(ctx, models.Collections.OTP, options.CreateCollection())
- otpCollection := mongodb.Collection(models.Collections.OTP, options.Collection())
+ mongodb.CreateCollection(ctx, schemas.Collections.OTP, options.CreateCollection())
+ otpCollection := mongodb.Collection(schemas.Collections.OTP, options.Collection())
otpCollection.Indexes().CreateMany(ctx, []mongo.IndexModel{
{
Keys: bson.M{"email": 1},
@@ -122,8 +131,8 @@ func NewProvider() (*provider, error) {
},
}, options.CreateIndexes())
- mongodb.CreateCollection(ctx, models.Collections.Authenticators, options.CreateCollection())
- authenticatorsCollection := mongodb.Collection(models.Collections.Authenticators, options.Collection())
+ mongodb.CreateCollection(ctx, schemas.Collections.Authenticators, options.CreateCollection())
+ authenticatorsCollection := mongodb.Collection(schemas.Collections.Authenticators, options.Collection())
authenticatorsCollection.Indexes().CreateMany(ctx, []mongo.IndexModel{
{
Keys: bson.M{"user_id": 1},
@@ -132,6 +141,8 @@ func NewProvider() (*provider, error) {
}, options.CreateIndexes())
return &provider{
- db: mongodb,
+ config: config,
+ dependencies: deps,
+ db: mongodb,
}, nil
}
diff --git a/server/db/providers/mongodb/session.go b/internal/storage/db/mongodb/session.go
similarity index 71%
rename from server/db/providers/mongodb/session.go
rename to internal/storage/db/mongodb/session.go
index 860eeefb3..395187fd0 100644
--- a/server/db/providers/mongodb/session.go
+++ b/internal/storage/db/mongodb/session.go
@@ -4,13 +4,14 @@ import (
"context"
"time"
- "github.com/authorizerdev/authorizer/server/db/models"
"github.com/google/uuid"
"go.mongodb.org/mongo-driver/mongo/options"
+
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
// AddSession to save session information in database
-func (p *provider) AddSession(ctx context.Context, session *models.Session) error {
+func (p *provider) AddSession(ctx context.Context, session *schemas.Session) error {
if session.ID == "" {
session.ID = uuid.New().String()
}
@@ -18,7 +19,7 @@ func (p *provider) AddSession(ctx context.Context, session *models.Session) erro
session.Key = session.ID
session.CreatedAt = time.Now().Unix()
session.UpdatedAt = time.Now().Unix()
- sessionCollection := p.db.Collection(models.Collections.Session, options.Collection())
+ sessionCollection := p.db.Collection(schemas.Collections.Session, options.Collection())
_, err := sessionCollection.InsertOne(ctx, session)
if err != nil {
return err
diff --git a/server/db/providers/mongodb/user.go b/internal/storage/db/mongodb/user.go
similarity index 65%
rename from server/db/providers/mongodb/user.go
rename to internal/storage/db/mongodb/user.go
index 776c4fc97..cfaa27f22 100644
--- a/server/db/providers/mongodb/user.go
+++ b/internal/storage/db/mongodb/user.go
@@ -6,29 +6,23 @@ import (
"strings"
"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/authorizerdev/authorizer/server/refs"
"github.com/google/uuid"
- log "github.com/sirupsen/logrus"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
+
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/refs"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
// AddUser to save user information in database
-func (p *provider) AddUser(ctx context.Context, user *models.User) (*models.User, error) {
+func (p *provider) AddUser(ctx context.Context, user *schemas.User) (*schemas.User, error) {
if user.ID == "" {
user.ID = uuid.New().String()
}
if user.Roles == "" {
- defaultRoles, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyDefaultRoles)
- if err != nil {
- return nil, err
- }
- user.Roles = defaultRoles
+ user.Roles = strings.Join(p.config.DefaultRoles, ",")
}
if user.PhoneNumber != nil && strings.TrimSpace(refs.StringValue(user.PhoneNumber)) != "" {
if u, _ := p.GetUserByPhoneNumber(ctx, refs.StringValue(user.PhoneNumber)); u != nil && u.ID != user.ID {
@@ -42,7 +36,7 @@ func (p *provider) AddUser(ctx context.Context, user *models.User) (*models.User
user.CreatedAt = time.Now().Unix()
user.UpdatedAt = time.Now().Unix()
user.Key = user.ID
- userCollection := p.db.Collection(models.Collections.User, options.Collection())
+ userCollection := p.db.Collection(schemas.Collections.User, options.Collection())
_, err := userCollection.InsertOne(ctx, user)
if err != nil {
return nil, err
@@ -51,9 +45,9 @@ func (p *provider) AddUser(ctx context.Context, user *models.User) (*models.User
}
// UpdateUser to update user information in database
-func (p *provider) UpdateUser(ctx context.Context, user *models.User) (*models.User, error) {
+func (p *provider) UpdateUser(ctx context.Context, user *schemas.User) (*schemas.User, error) {
user.UpdatedAt = time.Now().Unix()
- userCollection := p.db.Collection(models.Collections.User, options.Collection())
+ userCollection := p.db.Collection(schemas.Collections.User, options.Collection())
_, err := userCollection.UpdateOne(ctx, bson.M{"_id": bson.M{"$eq": user.ID}}, bson.M{"$set": user}, options.MergeUpdateOptions())
if err != nil {
return nil, err
@@ -62,13 +56,13 @@ func (p *provider) UpdateUser(ctx context.Context, user *models.User) (*models.U
}
// DeleteUser to delete user information from database
-func (p *provider) DeleteUser(ctx context.Context, user *models.User) error {
- userCollection := p.db.Collection(models.Collections.User, options.Collection())
+func (p *provider) DeleteUser(ctx context.Context, user *schemas.User) error {
+ userCollection := p.db.Collection(schemas.Collections.User, options.Collection())
_, err := userCollection.DeleteOne(ctx, bson.M{"_id": user.ID}, options.Delete())
if err != nil {
return err
}
- sessionCollection := p.db.Collection(models.Collections.Session, options.Collection())
+ sessionCollection := p.db.Collection(schemas.Collections.Session, options.Collection())
_, err = sessionCollection.DeleteMany(ctx, bson.M{"user_id": user.ID}, options.Delete())
if err != nil {
return err
@@ -77,42 +71,39 @@ func (p *provider) DeleteUser(ctx context.Context, user *models.User) error {
}
// ListUsers to get list of users from database
-func (p *provider) ListUsers(ctx context.Context, pagination *model.Pagination) (*model.Users, error) {
- var users []*model.User
+func (p *provider) ListUsers(ctx context.Context, pagination *model.Pagination) ([]*schemas.User, *model.Pagination, error) {
+ var users []*schemas.User
opts := options.Find()
opts.SetLimit(pagination.Limit)
opts.SetSkip(pagination.Offset)
opts.SetSort(bson.M{"created_at": -1})
paginationClone := pagination
- userCollection := p.db.Collection(models.Collections.User, options.Collection())
+ userCollection := p.db.Collection(schemas.Collections.User, options.Collection())
count, err := userCollection.CountDocuments(ctx, bson.M{}, options.Count())
if err != nil {
- return nil, err
+ return nil, nil, err
}
paginationClone.Total = count
cursor, err := userCollection.Find(ctx, bson.M{}, opts)
if err != nil {
- return nil, err
+ return nil, nil, err
}
defer cursor.Close(ctx)
for cursor.Next(ctx) {
- var user *models.User
+ var user *schemas.User
err := cursor.Decode(&user)
if err != nil {
- return nil, err
+ return nil, nil, err
}
- users = append(users, user.AsAPIUser())
+ users = append(users, user)
}
- return &model.Users{
- Pagination: paginationClone,
- Users: users,
- }, nil
+ return users, paginationClone, nil
}
// GetUserByEmail to get user information from database using email address
-func (p *provider) GetUserByEmail(ctx context.Context, email string) (*models.User, error) {
- var user *models.User
- userCollection := p.db.Collection(models.Collections.User, options.Collection())
+func (p *provider) GetUserByEmail(ctx context.Context, email string) (*schemas.User, error) {
+ var user *schemas.User
+ userCollection := p.db.Collection(schemas.Collections.User, options.Collection())
err := userCollection.FindOne(ctx, bson.M{"email": email}).Decode(&user)
if err != nil {
return nil, err
@@ -121,9 +112,9 @@ func (p *provider) GetUserByEmail(ctx context.Context, email string) (*models.Us
}
// GetUserByID to get user information from database using user ID
-func (p *provider) GetUserByID(ctx context.Context, id string) (*models.User, error) {
- var user *models.User
- userCollection := p.db.Collection(models.Collections.User, options.Collection())
+func (p *provider) GetUserByID(ctx context.Context, id string) (*schemas.User, error) {
+ var user *schemas.User
+ userCollection := p.db.Collection(schemas.Collections.User, options.Collection())
err := userCollection.FindOne(ctx, bson.M{"_id": id}).Decode(&user)
if err != nil {
return nil, err
@@ -136,7 +127,7 @@ func (p *provider) GetUserByID(ctx context.Context, id string) (*models.User, er
func (p *provider) UpdateUsers(ctx context.Context, data map[string]interface{}, ids []string) error {
// set updated_at time for all users
data["updated_at"] = time.Now().Unix()
- userCollection := p.db.Collection(models.Collections.User, options.Collection())
+ userCollection := p.db.Collection(schemas.Collections.User, options.Collection())
var res *mongo.UpdateResult
var err error
if len(ids) > 0 {
@@ -147,15 +138,15 @@ func (p *provider) UpdateUsers(ctx context.Context, data map[string]interface{},
if err != nil {
return err
} else {
- log.Info("Updated users: ", res.ModifiedCount)
+ p.dependencies.Log.Info().Int64("modified_count", res.ModifiedCount).Msg("users updated")
}
return nil
}
// GetUserByPhoneNumber to get user information from database using phone number
-func (p *provider) GetUserByPhoneNumber(ctx context.Context, phoneNumber string) (*models.User, error) {
- var user *models.User
- userCollection := p.db.Collection(models.Collections.User, options.Collection())
+func (p *provider) GetUserByPhoneNumber(ctx context.Context, phoneNumber string) (*schemas.User, error) {
+ var user *schemas.User
+ userCollection := p.db.Collection(schemas.Collections.User, options.Collection())
err := userCollection.FindOne(ctx, bson.M{"phone_number": phoneNumber}).Decode(&user)
if err != nil {
return nil, err
diff --git a/server/db/providers/mongodb/verification_requests.go b/internal/storage/db/mongodb/verification_requests.go
similarity index 63%
rename from server/db/providers/mongodb/verification_requests.go
rename to internal/storage/db/mongodb/verification_requests.go
index a4088f1eb..49020dad3 100644
--- a/server/db/providers/mongodb/verification_requests.go
+++ b/internal/storage/db/mongodb/verification_requests.go
@@ -4,22 +4,23 @@ import (
"context"
"time"
- "github.com/authorizerdev/authorizer/server/db/models"
- "github.com/authorizerdev/authorizer/server/graph/model"
"github.com/google/uuid"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo/options"
+
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
// AddVerification to save verification request in database
-func (p *provider) AddVerificationRequest(ctx context.Context, verificationRequest *models.VerificationRequest) (*models.VerificationRequest, error) {
+func (p *provider) AddVerificationRequest(ctx context.Context, verificationRequest *schemas.VerificationRequest) (*schemas.VerificationRequest, error) {
if verificationRequest.ID == "" {
verificationRequest.ID = uuid.New().String()
verificationRequest.CreatedAt = time.Now().Unix()
verificationRequest.UpdatedAt = time.Now().Unix()
verificationRequest.Key = verificationRequest.ID
- verificationRequestCollection := p.db.Collection(models.Collections.VerificationRequest, options.Collection())
+ verificationRequestCollection := p.db.Collection(schemas.Collections.VerificationRequest, options.Collection())
_, err := verificationRequestCollection.InsertOne(ctx, verificationRequest)
if err != nil {
return nil, err
@@ -30,10 +31,10 @@ func (p *provider) AddVerificationRequest(ctx context.Context, verificationReque
}
// GetVerificationRequestByToken to get verification request from database using token
-func (p *provider) GetVerificationRequestByToken(ctx context.Context, token string) (*models.VerificationRequest, error) {
- var verificationRequest *models.VerificationRequest
+func (p *provider) GetVerificationRequestByToken(ctx context.Context, token string) (*schemas.VerificationRequest, error) {
+ var verificationRequest *schemas.VerificationRequest
- verificationRequestCollection := p.db.Collection(models.Collections.VerificationRequest, options.Collection())
+ verificationRequestCollection := p.db.Collection(schemas.Collections.VerificationRequest, options.Collection())
err := verificationRequestCollection.FindOne(ctx, bson.M{"token": token}).Decode(&verificationRequest)
if err != nil {
return nil, err
@@ -43,10 +44,10 @@ func (p *provider) GetVerificationRequestByToken(ctx context.Context, token stri
}
// 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
+func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email string, identifier string) (*schemas.VerificationRequest, error) {
+ var verificationRequest *schemas.VerificationRequest
- verificationRequestCollection := p.db.Collection(models.Collections.VerificationRequest, options.Collection())
+ verificationRequestCollection := p.db.Collection(schemas.Collections.VerificationRequest, options.Collection())
err := verificationRequestCollection.FindOne(ctx, bson.M{"email": email, "identifier": identifier}).Decode(&verificationRequest)
if err != nil {
return nil, err
@@ -56,44 +57,43 @@ func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email stri
}
// ListVerificationRequests to get list of verification requests from database
-func (p *provider) ListVerificationRequests(ctx context.Context, pagination *model.Pagination) (*model.VerificationRequests, error) {
- var verificationRequests []*model.VerificationRequest
-
+func (p *provider) ListVerificationRequests(ctx context.Context, pagination *model.Pagination) ([]*schemas.VerificationRequest, *model.Pagination, error) {
+ var verificationRequests []*schemas.VerificationRequest
opts := options.Find()
opts.SetLimit(pagination.Limit)
opts.SetSkip(pagination.Offset)
opts.SetSort(bson.M{"created_at": -1})
- verificationRequestCollection := p.db.Collection(models.Collections.VerificationRequest, options.Collection())
+ verificationRequestCollection := p.db.Collection(schemas.Collections.VerificationRequest, options.Collection())
verificationRequestCollectionCount, err := verificationRequestCollection.CountDocuments(ctx, bson.M{})
+ if err != nil {
+ return nil, nil, err
+ }
paginationClone := pagination
paginationClone.Total = verificationRequestCollectionCount
cursor, err := verificationRequestCollection.Find(ctx, bson.M{}, opts)
if err != nil {
- return nil, err
+ return nil, nil, err
}
defer cursor.Close(ctx)
for cursor.Next(ctx) {
- var verificationRequest *models.VerificationRequest
+ var verificationRequest *schemas.VerificationRequest
err := cursor.Decode(&verificationRequest)
if err != nil {
- return nil, err
+ return nil, nil, err
}
- verificationRequests = append(verificationRequests, verificationRequest.AsAPIVerificationRequest())
+ verificationRequests = append(verificationRequests, verificationRequest)
}
- return &model.VerificationRequests{
- VerificationRequests: verificationRequests,
- Pagination: paginationClone,
- }, nil
+ return verificationRequests, paginationClone, nil
}
// DeleteVerificationRequest to delete verification request from database
-func (p *provider) DeleteVerificationRequest(ctx context.Context, verificationRequest *models.VerificationRequest) error {
- verificationRequestCollection := p.db.Collection(models.Collections.VerificationRequest, options.Collection())
+func (p *provider) DeleteVerificationRequest(ctx context.Context, verificationRequest *schemas.VerificationRequest) error {
+ verificationRequestCollection := p.db.Collection(schemas.Collections.VerificationRequest, options.Collection())
_, err := verificationRequestCollection.DeleteOne(ctx, bson.M{"_id": verificationRequest.ID}, options.Delete())
if err != nil {
return err
diff --git a/server/db/providers/mongodb/webhook.go b/internal/storage/db/mongodb/webhook.go
similarity index 58%
rename from server/db/providers/mongodb/webhook.go
rename to internal/storage/db/mongodb/webhook.go
index ef6b3820b..cf606ae90 100644
--- a/server/db/providers/mongodb/webhook.go
+++ b/internal/storage/db/mongodb/webhook.go
@@ -6,15 +6,16 @@ import (
"strings"
"time"
- "github.com/authorizerdev/authorizer/server/db/models"
- "github.com/authorizerdev/authorizer/server/graph/model"
"github.com/google/uuid"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo/options"
+
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
// AddWebhook to add webhook
-func (p *provider) AddWebhook(ctx context.Context, webhook *models.Webhook) (*model.Webhook, error) {
+func (p *provider) AddWebhook(ctx context.Context, webhook *schemas.Webhook) (*schemas.Webhook, error) {
if webhook.ID == "" {
webhook.ID = uuid.New().String()
}
@@ -23,77 +24,74 @@ func (p *provider) AddWebhook(ctx context.Context, webhook *models.Webhook) (*mo
webhook.UpdatedAt = time.Now().Unix()
// Add timestamp to make event name unique for legacy version
webhook.EventName = fmt.Sprintf("%s-%d", webhook.EventName, time.Now().Unix())
- webhookCollection := p.db.Collection(models.Collections.Webhook, options.Collection())
+ webhookCollection := p.db.Collection(schemas.Collections.Webhook, options.Collection())
_, err := webhookCollection.InsertOne(ctx, webhook)
if err != nil {
return nil, err
}
- return webhook.AsAPIWebhook(), nil
+ return webhook, nil
}
// UpdateWebhook to update webhook
-func (p *provider) UpdateWebhook(ctx context.Context, webhook *models.Webhook) (*model.Webhook, error) {
+func (p *provider) UpdateWebhook(ctx context.Context, webhook *schemas.Webhook) (*schemas.Webhook, error) {
webhook.UpdatedAt = time.Now().Unix()
// Event is changed
if !strings.Contains(webhook.EventName, "-") {
webhook.EventName = fmt.Sprintf("%s-%d", webhook.EventName, time.Now().Unix())
}
- webhookCollection := p.db.Collection(models.Collections.Webhook, options.Collection())
+ webhookCollection := p.db.Collection(schemas.Collections.Webhook, options.Collection())
_, err := webhookCollection.UpdateOne(ctx, bson.M{"_id": bson.M{"$eq": webhook.ID}}, bson.M{"$set": webhook}, options.MergeUpdateOptions())
if err != nil {
return nil, err
}
- return webhook.AsAPIWebhook(), nil
+ return webhook, nil
}
// ListWebhooks to list webhook
-func (p *provider) ListWebhook(ctx context.Context, pagination *model.Pagination) (*model.Webhooks, error) {
- webhooks := []*model.Webhook{}
+func (p *provider) ListWebhook(ctx context.Context, pagination *model.Pagination) ([]*schemas.Webhook, *model.Pagination, error) {
+ webhooks := []*schemas.Webhook{}
opts := options.Find()
opts.SetLimit(pagination.Limit)
opts.SetSkip(pagination.Offset)
opts.SetSort(bson.M{"created_at": -1})
paginationClone := pagination
- webhookCollection := p.db.Collection(models.Collections.Webhook, options.Collection())
+ webhookCollection := p.db.Collection(schemas.Collections.Webhook, options.Collection())
count, err := webhookCollection.CountDocuments(ctx, bson.M{}, options.Count())
if err != nil {
- return nil, err
+ return nil, nil, err
}
paginationClone.Total = count
cursor, err := webhookCollection.Find(ctx, bson.M{}, opts)
if err != nil {
- return nil, err
+ return nil, nil, err
}
defer cursor.Close(ctx)
for cursor.Next(ctx) {
- var webhook *models.Webhook
+ var webhook *schemas.Webhook
err := cursor.Decode(&webhook)
if err != nil {
- return nil, err
+ return nil, nil, err
}
- webhooks = append(webhooks, webhook.AsAPIWebhook())
+ webhooks = append(webhooks, webhook)
}
- return &model.Webhooks{
- Pagination: paginationClone,
- Webhooks: webhooks,
- }, nil
+ return webhooks, paginationClone, nil
}
// GetWebhookByID to get webhook by id
-func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*model.Webhook, error) {
- var webhook *models.Webhook
- webhookCollection := p.db.Collection(models.Collections.Webhook, options.Collection())
+func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*schemas.Webhook, error) {
+ var webhook *schemas.Webhook
+ webhookCollection := p.db.Collection(schemas.Collections.Webhook, options.Collection())
err := webhookCollection.FindOne(ctx, bson.M{"_id": webhookID}).Decode(&webhook)
if err != nil {
return nil, err
}
- return webhook.AsAPIWebhook(), nil
+ return webhook, nil
}
// GetWebhookByEventName to get webhook by event_name
-func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string) ([]*model.Webhook, error) {
- webhooks := []*model.Webhook{}
- webhookCollection := p.db.Collection(models.Collections.Webhook, options.Collection())
+func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string) ([]*schemas.Webhook, error) {
+ webhooks := []*schemas.Webhook{}
+ webhookCollection := p.db.Collection(schemas.Collections.Webhook, options.Collection())
opts := options.Find()
opts.SetSort(bson.M{"created_at": -1})
cursor, err := webhookCollection.Find(ctx, bson.M{"event_name": bson.M{
@@ -104,25 +102,25 @@ func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string)
}
defer cursor.Close(ctx)
for cursor.Next(ctx) {
- var webhook *models.Webhook
+ var webhook *schemas.Webhook
err := cursor.Decode(&webhook)
if err != nil {
return nil, err
}
- webhooks = append(webhooks, webhook.AsAPIWebhook())
+ webhooks = append(webhooks, webhook)
}
return webhooks, nil
}
// DeleteWebhook to delete webhook
-func (p *provider) DeleteWebhook(ctx context.Context, webhook *model.Webhook) error {
- webhookCollection := p.db.Collection(models.Collections.Webhook, options.Collection())
- _, err := webhookCollection.DeleteOne(nil, bson.M{"_id": webhook.ID}, options.Delete())
+func (p *provider) DeleteWebhook(ctx context.Context, webhook *schemas.Webhook) error {
+ webhookCollection := p.db.Collection(schemas.Collections.Webhook, options.Collection())
+ _, err := webhookCollection.DeleteOne(ctx, bson.M{"_id": webhook.ID}, options.Delete())
if err != nil {
return err
}
- webhookLogCollection := p.db.Collection(models.Collections.WebhookLog, options.Collection())
- _, err = webhookLogCollection.DeleteMany(nil, bson.M{"webhook_id": webhook.ID}, options.Delete())
+ webhookLogCollection := p.db.Collection(schemas.Collections.WebhookLog, options.Collection())
+ _, err = webhookLogCollection.DeleteMany(ctx, bson.M{"webhook_id": webhook.ID}, options.Delete())
if err != nil {
return err
}
diff --git a/server/db/providers/mongodb/webhook_log.go b/internal/storage/db/mongodb/webhook_log.go
similarity index 61%
rename from server/db/providers/mongodb/webhook_log.go
rename to internal/storage/db/mongodb/webhook_log.go
index 0c464d8e3..49570f88a 100644
--- a/server/db/providers/mongodb/webhook_log.go
+++ b/internal/storage/db/mongodb/webhook_log.go
@@ -4,15 +4,15 @@ import (
"context"
"time"
- "github.com/authorizerdev/authorizer/server/db/models"
- "github.com/authorizerdev/authorizer/server/graph/model"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
"github.com/google/uuid"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo/options"
)
// AddWebhookLog to add webhook log
-func (p *provider) AddWebhookLog(ctx context.Context, webhookLog *models.WebhookLog) (*model.WebhookLog, error) {
+func (p *provider) AddWebhookLog(ctx context.Context, webhookLog *schemas.WebhookLog) (*schemas.WebhookLog, error) {
if webhookLog.ID == "" {
webhookLog.ID = uuid.New().String()
}
@@ -21,17 +21,17 @@ func (p *provider) AddWebhookLog(ctx context.Context, webhookLog *models.Webhook
webhookLog.CreatedAt = time.Now().Unix()
webhookLog.UpdatedAt = time.Now().Unix()
- webhookLogCollection := p.db.Collection(models.Collections.WebhookLog, options.Collection())
+ webhookLogCollection := p.db.Collection(schemas.Collections.WebhookLog, options.Collection())
_, err := webhookLogCollection.InsertOne(ctx, webhookLog)
if err != nil {
return nil, err
}
- return webhookLog.AsAPIWebhookLog(), nil
+ return webhookLog, nil
}
// ListWebhookLogs to list webhook logs
-func (p *provider) ListWebhookLogs(ctx context.Context, pagination *model.Pagination, webhookID string) (*model.WebhookLogs, error) {
- webhookLogs := []*model.WebhookLog{}
+func (p *provider) ListWebhookLogs(ctx context.Context, pagination *model.Pagination, webhookID string) ([]*schemas.WebhookLog, *model.Pagination, error) {
+ webhookLogs := []*schemas.WebhookLog{}
opts := options.Find()
opts.SetLimit(pagination.Limit)
opts.SetSkip(pagination.Offset)
@@ -44,31 +44,28 @@ func (p *provider) ListWebhookLogs(ctx context.Context, pagination *model.Pagina
query = bson.M{"webhook_id": webhookID}
}
- webhookLogCollection := p.db.Collection(models.Collections.WebhookLog, options.Collection())
+ webhookLogCollection := p.db.Collection(schemas.Collections.WebhookLog, options.Collection())
count, err := webhookLogCollection.CountDocuments(ctx, query, options.Count())
if err != nil {
- return nil, err
+ return nil, nil, err
}
paginationClone.Total = count
cursor, err := webhookLogCollection.Find(ctx, query, opts)
if err != nil {
- return nil, err
+ return nil, nil, err
}
defer cursor.Close(ctx)
for cursor.Next(ctx) {
- var webhookLog *models.WebhookLog
+ var webhookLog *schemas.WebhookLog
err := cursor.Decode(&webhookLog)
if err != nil {
- return nil, err
+ return nil, nil, err
}
- webhookLogs = append(webhookLogs, webhookLog.AsAPIWebhookLog())
+ webhookLogs = append(webhookLogs, webhookLog)
}
- return &model.WebhookLogs{
- Pagination: paginationClone,
- WebhookLogs: webhookLogs,
- }, nil
+ return webhookLogs, paginationClone, nil
}
diff --git a/server/db/providers/provider_template/authenticator.go b/internal/storage/db/provider_template/authenticator.go
similarity index 69%
rename from server/db/providers/provider_template/authenticator.go
rename to internal/storage/db/provider_template/authenticator.go
index 508cd5e60..5bc5702e0 100644
--- a/server/db/providers/provider_template/authenticator.go
+++ b/internal/storage/db/provider_template/authenticator.go
@@ -6,10 +6,10 @@ import (
"github.com/google/uuid"
- "github.com/authorizerdev/authorizer/server/db/models"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
-func (p *provider) AddAuthenticator(ctx context.Context, authenticators *models.Authenticator) (*models.Authenticator, error) {
+func (p *provider) AddAuthenticator(ctx context.Context, authenticators *schemas.Authenticator) (*schemas.Authenticator, error) {
exists, _ := p.GetAuthenticatorDetailsByUserId(ctx, authenticators.UserID, authenticators.Method)
if exists != nil {
return authenticators, nil
@@ -23,12 +23,12 @@ func (p *provider) AddAuthenticator(ctx context.Context, authenticators *models.
return authenticators, nil
}
-func (p *provider) UpdateAuthenticator(ctx context.Context, authenticators *models.Authenticator) (*models.Authenticator, error) {
+func (p *provider) UpdateAuthenticator(ctx context.Context, authenticators *schemas.Authenticator) (*schemas.Authenticator, error) {
authenticators.UpdatedAt = time.Now().Unix()
return authenticators, nil
}
-func (p *provider) GetAuthenticatorDetailsByUserId(ctx context.Context, userId string, authenticatorType string) (*models.Authenticator, error) {
- var authenticators *models.Authenticator
+func (p *provider) GetAuthenticatorDetailsByUserId(ctx context.Context, userId string, authenticatorType string) (*schemas.Authenticator, error) {
+ var authenticators *schemas.Authenticator
return authenticators, nil
}
diff --git a/server/db/providers/provider_template/email_template.go b/internal/storage/db/provider_template/email_template.go
similarity index 65%
rename from server/db/providers/provider_template/email_template.go
rename to internal/storage/db/provider_template/email_template.go
index a30647995..8e1faf4a2 100644
--- a/server/db/providers/provider_template/email_template.go
+++ b/internal/storage/db/provider_template/email_template.go
@@ -4,13 +4,14 @@ import (
"context"
"time"
- "github.com/authorizerdev/authorizer/server/db/models"
- "github.com/authorizerdev/authorizer/server/graph/model"
"github.com/google/uuid"
+
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
// AddEmailTemplate to add EmailTemplate
-func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate *models.EmailTemplate) (*model.EmailTemplate, error) {
+func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate *schemas.EmailTemplate) (*schemas.EmailTemplate, error) {
if emailTemplate.ID == "" {
emailTemplate.ID = uuid.New().String()
}
@@ -18,31 +19,31 @@ func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate *models.E
emailTemplate.Key = emailTemplate.ID
emailTemplate.CreatedAt = time.Now().Unix()
emailTemplate.UpdatedAt = time.Now().Unix()
- return emailTemplate.AsAPIEmailTemplate(), nil
+ return emailTemplate, nil
}
// UpdateEmailTemplate to update EmailTemplate
-func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate *models.EmailTemplate) (*model.EmailTemplate, error) {
+func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate *schemas.EmailTemplate) (*schemas.EmailTemplate, error) {
emailTemplate.UpdatedAt = time.Now().Unix()
- return emailTemplate.AsAPIEmailTemplate(), nil
+ return emailTemplate, nil
}
// ListEmailTemplates to list EmailTemplate
-func (p *provider) ListEmailTemplate(ctx context.Context, pagination *model.Pagination) (*model.EmailTemplates, error) {
- return nil, nil
+func (p *provider) ListEmailTemplate(ctx context.Context, pagination *model.Pagination) ([]*schemas.EmailTemplate, *model.Pagination, error) {
+ return nil, nil, nil
}
// GetEmailTemplateByID to get EmailTemplate by id
-func (p *provider) GetEmailTemplateByID(ctx context.Context, emailTemplateID string) (*model.EmailTemplate, error) {
+func (p *provider) GetEmailTemplateByID(ctx context.Context, emailTemplateID string) (*schemas.EmailTemplate, error) {
return nil, nil
}
// GetEmailTemplateByEventName to get EmailTemplate by event_name
-func (p *provider) GetEmailTemplateByEventName(ctx context.Context, eventName string) (*model.EmailTemplate, error) {
+func (p *provider) GetEmailTemplateByEventName(ctx context.Context, eventName string) (*schemas.EmailTemplate, error) {
return nil, nil
}
// DeleteEmailTemplate to delete EmailTemplate
-func (p *provider) DeleteEmailTemplate(ctx context.Context, emailTemplate *model.EmailTemplate) error {
+func (p *provider) DeleteEmailTemplate(ctx context.Context, emailTemplate *schemas.EmailTemplate) error {
return nil
}
diff --git a/server/db/providers/provider_template/env.go b/internal/storage/db/provider_template/env.go
similarity index 58%
rename from server/db/providers/provider_template/env.go
rename to internal/storage/db/provider_template/env.go
index 823d4e305..1f4b05029 100644
--- a/server/db/providers/provider_template/env.go
+++ b/internal/storage/db/provider_template/env.go
@@ -4,12 +4,13 @@ import (
"context"
"time"
- "github.com/authorizerdev/authorizer/server/db/models"
"github.com/google/uuid"
+
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
// AddEnv to save environment information in database
-func (p *provider) AddEnv(ctx context.Context, env *models.Env) (*models.Env, error) {
+func (p *provider) AddEnv(ctx context.Context, env *schemas.Env) (*schemas.Env, error) {
if env.ID == "" {
env.ID = uuid.New().String()
}
@@ -20,14 +21,14 @@ func (p *provider) AddEnv(ctx context.Context, env *models.Env) (*models.Env, er
}
// UpdateEnv to update environment information in database
-func (p *provider) UpdateEnv(ctx context.Context, env *models.Env) (*models.Env, error) {
+func (p *provider) UpdateEnv(ctx context.Context, env *schemas.Env) (*schemas.Env, error) {
env.UpdatedAt = time.Now().Unix()
return env, nil
}
// GetEnv to get environment information from database
-func (p *provider) GetEnv(ctx context.Context) (*models.Env, error) {
- var env *models.Env
+func (p *provider) GetEnv(ctx context.Context) (*schemas.Env, error) {
+ var env *schemas.Env
return env, nil
}
diff --git a/server/db/providers/provider_template/otp.go b/internal/storage/db/provider_template/otp.go
similarity index 58%
rename from server/db/providers/provider_template/otp.go
rename to internal/storage/db/provider_template/otp.go
index 07167118f..94e351cbc 100644
--- a/server/db/providers/provider_template/otp.go
+++ b/internal/storage/db/provider_template/otp.go
@@ -3,25 +3,25 @@ package provider_template
import (
"context"
- "github.com/authorizerdev/authorizer/server/db/models"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
// UpsertOTP to add or update otp
-func (p *provider) UpsertOTP(ctx context.Context, otp *models.OTP) (*models.OTP, error) {
+func (p *provider) UpsertOTP(ctx context.Context, otp *schemas.OTP) (*schemas.OTP, error) {
return nil, nil
}
// GetOTPByEmail to get otp for a given email address
-func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*models.OTP, error) {
+func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*schemas.OTP, error) {
return nil, nil
}
// GetOTPByPhoneNumber to get otp for a given phone number
-func (p *provider) GetOTPByPhoneNumber(ctx context.Context, phoneNumber string) (*models.OTP, error) {
+func (p *provider) GetOTPByPhoneNumber(ctx context.Context, phoneNumber string) (*schemas.OTP, error) {
return nil, nil
}
// DeleteOTP to delete otp
-func (p *provider) DeleteOTP(ctx context.Context, otp *models.OTP) error {
+func (p *provider) DeleteOTP(ctx context.Context, otp *schemas.OTP) error {
return nil
}
diff --git a/internal/storage/db/provider_template/provider.go b/internal/storage/db/provider_template/provider.go
new file mode 100644
index 000000000..905db07a0
--- /dev/null
+++ b/internal/storage/db/provider_template/provider.go
@@ -0,0 +1,35 @@
+package provider_template
+
+import (
+ "github.com/rs/zerolog"
+ "gorm.io/gorm"
+
+ "github.com/authorizerdev/authorizer/internal/config"
+)
+
+// Dependencies struct the TODO(replace with new db name) data store provider
+type Dependencies struct {
+ Log *zerolog.Logger
+}
+
+// TODO change following provider to new db provider
+type provider struct {
+ config *config.Config
+ dependencies *Dependencies
+ db *gorm.DB
+}
+
+// NewProvider returns a new SQL provider
+// TODO change following provider to new db provider
+func NewProvider(
+ config *config.Config,
+ deps *Dependencies,
+) (*provider, error) {
+ var sqlDB *gorm.DB
+
+ return &provider{
+ config: config,
+ dependencies: deps,
+ db: sqlDB,
+ }, nil
+}
diff --git a/server/db/providers/provider_template/session.go b/internal/storage/db/provider_template/session.go
similarity index 74%
rename from server/db/providers/provider_template/session.go
rename to internal/storage/db/provider_template/session.go
index e398e8c51..ebbd8c79d 100644
--- a/server/db/providers/provider_template/session.go
+++ b/internal/storage/db/provider_template/session.go
@@ -4,12 +4,13 @@ import (
"context"
"time"
- "github.com/authorizerdev/authorizer/server/db/models"
"github.com/google/uuid"
+
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
// AddSession to save session information in database
-func (p *provider) AddSession(ctx context.Context, session *models.Session) error {
+func (p *provider) AddSession(ctx context.Context, session *schemas.Session) error {
if session.ID == "" {
session.ID = uuid.New().String()
}
diff --git a/server/db/providers/provider_template/user.go b/internal/storage/db/provider_template/user.go
similarity index 67%
rename from server/db/providers/provider_template/user.go
rename to internal/storage/db/provider_template/user.go
index b84aa6316..e5e28c54d 100644
--- a/server/db/providers/provider_template/user.go
+++ b/internal/storage/db/provider_template/user.go
@@ -6,25 +6,20 @@ import (
"strings"
"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/authorizerdev/authorizer/server/refs"
"github.com/google/uuid"
+
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/refs"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
// AddUser to save user information in database
-func (p *provider) AddUser(ctx context.Context, user *models.User) (*models.User, error) {
+func (p *provider) AddUser(ctx context.Context, user *schemas.User) (*schemas.User, error) {
if user.ID == "" {
user.ID = uuid.New().String()
}
if user.Roles == "" {
- defaultRoles, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyDefaultRoles)
- if err != nil {
- return nil, err
- }
- user.Roles = defaultRoles
+ user.Roles = strings.Join(p.config.DefaultRoles, ",")
}
if user.PhoneNumber != nil && strings.TrimSpace(refs.StringValue(user.PhoneNumber)) != "" {
if u, _ := p.GetUserByPhoneNumber(ctx, refs.StringValue(user.PhoneNumber)); u != nil && u.ID != user.ID {
@@ -41,30 +36,30 @@ func (p *provider) AddUser(ctx context.Context, user *models.User) (*models.User
}
// UpdateUser to update user information in database
-func (p *provider) UpdateUser(ctx context.Context, user *models.User) (*models.User, error) {
+func (p *provider) UpdateUser(ctx context.Context, user *schemas.User) (*schemas.User, error) {
user.UpdatedAt = time.Now().Unix()
return user, nil
}
// DeleteUser to delete user information from database
-func (p *provider) DeleteUser(ctx context.Context, user *models.User) error {
+func (p *provider) DeleteUser(ctx context.Context, user *schemas.User) error {
return nil
}
// ListUsers to get list of users from database
-func (p *provider) ListUsers(ctx context.Context, pagination *model.Pagination) (*model.Users, error) {
- return nil, nil
+func (p *provider) ListUsers(ctx context.Context, pagination *model.Pagination) ([]*schemas.User, *model.Pagination, error) {
+ return nil, nil, nil
}
// GetUserByEmail to get user information from database using email address
-func (p *provider) GetUserByEmail(ctx context.Context, email string) (*models.User, error) {
- var user *models.User
+func (p *provider) GetUserByEmail(ctx context.Context, email string) (*schemas.User, error) {
+ var user *schemas.User
return user, nil
}
// GetUserByID to get user information from database using user ID
-func (p *provider) GetUserByID(ctx context.Context, id string) (*models.User, error) {
- var user *models.User
+func (p *provider) GetUserByID(ctx context.Context, id string) (*schemas.User, error) {
+ var user *schemas.User
return user, nil
}
@@ -77,7 +72,7 @@ func (p *provider) UpdateUsers(ctx context.Context, data map[string]interface{},
}
// GetUserByPhoneNumber to get user information from database using phone number
-func (p *provider) GetUserByPhoneNumber(ctx context.Context, phoneNumber string) (*models.User, error) {
- var user *models.User
+func (p *provider) GetUserByPhoneNumber(ctx context.Context, phoneNumber string) (*schemas.User, error) {
+ var user *schemas.User
return user, nil
}
diff --git a/server/db/providers/provider_template/verification_requests.go b/internal/storage/db/provider_template/verification_requests.go
similarity index 63%
rename from server/db/providers/provider_template/verification_requests.go
rename to internal/storage/db/provider_template/verification_requests.go
index c3a7f18a5..e7a7d6d52 100644
--- a/server/db/providers/provider_template/verification_requests.go
+++ b/internal/storage/db/provider_template/verification_requests.go
@@ -4,13 +4,14 @@ import (
"context"
"time"
- "github.com/authorizerdev/authorizer/server/db/models"
- "github.com/authorizerdev/authorizer/server/graph/model"
"github.com/google/uuid"
+
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
// AddVerification to save verification request in database
-func (p *provider) AddVerificationRequest(ctx context.Context, verificationRequest *models.VerificationRequest) (*models.VerificationRequest, error) {
+func (p *provider) AddVerificationRequest(ctx context.Context, verificationRequest *schemas.VerificationRequest) (*schemas.VerificationRequest, error) {
if verificationRequest.ID == "" {
verificationRequest.ID = uuid.New().String()
}
@@ -22,25 +23,25 @@ func (p *provider) AddVerificationRequest(ctx context.Context, verificationReque
}
// GetVerificationRequestByToken to get verification request from database using token
-func (p *provider) GetVerificationRequestByToken(ctx context.Context, token string) (*models.VerificationRequest, error) {
- var verificationRequest *models.VerificationRequest
+func (p *provider) GetVerificationRequestByToken(ctx context.Context, token string) (*schemas.VerificationRequest, error) {
+ var verificationRequest *schemas.VerificationRequest
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
+func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email string, identifier string) (*schemas.VerificationRequest, error) {
+ var verificationRequest *schemas.VerificationRequest
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) {
- return nil, nil
+func (p *provider) ListVerificationRequests(ctx context.Context, pagination *model.Pagination) ([]*schemas.VerificationRequest, *model.Pagination, error) {
+ return nil, nil, nil
}
// DeleteVerificationRequest to delete verification request from database
-func (p *provider) DeleteVerificationRequest(ctx context.Context, verificationRequest *models.VerificationRequest) error {
+func (p *provider) DeleteVerificationRequest(ctx context.Context, verificationRequest *schemas.VerificationRequest) error {
return nil
}
diff --git a/server/db/providers/provider_template/webhook.go b/internal/storage/db/provider_template/webhook.go
similarity index 63%
rename from server/db/providers/provider_template/webhook.go
rename to internal/storage/db/provider_template/webhook.go
index cf0edbe00..fd945f87b 100644
--- a/server/db/providers/provider_template/webhook.go
+++ b/internal/storage/db/provider_template/webhook.go
@@ -6,13 +6,14 @@ import (
"strings"
"time"
- "github.com/authorizerdev/authorizer/server/db/models"
- "github.com/authorizerdev/authorizer/server/graph/model"
"github.com/google/uuid"
+
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
// AddWebhook to add webhook
-func (p *provider) AddWebhook(ctx context.Context, webhook *models.Webhook) (*model.Webhook, error) {
+func (p *provider) AddWebhook(ctx context.Context, webhook *schemas.Webhook) (*schemas.Webhook, error) {
if webhook.ID == "" {
webhook.ID = uuid.New().String()
}
@@ -21,36 +22,36 @@ func (p *provider) AddWebhook(ctx context.Context, webhook *models.Webhook) (*mo
webhook.UpdatedAt = time.Now().Unix()
// Add timestamp to make event name unique for legacy version
webhook.EventName = fmt.Sprintf("%s-%d", webhook.EventName, time.Now().Unix())
- return webhook.AsAPIWebhook(), nil
+ return webhook, nil
}
// UpdateWebhook to update webhook
-func (p *provider) UpdateWebhook(ctx context.Context, webhook *models.Webhook) (*model.Webhook, error) {
+func (p *provider) UpdateWebhook(ctx context.Context, webhook *schemas.Webhook) (*schemas.Webhook, error) {
webhook.UpdatedAt = time.Now().Unix()
// Event is changed
if !strings.Contains(webhook.EventName, "-") {
webhook.EventName = fmt.Sprintf("%s-%d", webhook.EventName, time.Now().Unix())
}
- return webhook.AsAPIWebhook(), nil
+ return webhook, nil
}
// ListWebhooks to list webhook
-func (p *provider) ListWebhook(ctx context.Context, pagination *model.Pagination) (*model.Webhooks, error) {
- return nil, nil
+func (p *provider) ListWebhook(ctx context.Context, pagination *model.Pagination) ([]*schemas.Webhook, *model.Pagination, error) {
+ return nil, nil, nil
}
// GetWebhookByID to get webhook by id
-func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*model.Webhook, error) {
+func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*schemas.Webhook, error) {
return nil, nil
}
// GetWebhookByEventName to get webhook by event_name
-func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string) ([]*model.Webhook, error) {
+func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string) ([]*schemas.Webhook, error) {
return nil, nil
}
// DeleteWebhook to delete webhook
-func (p *provider) DeleteWebhook(ctx context.Context, webhook *model.Webhook) error {
+func (p *provider) DeleteWebhook(ctx context.Context, webhook *schemas.Webhook) error {
// Also delete webhook logs for given webhook id
return nil
}
diff --git a/server/db/providers/provider_template/webhook_log.go b/internal/storage/db/provider_template/webhook_log.go
similarity index 60%
rename from server/db/providers/provider_template/webhook_log.go
rename to internal/storage/db/provider_template/webhook_log.go
index 9ad81d244..e2098cbaf 100644
--- a/server/db/providers/provider_template/webhook_log.go
+++ b/internal/storage/db/provider_template/webhook_log.go
@@ -4,13 +4,14 @@ import (
"context"
"time"
- "github.com/authorizerdev/authorizer/server/db/models"
- "github.com/authorizerdev/authorizer/server/graph/model"
"github.com/google/uuid"
+
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
// AddWebhookLog to add webhook log
-func (p *provider) AddWebhookLog(ctx context.Context, webhookLog *models.WebhookLog) (*model.WebhookLog, error) {
+func (p *provider) AddWebhookLog(ctx context.Context, webhookLog *schemas.WebhookLog) (*schemas.WebhookLog, error) {
if webhookLog.ID == "" {
webhookLog.ID = uuid.New().String()
}
@@ -18,10 +19,10 @@ func (p *provider) AddWebhookLog(ctx context.Context, webhookLog *models.Webhook
webhookLog.Key = webhookLog.ID
webhookLog.CreatedAt = time.Now().Unix()
webhookLog.UpdatedAt = time.Now().Unix()
- return webhookLog.AsAPIWebhookLog(), nil
+ return webhookLog, nil
}
// ListWebhookLogs to list webhook logs
-func (p *provider) ListWebhookLogs(ctx context.Context, pagination *model.Pagination, webhookID string) (*model.WebhookLogs, error) {
- return nil, nil
+func (p *provider) ListWebhookLogs(ctx context.Context, pagination *model.Pagination, webhookID string) ([]*schemas.WebhookLog, *model.Pagination, error) {
+ return nil, nil, nil
}
diff --git a/server/db/providers/sql/authenticator.go b/internal/storage/db/sql/authenticator.go
similarity index 79%
rename from server/db/providers/sql/authenticator.go
rename to internal/storage/db/sql/authenticator.go
index b8cf79717..7792c1ad2 100644
--- a/server/db/providers/sql/authenticator.go
+++ b/internal/storage/db/sql/authenticator.go
@@ -7,10 +7,10 @@ import (
"github.com/google/uuid"
"gorm.io/gorm/clause"
- "github.com/authorizerdev/authorizer/server/db/models"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
-func (p *provider) AddAuthenticator(ctx context.Context, authenticators *models.Authenticator) (*models.Authenticator, error) {
+func (p *provider) AddAuthenticator(ctx context.Context, authenticators *schemas.Authenticator) (*schemas.Authenticator, error) {
exists, _ := p.GetAuthenticatorDetailsByUserId(ctx, authenticators.UserID, authenticators.Method)
if exists != nil {
return authenticators, nil
@@ -33,7 +33,7 @@ func (p *provider) AddAuthenticator(ctx context.Context, authenticators *models.
return authenticators, nil
}
-func (p *provider) UpdateAuthenticator(ctx context.Context, authenticators *models.Authenticator) (*models.Authenticator, error) {
+func (p *provider) UpdateAuthenticator(ctx context.Context, authenticators *schemas.Authenticator) (*schemas.Authenticator, error) {
authenticators.UpdatedAt = time.Now().Unix()
result := p.db.Save(&authenticators)
if result.Error != nil {
@@ -42,8 +42,8 @@ func (p *provider) UpdateAuthenticator(ctx context.Context, authenticators *mode
return authenticators, nil
}
-func (p *provider) GetAuthenticatorDetailsByUserId(ctx context.Context, userId string, authenticatorType string) (*models.Authenticator, error) {
- var authenticators models.Authenticator
+func (p *provider) GetAuthenticatorDetailsByUserId(ctx context.Context, userId string, authenticatorType string) (*schemas.Authenticator, error) {
+ var authenticators schemas.Authenticator
result := p.db.Where("user_id = ?", userId).Where("method = ?", authenticatorType).First(&authenticators)
if result.Error != nil {
return nil, result.Error
diff --git a/server/db/providers/sql/email_template.go b/internal/storage/db/sql/email_template.go
similarity index 59%
rename from server/db/providers/sql/email_template.go
rename to internal/storage/db/sql/email_template.go
index 8928b6f7a..3926107d7 100644
--- a/server/db/providers/sql/email_template.go
+++ b/internal/storage/db/sql/email_template.go
@@ -4,13 +4,14 @@ import (
"context"
"time"
- "github.com/authorizerdev/authorizer/server/db/models"
- "github.com/authorizerdev/authorizer/server/graph/model"
"github.com/google/uuid"
+
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
// AddEmailTemplate to add EmailTemplate
-func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate *models.EmailTemplate) (*model.EmailTemplate, error) {
+func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate *schemas.EmailTemplate) (*schemas.EmailTemplate, error) {
if emailTemplate.ID == "" {
emailTemplate.ID = uuid.New().String()
}
@@ -23,72 +24,65 @@ func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate *models.E
if res.Error != nil {
return nil, res.Error
}
- return emailTemplate.AsAPIEmailTemplate(), nil
+ return emailTemplate, nil
}
// UpdateEmailTemplate to update EmailTemplate
-func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate *models.EmailTemplate) (*model.EmailTemplate, error) {
+func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate *schemas.EmailTemplate) (*schemas.EmailTemplate, error) {
emailTemplate.UpdatedAt = time.Now().Unix()
res := p.db.Save(&emailTemplate)
if res.Error != nil {
return nil, res.Error
}
- return emailTemplate.AsAPIEmailTemplate(), nil
+ return emailTemplate, nil
}
// ListEmailTemplates to list EmailTemplate
-func (p *provider) ListEmailTemplate(ctx context.Context, pagination *model.Pagination) (*model.EmailTemplates, error) {
- var emailTemplates []*models.EmailTemplate
+func (p *provider) ListEmailTemplate(ctx context.Context, pagination *model.Pagination) ([]*schemas.EmailTemplate, *model.Pagination, error) {
+ var emailTemplates []*schemas.EmailTemplate
result := p.db.Limit(int(pagination.Limit)).Offset(int(pagination.Offset)).Order("created_at DESC").Find(&emailTemplates)
if result.Error != nil {
- return nil, result.Error
+ return nil, nil, result.Error
}
var total int64
- totalRes := p.db.Model(&models.EmailTemplate{}).Count(&total)
+ totalRes := p.db.Model(&schemas.EmailTemplate{}).Count(&total)
if totalRes.Error != nil {
- return nil, totalRes.Error
+ return nil, nil, totalRes.Error
}
paginationClone := pagination
paginationClone.Total = total
- responseEmailTemplates := []*model.EmailTemplate{}
- for _, w := range emailTemplates {
- responseEmailTemplates = append(responseEmailTemplates, w.AsAPIEmailTemplate())
- }
- return &model.EmailTemplates{
- Pagination: paginationClone,
- EmailTemplates: responseEmailTemplates,
- }, nil
+ return emailTemplates, paginationClone, nil
}
// GetEmailTemplateByID to get EmailTemplate by id
-func (p *provider) GetEmailTemplateByID(ctx context.Context, emailTemplateID string) (*model.EmailTemplate, error) {
- var emailTemplate *models.EmailTemplate
+func (p *provider) GetEmailTemplateByID(ctx context.Context, emailTemplateID string) (*schemas.EmailTemplate, error) {
+ var emailTemplate *schemas.EmailTemplate
result := p.db.Where("id = ?", emailTemplateID).First(&emailTemplate)
if result.Error != nil {
return nil, result.Error
}
- return emailTemplate.AsAPIEmailTemplate(), nil
+ return emailTemplate, nil
}
// GetEmailTemplateByEventName to get EmailTemplate by event_name
-func (p *provider) GetEmailTemplateByEventName(ctx context.Context, eventName string) (*model.EmailTemplate, error) {
- var emailTemplate *models.EmailTemplate
+func (p *provider) GetEmailTemplateByEventName(ctx context.Context, eventName string) (*schemas.EmailTemplate, error) {
+ var emailTemplate *schemas.EmailTemplate
result := p.db.Where("event_name = ?", eventName).First(&emailTemplate)
if result.Error != nil {
return nil, result.Error
}
- return emailTemplate.AsAPIEmailTemplate(), nil
+ return emailTemplate, nil
}
// DeleteEmailTemplate to delete EmailTemplate
-func (p *provider) DeleteEmailTemplate(ctx context.Context, emailTemplate *model.EmailTemplate) error {
- result := p.db.Delete(&models.EmailTemplate{
+func (p *provider) DeleteEmailTemplate(ctx context.Context, emailTemplate *schemas.EmailTemplate) error {
+ result := p.db.Delete(&schemas.EmailTemplate{
ID: emailTemplate.ID,
})
if result.Error != nil {
diff --git a/server/db/providers/sql/env.go b/internal/storage/db/sql/env.go
similarity index 68%
rename from server/db/providers/sql/env.go
rename to internal/storage/db/sql/env.go
index 11584a050..f13503209 100644
--- a/server/db/providers/sql/env.go
+++ b/internal/storage/db/sql/env.go
@@ -4,12 +4,13 @@ import (
"context"
"time"
- "github.com/authorizerdev/authorizer/server/db/models"
"github.com/google/uuid"
+
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
// AddEnv to save environment information in database
-func (p *provider) AddEnv(ctx context.Context, env *models.Env) (*models.Env, error) {
+func (p *provider) AddEnv(ctx context.Context, env *schemas.Env) (*schemas.Env, error) {
if env.ID == "" {
env.ID = uuid.New().String()
}
@@ -26,7 +27,7 @@ func (p *provider) AddEnv(ctx context.Context, env *models.Env) (*models.Env, er
}
// UpdateEnv to update environment information in database
-func (p *provider) UpdateEnv(ctx context.Context, env *models.Env) (*models.Env, error) {
+func (p *provider) UpdateEnv(ctx context.Context, env *schemas.Env) (*schemas.Env, error) {
env.UpdatedAt = time.Now().Unix()
result := p.db.Save(&env)
if result.Error != nil {
@@ -36,8 +37,8 @@ func (p *provider) UpdateEnv(ctx context.Context, env *models.Env) (*models.Env,
}
// GetEnv to get environment information from database
-func (p *provider) GetEnv(ctx context.Context) (*models.Env, error) {
- var env *models.Env
+func (p *provider) GetEnv(ctx context.Context) (*schemas.Env, error) {
+ var env *schemas.Env
result := p.db.First(&env)
if result.Error != nil {
return env, result.Error
diff --git a/server/db/providers/sql/otp.go b/internal/storage/db/sql/otp.go
similarity index 76%
rename from server/db/providers/sql/otp.go
rename to internal/storage/db/sql/otp.go
index 4bf9b11f3..eed7e0596 100644
--- a/server/db/providers/sql/otp.go
+++ b/internal/storage/db/sql/otp.go
@@ -5,12 +5,13 @@ import (
"errors"
"time"
- "github.com/authorizerdev/authorizer/server/db/models"
"github.com/google/uuid"
+
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
// UpsertOTP to add or update otp
-func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models.OTP, error) {
+func (p *provider) UpsertOTP(ctx context.Context, otpParam *schemas.OTP) (*schemas.OTP, error) {
if otpParam.ID == "" {
otpParam.ID = uuid.New().String()
}
@@ -18,12 +19,12 @@ func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models
if otpParam.Email == "" && otpParam.PhoneNumber == "" {
return nil, errors.New("email or phone_number is required")
}
- uniqueField := models.FieldNameEmail
+ uniqueField := schemas.FieldNameEmail
if otpParam.Email == "" && otpParam.PhoneNumber != "" {
- uniqueField = models.FieldNamePhoneNumber
+ uniqueField = schemas.FieldNamePhoneNumber
}
- var otp *models.OTP
- if uniqueField == models.FieldNameEmail {
+ var otp *schemas.OTP
+ if uniqueField == schemas.FieldNameEmail {
otp, _ = p.GetOTPByEmail(ctx, otpParam.Email)
} else {
otp, _ = p.GetOTPByPhoneNumber(ctx, otpParam.PhoneNumber)
@@ -31,7 +32,7 @@ func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models
shouldCreate := false
if otp == nil {
id := uuid.NewString()
- otp = &models.OTP{
+ otp = &schemas.OTP{
ID: id,
Key: id,
Otp: otpParam.Otp,
@@ -61,8 +62,8 @@ func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models
}
// GetOTPByEmail to get otp for a given email address
-func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*models.OTP, error) {
- var otp models.OTP
+func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*schemas.OTP, error) {
+ var otp schemas.OTP
result := p.db.Where("email = ?", emailAddress).First(&otp)
if result.Error != nil {
return nil, result.Error
@@ -71,8 +72,8 @@ func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*mod
}
// GetOTPByPhoneNumber to get otp for a given phone number
-func (p *provider) GetOTPByPhoneNumber(ctx context.Context, phoneNumber string) (*models.OTP, error) {
- var otp models.OTP
+func (p *provider) GetOTPByPhoneNumber(ctx context.Context, phoneNumber string) (*schemas.OTP, error) {
+ var otp schemas.OTP
result := p.db.Where("phone_number = ?", phoneNumber).First(&otp)
if result.Error != nil {
return nil, result.Error
@@ -81,8 +82,8 @@ func (p *provider) GetOTPByPhoneNumber(ctx context.Context, phoneNumber string)
}
// DeleteOTP to delete otp
-func (p *provider) DeleteOTP(ctx context.Context, otp *models.OTP) error {
- result := p.db.Delete(&models.OTP{
+func (p *provider) DeleteOTP(ctx context.Context, otp *schemas.OTP) error {
+ result := p.db.Delete(&schemas.OTP{
ID: otp.ID,
})
if result.Error != nil {
diff --git a/server/db/providers/sql/provider.go b/internal/storage/db/sql/provider.go
similarity index 70%
rename from server/db/providers/sql/provider.go
rename to internal/storage/db/sql/provider.go
index 02118ec2f..37d16ae39 100644
--- a/server/db/providers/sql/provider.go
+++ b/internal/storage/db/sql/provider.go
@@ -1,26 +1,33 @@
package sql
import (
- "time"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/db/models"
- "github.com/authorizerdev/authorizer/server/memorystore"
libsql "github.com/ekristen/gorm-libsql"
"github.com/glebarez/sqlite"
- "github.com/sirupsen/logrus"
+ "github.com/rs/zerolog"
"gorm.io/driver/mysql"
"gorm.io/driver/postgres"
"gorm.io/driver/sqlserver"
"gorm.io/gorm"
- "gorm.io/gorm/logger"
"gorm.io/gorm/schema"
+
+ "github.com/authorizerdev/authorizer/internal/config"
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
+// Dependencies struct the sql data store provider
+type Dependencies struct {
+ Log *zerolog.Logger
+}
+
type provider struct {
- db *gorm.DB
+ config *config.Config
+ dependencies *Dependencies
+ db *gorm.DB
}
+/**
+Required to address the impact of the following code block:
const (
phoneNumberIndexName = "UQ_phone_number"
phoneNumberColumnName = "phone_number"
@@ -30,31 +37,25 @@ type indexInfo struct {
IndexName string `json:"index_name"`
ColumnName string `json:"column_name"`
}
+**/
// NewProvider returns a new SQL provider
-func NewProvider() (*provider, error) {
+func NewProvider(
+ config *config.Config,
+ deps *Dependencies,
+) (*provider, error) {
var sqlDB *gorm.DB
var err error
- customLogger := logger.New(
- logrus.StandardLogger(),
- logger.Config{
- SlowThreshold: time.Second, // Slow SQL threshold
- LogLevel: logger.Error, // Log level
- IgnoreRecordNotFoundError: true, // Ignore ErrRecordNotFound error for logger
- Colorful: false, // Disable color
- },
- )
ormConfig := &gorm.Config{
- Logger: customLogger,
NamingStrategy: schema.NamingStrategy{
- TablePrefix: models.Prefix,
+ TablePrefix: schemas.Prefix,
},
AllowGlobalUpdate: true,
}
- dbType := memorystore.RequiredEnvStoreObj.GetRequiredEnv().DatabaseType
- dbURL := memorystore.RequiredEnvStoreObj.GetRequiredEnv().DatabaseURL
+ dbType := config.DatabaseType
+ dbURL := config.DatabaseURL
switch dbType {
case constants.DbTypePostgres, constants.DbTypeYugabyte, constants.DbTypeCockroachDB:
@@ -75,12 +76,14 @@ func NewProvider() (*provider, error) {
// For sqlserver, handle uniqueness of phone_number manually via extra db call
// during create and update mutation.
- if sqlDB.Migrator().HasConstraint(&models.User{}, "authorizer_users_phone_number_key") {
- err = sqlDB.Migrator().DropConstraint(&models.User{}, "authorizer_users_phone_number_key")
- logrus.Debug("Failed to drop phone number constraint:", err)
+ if sqlDB.Migrator().HasConstraint(&schemas.User{}, "authorizer_users_phone_number_key") {
+ err = sqlDB.Migrator().DropConstraint(&schemas.User{}, "authorizer_users_phone_number_key")
+ if err != nil {
+ deps.Log.Debug().Err(err).Msg("failed to drop unique constraint on phone_number")
+ }
}
- err = sqlDB.AutoMigrate(&models.User{}, &models.VerificationRequest{}, &models.Session{}, &models.Env{}, &models.Webhook{}, &models.WebhookLog{}, &models.EmailTemplate{}, &models.OTP{}, &models.Authenticator{})
+ err = sqlDB.AutoMigrate(&schemas.User{}, &schemas.VerificationRequest{}, &schemas.Session{}, &schemas.Env{}, &schemas.Webhook{}, &schemas.WebhookLog{}, &schemas.EmailTemplate{}, &schemas.OTP{}, &schemas.Authenticator{})
if err != nil {
return nil, err
}
@@ -112,6 +115,8 @@ func NewProvider() (*provider, error) {
// }
return &provider{
- db: sqlDB,
+ config: config,
+ dependencies: deps,
+ db: sqlDB,
}, nil
}
diff --git a/server/db/providers/sql/session.go b/internal/storage/db/sql/session.go
similarity index 80%
rename from server/db/providers/sql/session.go
rename to internal/storage/db/sql/session.go
index a7e3e1374..ad2941b36 100644
--- a/server/db/providers/sql/session.go
+++ b/internal/storage/db/sql/session.go
@@ -4,13 +4,14 @@ import (
"context"
"time"
- "github.com/authorizerdev/authorizer/server/db/models"
"github.com/google/uuid"
"gorm.io/gorm/clause"
+
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
// AddSession to save session information in database
-func (p *provider) AddSession(ctx context.Context, session *models.Session) error {
+func (p *provider) AddSession(ctx context.Context, session *schemas.Session) error {
if session.ID == "" {
session.ID = uuid.New().String()
}
diff --git a/server/db/providers/sql/user.go b/internal/storage/db/sql/user.go
similarity index 67%
rename from server/db/providers/sql/user.go
rename to internal/storage/db/sql/user.go
index e0b61fe3d..ba6cdfdae 100644
--- a/server/db/providers/sql/user.go
+++ b/internal/storage/db/sql/user.go
@@ -6,27 +6,22 @@ import (
"strings"
"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/authorizerdev/authorizer/server/refs"
"github.com/google/uuid"
"gorm.io/gorm"
+
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/refs"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
// AddUser to save user information in database
-func (p *provider) AddUser(ctx context.Context, user *models.User) (*models.User, error) {
+func (p *provider) AddUser(ctx context.Context, user *schemas.User) (*schemas.User, error) {
if user.ID == "" {
user.ID = uuid.New().String()
}
if user.Roles == "" {
- defaultRoles, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyDefaultRoles)
- if err != nil {
- return nil, err
- }
- user.Roles = defaultRoles
+ user.Roles = strings.Join(p.config.DefaultRoles, ",")
}
if user.PhoneNumber != nil && strings.TrimSpace(refs.StringValue(user.PhoneNumber)) != "" {
@@ -52,7 +47,7 @@ func (p *provider) AddUser(ctx context.Context, user *models.User) (*models.User
}
// UpdateUser to update user information in database
-func (p *provider) UpdateUser(ctx context.Context, user *models.User) (*models.User, error) {
+func (p *provider) UpdateUser(ctx context.Context, user *schemas.User) (*schemas.User, error) {
user.UpdatedAt = time.Now().Unix()
result := p.db.Save(&user)
@@ -65,8 +60,8 @@ func (p *provider) UpdateUser(ctx context.Context, user *models.User) (*models.U
}
// DeleteUser to delete user information from database
-func (p *provider) DeleteUser(ctx context.Context, user *models.User) error {
- result := p.db.Where("user_id = ?", user.ID).Delete(&models.Session{})
+func (p *provider) DeleteUser(ctx context.Context, user *schemas.User) error {
+ result := p.db.Where("user_id = ?", user.ID).Delete(&schemas.Session{})
if result.Error != nil {
return result.Error
}
@@ -80,36 +75,28 @@ func (p *provider) DeleteUser(ctx context.Context, user *models.User) error {
}
// ListUsers to get list of users from database
-func (p *provider) ListUsers(ctx context.Context, pagination *model.Pagination) (*model.Users, error) {
- var users []models.User
+func (p *provider) ListUsers(ctx context.Context, pagination *model.Pagination) ([]*schemas.User, *model.Pagination, error) {
+ var users []*schemas.User
result := p.db.Limit(int(pagination.Limit)).Offset(int(pagination.Offset)).Order("created_at DESC").Find(&users)
if result.Error != nil {
- return nil, result.Error
- }
-
- responseUsers := []*model.User{}
- for _, user := range users {
- responseUsers = append(responseUsers, user.AsAPIUser())
+ return nil, nil, result.Error
}
var total int64
- totalRes := p.db.Model(&models.User{}).Count(&total)
+ totalRes := p.db.Model(&schemas.User{}).Count(&total)
if totalRes.Error != nil {
- return nil, totalRes.Error
+ return nil, nil, totalRes.Error
}
paginationClone := pagination
paginationClone.Total = total
- return &model.Users{
- Pagination: paginationClone,
- Users: responseUsers,
- }, nil
+ return users, paginationClone, nil
}
// GetUserByEmail to get user information from database using email address
-func (p *provider) GetUserByEmail(ctx context.Context, email string) (*models.User, error) {
- var user *models.User
+func (p *provider) GetUserByEmail(ctx context.Context, email string) (*schemas.User, error) {
+ var user *schemas.User
result := p.db.Where("email = ?", email).First(&user)
if result.Error != nil {
return nil, result.Error
@@ -118,8 +105,8 @@ func (p *provider) GetUserByEmail(ctx context.Context, email string) (*models.Us
}
// GetUserByID to get user information from database using user ID
-func (p *provider) GetUserByID(ctx context.Context, id string) (*models.User, error) {
- var user *models.User
+func (p *provider) GetUserByID(ctx context.Context, id string) (*schemas.User, error) {
+ var user *schemas.User
result := p.db.Where("id = ?", id).First(&user)
if result.Error != nil {
return nil, result.Error
@@ -134,9 +121,9 @@ func (p *provider) UpdateUsers(ctx context.Context, data map[string]interface{},
data["updated_at"] = time.Now().Unix()
var res *gorm.DB
if len(ids) > 0 {
- res = p.db.Model(&models.User{}).Where("id in ?", ids).Updates(data)
+ res = p.db.Model(&schemas.User{}).Where("id in ?", ids).Updates(data)
} else {
- res = p.db.Model(&models.User{}).Updates(data)
+ res = p.db.Model(&schemas.User{}).Updates(data)
}
if res.Error != nil {
return res.Error
@@ -145,8 +132,8 @@ func (p *provider) UpdateUsers(ctx context.Context, data map[string]interface{},
}
// GetUserByPhoneNumber to get user information from database using phone number
-func (p *provider) GetUserByPhoneNumber(ctx context.Context, phoneNumber string) (*models.User, error) {
- var user *models.User
+func (p *provider) GetUserByPhoneNumber(ctx context.Context, phoneNumber string) (*schemas.User, error) {
+ var user *schemas.User
result := p.db.Where("phone_number = ?", phoneNumber).First(&user)
if result.Error != nil {
return nil, result.Error
diff --git a/server/db/providers/sql/verification_requests.go b/internal/storage/db/sql/verification_requests.go
similarity index 66%
rename from server/db/providers/sql/verification_requests.go
rename to internal/storage/db/sql/verification_requests.go
index ac91becdf..21bbc6cd3 100644
--- a/server/db/providers/sql/verification_requests.go
+++ b/internal/storage/db/sql/verification_requests.go
@@ -4,14 +4,15 @@ import (
"context"
"time"
- "github.com/authorizerdev/authorizer/server/db/models"
- "github.com/authorizerdev/authorizer/server/graph/model"
"github.com/google/uuid"
"gorm.io/gorm/clause"
+
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
// AddVerification to save verification request in database
-func (p *provider) AddVerificationRequest(ctx context.Context, verificationRequest *models.VerificationRequest) (*models.VerificationRequest, error) {
+func (p *provider) AddVerificationRequest(ctx context.Context, verificationRequest *schemas.VerificationRequest) (*schemas.VerificationRequest, error) {
if verificationRequest.ID == "" {
verificationRequest.ID = uuid.New().String()
}
@@ -29,8 +30,8 @@ func (p *provider) AddVerificationRequest(ctx context.Context, verificationReque
}
// GetVerificationRequestByToken to get verification request from database using token
-func (p *provider) GetVerificationRequestByToken(ctx context.Context, token string) (*models.VerificationRequest, error) {
- var verificationRequest *models.VerificationRequest
+func (p *provider) GetVerificationRequestByToken(ctx context.Context, token string) (*schemas.VerificationRequest, error) {
+ var verificationRequest *schemas.VerificationRequest
result := p.db.Where("token = ?", token).First(&verificationRequest)
if result.Error != nil {
return verificationRequest, result.Error
@@ -39,8 +40,8 @@ func (p *provider) GetVerificationRequestByToken(ctx context.Context, token stri
}
// 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
+func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email string, identifier string) (*schemas.VerificationRequest, error) {
+ var verificationRequest *schemas.VerificationRequest
result := p.db.Where("email = ? AND identifier = ?", email, identifier).First(&verificationRequest)
if result.Error != nil {
return verificationRequest, result.Error
@@ -49,31 +50,24 @@ func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email stri
}
// ListVerificationRequests to get list of verification requests from database
-func (p *provider) ListVerificationRequests(ctx context.Context, pagination *model.Pagination) (*model.VerificationRequests, error) {
- var verificationRequests []models.VerificationRequest
+func (p *provider) ListVerificationRequests(ctx context.Context, pagination *model.Pagination) ([]*schemas.VerificationRequest, *model.Pagination, error) {
+ var verificationRequests []*schemas.VerificationRequest
result := p.db.Limit(int(pagination.Limit)).Offset(int(pagination.Offset)).Order("created_at DESC").Find(&verificationRequests)
if result.Error != nil {
- return nil, result.Error
- }
- responseVerificationRequests := []*model.VerificationRequest{}
- for _, v := range verificationRequests {
- responseVerificationRequests = append(responseVerificationRequests, v.AsAPIVerificationRequest())
+ return nil, nil, result.Error
}
var total int64
- totalRes := p.db.Model(&models.VerificationRequest{}).Count(&total)
+ totalRes := p.db.Model(&schemas.VerificationRequest{}).Count(&total)
if totalRes.Error != nil {
- return nil, totalRes.Error
+ return nil, nil, totalRes.Error
}
paginationClone := pagination
paginationClone.Total = total
- return &model.VerificationRequests{
- VerificationRequests: responseVerificationRequests,
- Pagination: paginationClone,
- }, nil
+ return verificationRequests, paginationClone, nil
}
// DeleteVerificationRequest to delete verification request from database
-func (p *provider) DeleteVerificationRequest(ctx context.Context, verificationRequest *models.VerificationRequest) error {
+func (p *provider) DeleteVerificationRequest(ctx context.Context, verificationRequest *schemas.VerificationRequest) error {
result := p.db.Delete(&verificationRequest)
if result.Error != nil {
return result.Error
diff --git a/server/db/providers/sql/webhook.go b/internal/storage/db/sql/webhook.go
similarity index 57%
rename from server/db/providers/sql/webhook.go
rename to internal/storage/db/sql/webhook.go
index 54e2d130f..41675c233 100644
--- a/server/db/providers/sql/webhook.go
+++ b/internal/storage/db/sql/webhook.go
@@ -6,13 +6,14 @@ import (
"strings"
"time"
- "github.com/authorizerdev/authorizer/server/db/models"
- "github.com/authorizerdev/authorizer/server/graph/model"
"github.com/google/uuid"
+
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
// AddWebhook to add webhook
-func (p *provider) AddWebhook(ctx context.Context, webhook *models.Webhook) (*model.Webhook, error) {
+func (p *provider) AddWebhook(ctx context.Context, webhook *schemas.Webhook) (*schemas.Webhook, error) {
if webhook.ID == "" {
webhook.ID = uuid.New().String()
}
@@ -25,11 +26,11 @@ func (p *provider) AddWebhook(ctx context.Context, webhook *models.Webhook) (*mo
if res.Error != nil {
return nil, res.Error
}
- return webhook.AsAPIWebhook(), nil
+ return webhook, nil
}
// UpdateWebhook to update webhook
-func (p *provider) UpdateWebhook(ctx context.Context, webhook *models.Webhook) (*model.Webhook, error) {
+func (p *provider) UpdateWebhook(ctx context.Context, webhook *schemas.Webhook) (*schemas.Webhook, error) {
webhook.UpdatedAt = time.Now().Unix()
// Event is changed
if !strings.Contains(webhook.EventName, "-") {
@@ -39,68 +40,58 @@ func (p *provider) UpdateWebhook(ctx context.Context, webhook *models.Webhook) (
if result.Error != nil {
return nil, result.Error
}
- return webhook.AsAPIWebhook(), nil
+ return webhook, nil
}
// ListWebhooks to list webhook
-func (p *provider) ListWebhook(ctx context.Context, pagination *model.Pagination) (*model.Webhooks, error) {
- var webhooks []models.Webhook
+func (p *provider) ListWebhook(ctx context.Context, pagination *model.Pagination) ([]*schemas.Webhook, *model.Pagination, error) {
+ var webhooks []*schemas.Webhook
result := p.db.Limit(int(pagination.Limit)).Offset(int(pagination.Offset)).Order("created_at DESC").Find(&webhooks)
if result.Error != nil {
- return nil, result.Error
+ return nil, nil, result.Error
}
var total int64
- totalRes := p.db.Model(&models.Webhook{}).Count(&total)
+ totalRes := p.db.Model(&schemas.Webhook{}).Count(&total)
if totalRes.Error != nil {
- return nil, totalRes.Error
+ return nil, nil, totalRes.Error
}
paginationClone := pagination
paginationClone.Total = total
- responseWebhooks := []*model.Webhook{}
- for _, w := range webhooks {
- responseWebhooks = append(responseWebhooks, w.AsAPIWebhook())
- }
- return &model.Webhooks{
- Pagination: paginationClone,
- Webhooks: responseWebhooks,
- }, nil
+
+ return webhooks, paginationClone, nil
}
// GetWebhookByID to get webhook by id
-func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*model.Webhook, error) {
- var webhook *models.Webhook
+func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*schemas.Webhook, error) {
+ var webhook *schemas.Webhook
result := p.db.Where("id = ?", webhookID).First(&webhook)
if result.Error != nil {
return nil, result.Error
}
- return webhook.AsAPIWebhook(), nil
+ return webhook, nil
}
// GetWebhookByEventName to get webhook by event_name
-func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string) ([]*model.Webhook, error) {
- var webhooks []models.Webhook
+func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string) ([]*schemas.Webhook, error) {
+ var webhooks []*schemas.Webhook
result := p.db.Where("event_name LIKE ?", eventName+"%").Find(&webhooks)
if result.Error != nil {
return nil, result.Error
}
- responseWebhooks := []*model.Webhook{}
- for _, w := range webhooks {
- responseWebhooks = append(responseWebhooks, w.AsAPIWebhook())
- }
- return responseWebhooks, nil
+ return webhooks, nil
}
// DeleteWebhook to delete webhook
-func (p *provider) DeleteWebhook(ctx context.Context, webhook *model.Webhook) error {
- result := p.db.Delete(&models.Webhook{
+func (p *provider) DeleteWebhook(ctx context.Context, webhook *schemas.Webhook) error {
+ result := p.db.Delete(&schemas.Webhook{
ID: webhook.ID,
})
if result.Error != nil {
return result.Error
}
- result = p.db.Where("webhook_id = ?", webhook.ID).Delete(&models.WebhookLog{})
+ result = p.db.Where("webhook_id = ?", webhook.ID).Delete(&schemas.WebhookLog{})
if result.Error != nil {
return result.Error
}
diff --git a/server/db/providers/sql/webhook_log.go b/internal/storage/db/sql/webhook_log.go
similarity index 59%
rename from server/db/providers/sql/webhook_log.go
rename to internal/storage/db/sql/webhook_log.go
index cf50be2c6..fddf9f951 100644
--- a/server/db/providers/sql/webhook_log.go
+++ b/internal/storage/db/sql/webhook_log.go
@@ -4,15 +4,16 @@ import (
"context"
"time"
- "github.com/authorizerdev/authorizer/server/db/models"
- "github.com/authorizerdev/authorizer/server/graph/model"
"github.com/google/uuid"
"gorm.io/gorm"
"gorm.io/gorm/clause"
+
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
)
// AddWebhookLog to add webhook log
-func (p *provider) AddWebhookLog(ctx context.Context, webhookLog *models.WebhookLog) (*model.WebhookLog, error) {
+func (p *provider) AddWebhookLog(ctx context.Context, webhookLog *schemas.WebhookLog) (*schemas.WebhookLog, error) {
if webhookLog.ID == "" {
webhookLog.ID = uuid.New().String()
}
@@ -28,41 +29,34 @@ func (p *provider) AddWebhookLog(ctx context.Context, webhookLog *models.Webhook
return nil, res.Error
}
- return webhookLog.AsAPIWebhookLog(), nil
+ return webhookLog, nil
}
// ListWebhookLogs to list webhook logs
-func (p *provider) ListWebhookLogs(ctx context.Context, pagination *model.Pagination, webhookID string) (*model.WebhookLogs, error) {
- var webhookLogs []models.WebhookLog
+func (p *provider) ListWebhookLogs(ctx context.Context, pagination *model.Pagination, webhookID string) ([]*schemas.WebhookLog, *model.Pagination, error) {
+ var webhookLogs []*schemas.WebhookLog
var result *gorm.DB
var totalRes *gorm.DB
var total int64
if webhookID != "" {
result = p.db.Where("webhook_id = ?", webhookID).Limit(int(pagination.Limit)).Offset(int(pagination.Offset)).Order("created_at DESC").Find(&webhookLogs)
- totalRes = p.db.Where("webhook_id = ?", webhookID).Model(&models.WebhookLog{}).Count(&total)
+ totalRes = p.db.Where("webhook_id = ?", webhookID).Model(&schemas.WebhookLog{}).Count(&total)
} else {
result = p.db.Limit(int(pagination.Limit)).Offset(int(pagination.Offset)).Order("created_at DESC").Find(&webhookLogs)
- totalRes = p.db.Model(&models.WebhookLog{}).Count(&total)
+ totalRes = p.db.Model(&schemas.WebhookLog{}).Count(&total)
}
if result.Error != nil {
- return nil, result.Error
+ return nil, nil, result.Error
}
if totalRes.Error != nil {
- return nil, totalRes.Error
+ return nil, nil, totalRes.Error
}
paginationClone := pagination
paginationClone.Total = total
- responseWebhookLogs := []*model.WebhookLog{}
- for _, w := range webhookLogs {
- responseWebhookLogs = append(responseWebhookLogs, w.AsAPIWebhookLog())
- }
- return &model.WebhookLogs{
- WebhookLogs: responseWebhookLogs,
- Pagination: paginationClone,
- }, nil
+ return webhookLogs, paginationClone, nil
}
diff --git a/internal/storage/provider.go b/internal/storage/provider.go
new file mode 100644
index 000000000..f30bef428
--- /dev/null
+++ b/internal/storage/provider.go
@@ -0,0 +1,171 @@
+package storage
+
+import (
+ "context"
+ "fmt"
+
+ "github.com/rs/zerolog"
+
+ "github.com/authorizerdev/authorizer/internal/config"
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/storage/db/arangodb"
+ "github.com/authorizerdev/authorizer/internal/storage/db/cassandradb"
+ "github.com/authorizerdev/authorizer/internal/storage/db/couchbase"
+ "github.com/authorizerdev/authorizer/internal/storage/db/dynamodb"
+ "github.com/authorizerdev/authorizer/internal/storage/db/mongodb"
+ "github.com/authorizerdev/authorizer/internal/storage/db/sql"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
+)
+
+// Dependencies struct the data store provider
+type Dependencies struct {
+ Log *zerolog.Logger
+}
+
+// Provider is the interface which defines the methods for the database provider
+type Provider interface {
+ // AddUser to save user information in database
+ AddUser(ctx context.Context, user *schemas.User) (*schemas.User, error)
+ // UpdateUser to update user information in database
+ UpdateUser(ctx context.Context, user *schemas.User) (*schemas.User, error)
+ // DeleteUser to delete user information from database
+ DeleteUser(ctx context.Context, user *schemas.User) error
+ // ListUsers to get list of users from database
+ ListUsers(ctx context.Context, pagination *model.Pagination) ([]*schemas.User, *model.Pagination, error)
+ // GetUserByEmail to get user information from database using email address
+ GetUserByEmail(ctx context.Context, email string) (*schemas.User, error)
+ // GetUserByPhoneNumber to get user information from database using phone number
+ GetUserByPhoneNumber(ctx context.Context, phoneNumber string) (*schemas.User, error)
+ // GetUserByID to get user information from database using user ID
+ GetUserByID(ctx context.Context, id string) (*schemas.User, error)
+ // UpdateUsers to update multiple users, with parameters of user IDs slice
+ // If ids set to nil / empty all the users will be updated
+ UpdateUsers(ctx context.Context, data map[string]interface{}, ids []string) error
+
+ // AddVerificationRequest to save verification request in database
+ AddVerificationRequest(ctx context.Context, verificationRequest *schemas.VerificationRequest) (*schemas.VerificationRequest, error)
+ // GetVerificationRequestByToken to get verification request from database using token
+ GetVerificationRequestByToken(ctx context.Context, token string) (*schemas.VerificationRequest, error)
+ // GetVerificationRequestByEmail to get verification request by email from database
+ GetVerificationRequestByEmail(ctx context.Context, email string, identifier string) (*schemas.VerificationRequest, error)
+ // ListVerificationRequests to get list of verification requests from database
+ ListVerificationRequests(ctx context.Context, pagination *model.Pagination) ([]*schemas.VerificationRequest, *model.Pagination, error)
+ // DeleteVerificationRequest to delete verification request from database
+ DeleteVerificationRequest(ctx context.Context, verificationRequest *schemas.VerificationRequest) error
+
+ // AddSession to save session information in database
+ AddSession(ctx context.Context, session *schemas.Session) error
+ // DeleteSession to delete session information from database
+ DeleteSession(ctx context.Context, userId string) error
+
+ // // AddEnv to save environment information in database
+ // AddEnv(ctx context.Context, env *schemas.Env) (*schemas.Env, error)
+ // // UpdateEnv to update environment information in database
+ // UpdateEnv(ctx context.Context, env *schemas.Env) (*schemas.Env, error)
+ // // GetEnv to get environment information from database
+ // GetEnv(ctx context.Context) (*schemas.Env, error)
+
+ // AddWebhook to add webhook
+ AddWebhook(ctx context.Context, webhook *schemas.Webhook) (*schemas.Webhook, error)
+ // UpdateWebhook to update webhook
+ UpdateWebhook(ctx context.Context, webhook *schemas.Webhook) (*schemas.Webhook, error)
+ // ListWebhook to list webhook
+ ListWebhook(ctx context.Context, pagination *model.Pagination) ([]*schemas.Webhook, *model.Pagination, error)
+ // GetWebhookByID to get webhook by id
+ GetWebhookByID(ctx context.Context, webhookID string) (*schemas.Webhook, error)
+ // GetWebhookByEventName to get webhook by event_name
+ GetWebhookByEventName(ctx context.Context, eventName string) ([]*schemas.Webhook, error)
+ // DeleteWebhook to delete webhook
+ DeleteWebhook(ctx context.Context, webhook *schemas.Webhook) error
+
+ // AddWebhookLog to add webhook log
+ AddWebhookLog(ctx context.Context, webhookLog *schemas.WebhookLog) (*schemas.WebhookLog, error)
+ // ListWebhookLogs to list webhook logs
+ ListWebhookLogs(ctx context.Context, pagination *model.Pagination, webhookID string) ([]*schemas.WebhookLog, *model.Pagination, error)
+
+ // AddEmailTemplate to add EmailTemplate
+ AddEmailTemplate(ctx context.Context, emailTemplate *schemas.EmailTemplate) (*schemas.EmailTemplate, error)
+ // UpdateEmailTemplate to update EmailTemplate
+ UpdateEmailTemplate(ctx context.Context, emailTemplate *schemas.EmailTemplate) (*schemas.EmailTemplate, error)
+ // ListEmailTemplate to list EmailTemplate
+ ListEmailTemplate(ctx context.Context, pagination *model.Pagination) ([]*schemas.EmailTemplate, *model.Pagination, error)
+ // GetEmailTemplateByID to get EmailTemplate by id
+ GetEmailTemplateByID(ctx context.Context, emailTemplateID string) (*schemas.EmailTemplate, error)
+ // GetEmailTemplateByEventName to get EmailTemplate by event_name
+ GetEmailTemplateByEventName(ctx context.Context, eventName string) (*schemas.EmailTemplate, error)
+ // DeleteEmailTemplate to delete EmailTemplate
+ DeleteEmailTemplate(ctx context.Context, emailTemplate *schemas.EmailTemplate) error
+
+ // UpsertOTP to add or update otp
+ UpsertOTP(ctx context.Context, otp *schemas.OTP) (*schemas.OTP, error)
+ // GetOTPByEmail to get otp for a given email address
+ GetOTPByEmail(ctx context.Context, emailAddress string) (*schemas.OTP, error)
+ // GetOTPByPhoneNumber to get otp for a given phone number
+ GetOTPByPhoneNumber(ctx context.Context, phoneNumber string) (*schemas.OTP, error)
+ // DeleteOTP to delete otp
+ DeleteOTP(ctx context.Context, otp *schemas.OTP) error
+
+ // AddAuthenticator adds a new authenticator document to the database.
+ // If the authenticator doesn't have an ID, a new one is generated.
+ // The created document is returned, or an error if the operation fails.
+ AddAuthenticator(ctx context.Context, totp *schemas.Authenticator) (*schemas.Authenticator, error)
+ // UpdateAuthenticator updates an existing authenticator document in the database.
+ // The updated document is returned, or an error if the operation fails.
+ UpdateAuthenticator(ctx context.Context, totp *schemas.Authenticator) (*schemas.Authenticator, error)
+ // GetAuthenticatorDetailsByUserId retrieves details of an authenticator document based on user ID and authenticator type.
+ // If found, the authenticator document is returned, or an error if not found or an error occurs during the retrieval.
+ GetAuthenticatorDetailsByUserId(ctx context.Context, userId string, authenticatorType string) (*schemas.Authenticator, error)
+}
+
+// New creates a new database provider based on the configuration
+func New(config *config.Config, deps *Dependencies) (Provider, error) {
+ var provider Provider
+ var err error
+ if config.DatabaseType == "" {
+ return nil, fmt.Errorf("database type is required")
+ }
+
+ switch config.DatabaseType {
+ case constants.DbTypePostgres,
+ constants.DbTypeSqlite,
+ constants.DbTypeLibSQL,
+ constants.DbTypeMysql,
+ constants.DbTypeSqlserver,
+ constants.DbTypeYugabyte,
+ constants.DbTypeMariaDB,
+ constants.DbTypeCockroachDB,
+ constants.DbTypePlanetScaleDB:
+ provider, err = sql.NewProvider(config, &sql.Dependencies{
+ Log: deps.Log,
+ })
+ case constants.DbTypeMongoDB:
+ provider, err = mongodb.NewProvider(config, &mongodb.Dependencies{
+ Log: deps.Log,
+ })
+ case constants.DbTypeArangoDB:
+ provider, err = arangodb.NewProvider(config, &arangodb.Dependencies{
+ Log: deps.Log,
+ })
+ case constants.DbTypeCassandraDB,
+ constants.DbTypeScyllaDB:
+ provider, err = cassandradb.NewProvider(config, &cassandradb.Dependencies{
+ Log: deps.Log,
+ })
+ case constants.DbTypeCouchbaseDB:
+ provider, err = couchbase.NewProvider(config, &couchbase.Dependencies{
+ Log: deps.Log,
+ })
+ case constants.DbTypeDynamoDB:
+ provider, err = dynamodb.NewProvider(config, &dynamodb.Dependencies{
+ Log: deps.Log,
+ })
+ default:
+ err = fmt.Errorf("unsupported database type: %s", config.DatabaseType)
+
+ }
+ if err != nil {
+ return nil, err
+ }
+ return provider, nil
+}
diff --git a/internal/storage/provider_test.go b/internal/storage/provider_test.go
new file mode 100644
index 000000000..d70cbcb1d
--- /dev/null
+++ b/internal/storage/provider_test.go
@@ -0,0 +1,401 @@
+package storage
+
+import (
+ "context"
+ "os"
+ "testing"
+ "time"
+
+ "github.com/authorizerdev/authorizer/internal/config"
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/refs"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
+ "github.com/google/uuid"
+ "github.com/rs/zerolog"
+ "github.com/rs/zerolog/log"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+var dbTypes = []string{
+ constants.DbTypePostgres,
+ // constants.DbTypeMongoDB,
+ // constants.DbTypeArangoDB,
+ // constants.DbTypeScyllaDB,
+ // constants.DbTypeCouchbaseDB,
+ // constants.DbTypeDynamoDB,
+}
+
+func getTestDBConfig(dbType string) *config.Config {
+ cfg := &config.Config{
+ DatabaseName: "authorizer_test",
+ AWSRegion: "us-east-1",
+ }
+ cfg.DatabaseType = dbType
+
+ // Set specific database URLs based on type
+ switch dbType {
+ case constants.DbTypePostgres:
+ cfg.DatabaseURL = "postgres://postgres:postgres@localhost:5432/postgres"
+ case constants.DbTypeMongoDB:
+ cfg.DatabaseURL = "mongodb://localhost:27017"
+ case constants.DbTypeArangoDB:
+ cfg.DatabaseURL = "http://localhost:8529"
+ case constants.DbTypeScyllaDB:
+ cfg.DatabaseURL = "127.0.0.1:9042"
+ case constants.DbTypeCouchbaseDB:
+ cfg.DatabaseURL = "couchbase://127.0.0.1"
+ case constants.DbTypeDynamoDB:
+ cfg.DatabaseURL = "http://0.0.0.0:8000"
+ }
+
+ return cfg
+}
+
+func TestStorageProvider(t *testing.T) {
+ // Initialize logger
+ logger := zerolog.New(zerolog.NewTestWriter(t)).With().Timestamp().Logger()
+ for _, dbType := range dbTypes {
+ t.Run("should test storage provider for "+dbType, func(t *testing.T) {
+ if dbType == constants.DbTypeDynamoDB {
+ os.Unsetenv("AWS_ACCESS_KEY_ID")
+ os.Unsetenv("AWS_SECRET_ACCESS_KEY")
+ }
+ cfg := getTestDBConfig(dbType)
+ if dbType == constants.DbTypeCouchbaseDB {
+ cfg.DatabaseUsername = "Administrator"
+ cfg.DatabasePassword = "password"
+ }
+ ctx := context.Background()
+ provider, err := New(cfg, &Dependencies{
+ Log: &logger,
+ })
+ if err != nil {
+ log.Error().Err(err).Msg("failed to create storage provider")
+ }
+ require.NoError(t, err)
+ require.NotNil(t, provider)
+
+ t.Run("Authenticator Operations", func(t *testing.T) {
+ testAuthenticatorOperations(t, ctx, provider)
+ })
+
+ t.Run("Email Template Operations", func(t *testing.T) {
+ testEmailTemplateOperations(t, ctx, provider)
+ })
+
+ t.Run("OTP Operations", func(t *testing.T) {
+ testOTPOperations(t, ctx, provider)
+ })
+
+ t.Run("Session Operations", func(t *testing.T) {
+ testSessionOperations(t, ctx, provider)
+ })
+
+ t.Run("User Operations", func(t *testing.T) {
+ testUserOperations(t, ctx, provider)
+ })
+
+ t.Run("Verification Request Operations", func(t *testing.T) {
+ testVerificationRequestOperations(t, ctx, provider)
+ })
+
+ t.Run("Webhook Operations", func(t *testing.T) {
+ testWebhookOperations(t, ctx, provider)
+ })
+
+ })
+ }
+}
+
+func testUserOperations(t *testing.T, ctx context.Context, provider Provider) {
+ // Create test user
+ user := &schemas.User{
+ ID: uuid.New().String(),
+ Email: refs.NewStringRef("test_" + uuid.New().String() + "@test.com"),
+ Password: refs.NewStringRef("hashedPassword"),
+ SignupMethods: "basic_auth",
+ }
+
+ // Test AddUser
+ createdUser, err := provider.AddUser(ctx, user)
+ assert.NoError(t, err)
+ assert.NotNil(t, createdUser)
+ assert.Equal(t, user.Email, createdUser.Email)
+
+ // Test GetUserByEmail
+ fetchedUser, err := provider.GetUserByEmail(ctx, *user.Email)
+ assert.NoError(t, err)
+ assert.Equal(t, user.Email, fetchedUser.Email)
+
+ // Test UpdateUser
+ fetchedUser.GivenName = refs.NewStringRef("Updated")
+ updatedUser, err := provider.UpdateUser(ctx, fetchedUser)
+ assert.NoError(t, err)
+ assert.Equal(t, "Updated", *updatedUser.GivenName)
+
+ // Test ListUsers
+ users, pagination, err := provider.ListUsers(ctx, &model.Pagination{
+ Limit: 10,
+ Offset: 0,
+ })
+ assert.NoError(t, err)
+ assert.NotNil(t, users)
+ assert.Greater(t, len(users), 0)
+ assert.NotNil(t, pagination)
+ assert.Greater(t, pagination.Total, int64(0))
+
+ // Test DeleteUser
+ err = provider.DeleteUser(ctx, user)
+ assert.NoError(t, err)
+
+ // Verify deletion
+ _, err = provider.GetUserByEmail(ctx, *user.Email)
+ assert.Error(t, err)
+
+ // Test GetUserByPhoneNumber
+ user.PhoneNumber = refs.NewStringRef("+1234567891")
+ createdUser, err = provider.AddUser(ctx, user)
+ assert.NoError(t, err)
+ assert.NotNil(t, createdUser)
+ assert.Equal(t, user.PhoneNumber, createdUser.PhoneNumber)
+
+ // Test GetUserByID
+ fetchedUser, err = provider.GetUserByID(ctx, createdUser.ID)
+ assert.NoError(t, err)
+ assert.NotNil(t, fetchedUser)
+ assert.Equal(t, user.PhoneNumber, fetchedUser.PhoneNumber)
+
+ // Test UpdateUsers
+ users, _, err = provider.ListUsers(ctx, &model.Pagination{
+ Limit: 10,
+ Offset: 0,
+ })
+ assert.NoError(t, err)
+ assert.NotNil(t, users)
+ assert.Greater(t, len(users), 0)
+ data := map[string]interface{}{
+ "phone_number": "+3216549870",
+ }
+ err = provider.UpdateUsers(ctx, data, []string{createdUser.ID})
+ assert.NoError(t, err)
+
+ // Test GetUserByPhoneNumber after update
+ user, err = provider.GetUserByPhoneNumber(ctx, "+3216549870")
+ assert.NoError(t, err)
+ assert.NotNil(t, user)
+ assert.Equal(t, "+3216549870", *user.PhoneNumber)
+
+}
+
+func testVerificationRequestOperations(t *testing.T, ctx context.Context, provider Provider) {
+ vr := &schemas.VerificationRequest{
+ Token: uuid.New().String(),
+ Email: "test_" + uuid.New().String() + "@test.com",
+ ExpiresAt: time.Now().Add(24 * time.Hour).Unix(),
+ Identifier: "email_verification",
+ }
+
+ // Test AddVerificationRequest
+ created, err := provider.AddVerificationRequest(ctx, vr)
+ assert.NoError(t, err)
+ assert.NotNil(t, created)
+
+ // Test GetVerificationRequestByToken
+ fetched, err := provider.GetVerificationRequestByToken(ctx, vr.Token)
+ assert.NoError(t, err)
+ assert.Equal(t, vr.Email, fetched.Email)
+
+ // Test GetVerificationRequestByEmail
+ fetchedByEmail, err := provider.GetVerificationRequestByEmail(ctx, vr.Email, vr.Identifier)
+ assert.NoError(t, err)
+ assert.Equal(t, vr.Token, fetchedByEmail.Token)
+
+ // Test ListVerificationRequests
+ requests, _, err := provider.ListVerificationRequests(ctx, &model.Pagination{
+ Limit: 10,
+ Offset: 0,
+ })
+ assert.NoError(t, err)
+ assert.NotNil(t, requests)
+ assert.Greater(t, len(requests), 0)
+
+ // Test DeleteVerificationRequest
+ err = provider.DeleteVerificationRequest(ctx, vr)
+ assert.NoError(t, err)
+}
+
+func testSessionOperations(t *testing.T, ctx context.Context, provider Provider) {
+ userID := uuid.New().String()
+ session := &schemas.Session{
+ UserID: userID,
+ UserAgent: "test_user_agent",
+ IP: "127.0.0.1",
+ }
+
+ // Test AddSession
+ err := provider.AddSession(ctx, session)
+ assert.NoError(t, err)
+
+ // Test DeleteSession
+ err = provider.DeleteSession(ctx, userID)
+ assert.NoError(t, err)
+}
+
+func testWebhookOperations(t *testing.T, ctx context.Context, provider Provider) {
+ webhook := &schemas.Webhook{
+ EventName: "test_event",
+ EndPoint: "https://test.com/webhook",
+ Enabled: true,
+ }
+
+ // Test AddWebhook
+ created, err := provider.AddWebhook(ctx, webhook)
+ assert.NoError(t, err)
+ assert.NotNil(t, created)
+
+ // Test GetWebhookByID
+ fetched, err := provider.GetWebhookByID(ctx, created.ID)
+ assert.NoError(t, err)
+ assert.Equal(t, webhook.EventName, fetched.EventName)
+
+ // Test GetWebhookByEventName
+ fetchedByEventName, err := provider.GetWebhookByEventName(ctx, webhook.EventName)
+ assert.NoError(t, err)
+ assert.NotNil(t, fetchedByEventName)
+ assert.Equal(t, created.ID, fetchedByEventName[0].ID)
+
+ // Test UpdateWebhook
+ webhook.EndPoint = "https://test.com/webhook_updated"
+ updated, err := provider.UpdateWebhook(ctx, webhook)
+ assert.NoError(t, err)
+ assert.Equal(t, webhook.EndPoint, updated.EndPoint)
+
+ // Test ListWebhook
+ webhooks, _, err := provider.ListWebhook(ctx, &model.Pagination{
+ Limit: 10,
+ Offset: 0,
+ })
+ assert.NoError(t, err)
+ assert.NotNil(t, webhooks)
+ assert.Greater(t, len(webhooks), 0)
+
+ // Test ListWebhookLogs
+ logs, _, err := provider.ListWebhookLogs(ctx, &model.Pagination{
+ Limit: 10,
+ Offset: 0,
+ }, webhook.ID)
+ assert.NoError(t, err)
+ assert.NotNil(t, logs)
+ assert.Empty(t, len(logs))
+
+ // Test DeleteWebhook
+ err = provider.DeleteWebhook(ctx, updated)
+ assert.NoError(t, err)
+}
+
+func testEmailTemplateOperations(t *testing.T, ctx context.Context, provider Provider) {
+ template := &schemas.EmailTemplate{
+ EventName: "test_event",
+ Template: "Test template",
+ Subject: "Test subject",
+ }
+
+ // Test AddEmailTemplate
+ created, err := provider.AddEmailTemplate(ctx, template)
+ assert.NoError(t, err)
+ assert.NotNil(t, created)
+
+ // Test GetEmailTemplateByID
+ fetched, err := provider.GetEmailTemplateByID(ctx, template.ID)
+ assert.NoError(t, err)
+ assert.Equal(t, template.EventName, fetched.EventName)
+
+ // Test GetEmailTemplateByEventName
+ fetchedByEventName, err := provider.GetEmailTemplateByEventName(ctx, template.EventName)
+ assert.NoError(t, err)
+ assert.NotNil(t, fetchedByEventName)
+ assert.Equal(t, template.EventName, fetchedByEventName.EventName)
+ assert.Equal(t, created.ID, fetchedByEventName.ID)
+
+ // Test UpdateEmailTemplate
+ template.Template = "Updated template"
+ updated, err := provider.UpdateEmailTemplate(ctx, template)
+ assert.NoError(t, err)
+ assert.Equal(t, template.Template, updated.Template)
+
+ // Test ListEmailTemplate
+ templates, _, err := provider.ListEmailTemplate(ctx, &model.Pagination{
+ Limit: 10,
+ Offset: 0,
+ })
+ assert.NoError(t, err)
+ assert.NotNil(t, templates)
+ assert.Greater(t, len(templates), 0)
+ assert.Equal(t, template.EventName, templates[0].EventName)
+ assert.Equal(t, template.Template, templates[0].Template)
+
+ // Test DeleteEmailTemplate
+ err = provider.DeleteEmailTemplate(ctx, updated)
+ assert.NoError(t, err)
+
+ // Test GetEmailTemplateByEventName after delete
+ fetchedByEventName, err = provider.GetEmailTemplateByEventName(ctx, template.EventName)
+ assert.Error(t, err)
+ assert.Nil(t, fetchedByEventName)
+}
+
+func testOTPOperations(t *testing.T, ctx context.Context, provider Provider) {
+ otp := &schemas.OTP{
+ Email: "test_" + uuid.New().String() + "@test.com",
+ Otp: "123456",
+ ExpiresAt: time.Now().Add(5 * time.Minute).Unix(),
+ }
+
+ // Test UpsertOTP
+ created, err := provider.UpsertOTP(ctx, otp)
+ assert.NoError(t, err)
+ assert.NotNil(t, created)
+
+ // Test GetOTPByEmail
+ fetched, err := provider.GetOTPByEmail(ctx, otp.Email)
+ assert.NoError(t, err)
+ assert.Equal(t, otp.Otp, fetched.Otp)
+
+ // For same email address, upsert should update the OTP
+ otp.Otp = "789012"
+ updated, err := provider.UpsertOTP(ctx, otp)
+ assert.NoError(t, err)
+ assert.NotNil(t, updated)
+ assert.Equal(t, otp.Otp, updated.Otp)
+
+ // Test DeleteOTP
+ err = provider.DeleteOTP(ctx, updated)
+ assert.NoError(t, err)
+}
+
+func testAuthenticatorOperations(t *testing.T, ctx context.Context, provider Provider) {
+ auth := &schemas.Authenticator{
+ UserID: uuid.New().String(),
+ Method: constants.EnvKeyTOTPAuthenticator,
+ RecoveryCodes: refs.NewStringRef("test"),
+ Secret: "test_secret",
+ }
+
+ // Test AddAuthenticator
+ created, err := provider.AddAuthenticator(ctx, auth)
+ assert.NoError(t, err)
+ assert.NotNil(t, created)
+
+ // Test GetAuthenticatorDetailsByUserId
+ fetched, err := provider.GetAuthenticatorDetailsByUserId(ctx, auth.UserID, constants.EnvKeyTOTPAuthenticator)
+ assert.NoError(t, err)
+ assert.Equal(t, auth.Secret, fetched.Secret)
+
+ // Test UpdateAuthenticator
+ auth.Secret = "updated_secret"
+ updated, err := provider.UpdateAuthenticator(ctx, auth)
+ assert.NoError(t, err)
+ assert.Equal(t, "updated_secret", updated.Secret)
+}
diff --git a/server/db/models/authenticators.go b/internal/storage/schemas/authenticators.go
similarity index 98%
rename from server/db/models/authenticators.go
rename to internal/storage/schemas/authenticators.go
index c5c05ed41..b0d65ba1d 100644
--- a/server/db/models/authenticators.go
+++ b/internal/storage/schemas/authenticators.go
@@ -1,4 +1,4 @@
-package models
+package schemas
// Note: any change here should be reflected in providers/casandra/provider.go as it does not have model support in collection creation
diff --git a/server/db/models/email_templates.go b/internal/storage/schemas/email_templates.go
similarity index 91%
rename from server/db/models/email_templates.go
rename to internal/storage/schemas/email_templates.go
index f8be29259..0ee6c1ace 100644
--- a/server/db/models/email_templates.go
+++ b/internal/storage/schemas/email_templates.go
@@ -1,10 +1,10 @@
-package models
+package schemas
import (
"strings"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/refs"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/refs"
)
// EmailTemplate model for database
diff --git a/server/db/models/env.go b/internal/storage/schemas/env.go
similarity index 98%
rename from server/db/models/env.go
rename to internal/storage/schemas/env.go
index 8c39cd6bf..02215a74d 100644
--- a/server/db/models/env.go
+++ b/internal/storage/schemas/env.go
@@ -1,4 +1,4 @@
-package models
+package schemas
// Note: any change here should be reflected in providers/casandra/provider.go as it does not have model support in collection creation
diff --git a/server/db/models/model.go b/internal/storage/schemas/model.go
similarity index 98%
rename from server/db/models/model.go
rename to internal/storage/schemas/model.go
index 908303716..9060d0d8e 100644
--- a/server/db/models/model.go
+++ b/internal/storage/schemas/model.go
@@ -1,4 +1,4 @@
-package models
+package schemas
// CollectionList / Tables available for authorizer in the database
type CollectionList struct {
diff --git a/server/db/models/otp.go b/internal/storage/schemas/otp.go
similarity index 98%
rename from server/db/models/otp.go
rename to internal/storage/schemas/otp.go
index ad84cf26e..4fb94ead6 100644
--- a/server/db/models/otp.go
+++ b/internal/storage/schemas/otp.go
@@ -1,4 +1,4 @@
-package models
+package schemas
const (
// FieldName email is the field name for email
diff --git a/server/db/models/session.go b/internal/storage/schemas/session.go
similarity index 98%
rename from server/db/models/session.go
rename to internal/storage/schemas/session.go
index 8460c66d8..3400917f8 100644
--- a/server/db/models/session.go
+++ b/internal/storage/schemas/session.go
@@ -1,4 +1,4 @@
-package models
+package schemas
// Note: any change here should be reflected in providers/casandra/provider.go as it does not have model support in collection creation
diff --git a/server/db/models/user.go b/internal/storage/schemas/user.go
similarity index 96%
rename from server/db/models/user.go
rename to internal/storage/schemas/user.go
index 3e4f354e8..a5a5a5f69 100644
--- a/server/db/models/user.go
+++ b/internal/storage/schemas/user.go
@@ -1,11 +1,11 @@
-package models
+package schemas
import (
"encoding/json"
"strings"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/refs"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/refs"
)
// Note: any change here should be reflected in providers/casandra/provider.go as it does not have model support in collection creation
@@ -58,7 +58,7 @@ func (user *User) AsAPIUser() *model.User {
Gender: user.Gender,
Birthdate: user.Birthdate,
PhoneNumber: user.PhoneNumber,
- PhoneNumberVerified: &isPhoneVerified,
+ PhoneNumberVerified: isPhoneVerified,
Picture: user.Picture,
Roles: strings.Split(user.Roles, ","),
RevokedTimestamp: user.RevokedTimestamp,
diff --git a/server/db/models/verification_requests.go b/internal/storage/schemas/verification_requests.go
similarity index 93%
rename from server/db/models/verification_requests.go
rename to internal/storage/schemas/verification_requests.go
index 615452356..893ef2548 100644
--- a/server/db/models/verification_requests.go
+++ b/internal/storage/schemas/verification_requests.go
@@ -1,10 +1,10 @@
-package models
+package schemas
import (
"strings"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/refs"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/refs"
)
// Note: any change here should be reflected in providers/casandra/provider.go as it does not have model support in collection creation
diff --git a/server/db/models/webhook.go b/internal/storage/schemas/webhook.go
similarity index 94%
rename from server/db/models/webhook.go
rename to internal/storage/schemas/webhook.go
index 3faefc1bd..d70d2eb99 100644
--- a/server/db/models/webhook.go
+++ b/internal/storage/schemas/webhook.go
@@ -1,11 +1,11 @@
-package models
+package schemas
import (
"encoding/json"
"strings"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/refs"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/refs"
)
// Note: any change here should be reflected in providers/casandra/provider.go as it does not have model support in collection creation
diff --git a/server/db/models/webhook_log.go b/internal/storage/schemas/webhook_log.go
similarity index 92%
rename from server/db/models/webhook_log.go
rename to internal/storage/schemas/webhook_log.go
index 0648487d8..97e90eb04 100644
--- a/server/db/models/webhook_log.go
+++ b/internal/storage/schemas/webhook_log.go
@@ -1,10 +1,10 @@
-package models
+package schemas
import (
"strings"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/refs"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
+ "github.com/authorizerdev/authorizer/internal/refs"
)
// Note: any change here should be reflected in providers/casandra/provider.go as it does not have model support in collection creation
diff --git a/internal/token/admin_token.go b/internal/token/admin_token.go
new file mode 100644
index 000000000..cd530f01f
--- /dev/null
+++ b/internal/token/admin_token.go
@@ -0,0 +1,47 @@
+package token
+
+import (
+ "fmt"
+
+ "github.com/authorizerdev/authorizer/internal/cookie"
+ "github.com/gin-gonic/gin"
+ "golang.org/x/crypto/bcrypt"
+)
+
+// TODO remove if not used
+// // CreateAdminAuthToken creates the admin token based on secret key
+// func CreateAdminAuthToken(tokenType string, c *gin.Context) (string, error) {
+// adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
+// if err != nil {
+// return "", err
+// }
+// return crypto.EncryptPassword(adminSecret)
+// }
+
+// GetAdminAuthToken helps in getting the admin token from the request cookie
+func (p *provider) GetAdminAuthToken(gc *gin.Context) (string, error) {
+ token, err := cookie.GetAdminCookie(gc)
+ if err != nil || token == "" {
+ return "", fmt.Errorf("unauthorized")
+ }
+ err = bcrypt.CompareHashAndPassword([]byte(token), []byte(p.config.AdminSecret))
+ if err != nil {
+ return "", fmt.Errorf(`unauthorized`)
+ }
+
+ return token, nil
+}
+
+// IsSuperAdmin checks if user is super admin
+func (p *provider) IsSuperAdmin(gc *gin.Context) bool {
+ token, err := p.GetAdminAuthToken(gc)
+ if err != nil {
+ secret := gc.Request.Header.Get("x-authorizer-admin-secret")
+ if secret == "" {
+ return false
+ }
+ return secret == p.config.AdminSecret
+ }
+
+ return token != ""
+}
diff --git a/server/token/auth_token.go b/internal/token/auth_token.go
similarity index 57%
rename from server/token/auth_token.go
rename to internal/token/auth_token.go
index 3fb4f3a91..8128c2db1 100644
--- a/server/token/auth_token.go
+++ b/internal/token/auth_token.go
@@ -8,29 +8,40 @@ import (
"strings"
"time"
- log "github.com/sirupsen/logrus"
-
"github.com/gin-gonic/gin"
- "github.com/golang-jwt/jwt"
+ "github.com/golang-jwt/jwt/v4"
"github.com/robertkrimen/otto"
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/cookie"
- "github.com/authorizerdev/authorizer/server/crypto"
- "github.com/authorizerdev/authorizer/server/db/models"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/parsers"
- "github.com/authorizerdev/authorizer/server/utils"
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/cookie"
+ "github.com/authorizerdev/authorizer/internal/crypto"
+ "github.com/authorizerdev/authorizer/internal/parsers"
+ "github.com/authorizerdev/authorizer/internal/storage/schemas"
+ "github.com/authorizerdev/authorizer/internal/utils"
)
+// AuthTokenConfig is the configuration for auth token
+type AuthTokenConfig struct {
+ LoginMethod string
+ Nonce string
+ Code string
+ AtHash string
+ CodeHash string
+ ExpireTime string
+ User *schemas.User
+ HostName string
+ Roles []string
+ Scope []string
+}
+
// JWTToken is a struct to hold JWT token and its expiration time
type JWTToken struct {
Token string `json:"token"`
ExpiresAt int64 `json:"expires_at"`
}
-// Token object to hold the finger print and refresh token information
-type Token struct {
+// AuthToken object to hold the finger print, access token, id token and refresh token information
+type AuthToken struct {
FingerPrint string `json:"fingerprint"`
// Session Token
FingerPrintHash string `json:"fingerprint_hash"`
@@ -52,13 +63,12 @@ type SessionData struct {
}
// CreateAuthToken creates a new auth token when userlogs in
-func CreateAuthToken(gc *gin.Context, user *models.User, roles, scope []string, loginMethod, nonce string, code string) (*Token, error) {
- hostname := parsers.GetHost(gc)
- _, fingerPrintHash, sessionTokenExpiresAt, err := CreateSessionToken(user, nonce, roles, scope, loginMethod)
+func (p *provider) CreateAuthToken(gc *gin.Context, cfg *AuthTokenConfig) (*AuthToken, error) {
+ _, fingerPrintHash, sessionTokenExpiresAt, err := p.CreateSessionToken(cfg)
if err != nil {
return nil, err
}
- accessToken, accessTokenExpiresAt, err := CreateAccessToken(user, roles, scope, hostname, nonce, loginMethod)
+ accessToken, accessTokenExpiresAt, err := p.CreateAccessToken(cfg)
if err != nil {
return nil, err
}
@@ -69,30 +79,30 @@ func CreateAuthToken(gc *gin.Context, user *models.User, roles, scope []string,
// hashedToken := string(bs)
atHashDigest := atHashBytes[0 : len(atHashBytes)/2]
atHashString := base64.RawURLEncoding.EncodeToString(atHashDigest)
-
+ cfg.AtHash = atHashString
codeHashString := ""
- if code != "" {
+ if cfg.Code != "" {
codeHash := sha256.New()
- codeHash.Write([]byte(code))
+ codeHash.Write([]byte(cfg.Code))
codeHashBytes := codeHash.Sum(nil)
codeHashDigest := codeHashBytes[0 : len(codeHashBytes)/2]
codeHashString = base64.RawURLEncoding.EncodeToString(codeHashDigest)
}
-
- idToken, idTokenExpiresAt, err := CreateIDToken(user, roles, hostname, nonce, atHashString, codeHashString, loginMethod)
+ cfg.CodeHash = codeHashString
+ idToken, idTokenExpiresAt, err := p.CreateIDToken(cfg)
if err != nil {
return nil, err
}
- res := &Token{
- FingerPrint: nonce,
+ res := &AuthToken{
+ FingerPrint: cfg.Nonce,
FingerPrintHash: fingerPrintHash,
SessionTokenExpiresAt: sessionTokenExpiresAt,
AccessToken: &JWTToken{Token: accessToken, ExpiresAt: accessTokenExpiresAt},
IDToken: &JWTToken{Token: idToken, ExpiresAt: idTokenExpiresAt},
}
- if utils.StringSliceContains(scope, "offline_access") {
- refreshToken, refreshTokenExpiresAt, err := CreateRefreshToken(user, roles, scope, hostname, nonce, loginMethod)
+ if utils.StringSliceContains(cfg.Scope, "offline_access") {
+ refreshToken, refreshTokenExpiresAt, err := p.CreateRefreshToken(cfg)
if err != nil {
return nil, err
}
@@ -104,19 +114,19 @@ func CreateAuthToken(gc *gin.Context, user *models.User, roles, scope []string,
}
// CreateSessionToken creates a new session token
-func CreateSessionToken(user *models.User, nonce string, roles, scope []string, loginMethod string) (*SessionData, string, int64, error) {
+func (p *provider) CreateSessionToken(cfg *AuthTokenConfig) (*SessionData, string, int64, error) {
expiresAt := time.Now().AddDate(1, 0, 0).Unix()
fingerPrintMap := &SessionData{
- Nonce: nonce,
- Roles: roles,
- Subject: user.ID,
- Scope: scope,
- LoginMethod: loginMethod,
+ Nonce: cfg.Nonce,
+ Roles: cfg.Roles,
+ Subject: cfg.User.ID,
+ Scope: cfg.Scope,
+ LoginMethod: cfg.LoginMethod,
IssuedAt: time.Now().Unix(),
ExpiresAt: expiresAt,
}
fingerPrintBytes, _ := json.Marshal(fingerPrintMap)
- fingerPrintHash, err := crypto.EncryptAES(string(fingerPrintBytes))
+ fingerPrintHash, err := crypto.EncryptAES(p.config.ClientSecret, string(fingerPrintBytes))
if err != nil {
return nil, "", 0, err
}
@@ -125,29 +135,25 @@ func CreateSessionToken(user *models.User, nonce string, roles, scope []string,
}
// CreateRefreshToken util to create JWT token
-func CreateRefreshToken(user *models.User, roles, scopes []string, hostname, nonce, loginMethod string) (string, int64, error) {
+func (p *provider) CreateRefreshToken(cfg *AuthTokenConfig) (string, int64, error) {
// expires in 1 year
expiryBound := time.Hour * 8760
expiresAt := time.Now().Add(expiryBound).Unix()
- clientID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyClientID)
- if err != nil {
- return "", 0, err
- }
customClaims := jwt.MapClaims{
- "iss": hostname,
- "aud": clientID,
- "sub": user.ID,
+ "iss": cfg.HostName,
+ "aud": p.config.ClientID,
+ "sub": cfg.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, ","),
+ "roles": cfg.Roles,
+ "scope": cfg.Scope,
+ "nonce": cfg.Nonce,
+ "login_method": cfg.LoginMethod,
+ "allowed_roles": strings.Split(cfg.User.Roles, ","),
}
- token, err := SignJWTToken(customClaims)
+ token, err := p.SignJWTToken(customClaims)
if err != nil {
return "", 0, err
}
@@ -157,41 +163,28 @@ func CreateRefreshToken(user *models.User, roles, scopes []string, hostname, non
// CreateAccessToken util to create JWT token, based on
// user information, roles config and CUSTOM_ACCESS_TOKEN_SCRIPT
-func CreateAccessToken(user *models.User, roles, scopes []string, hostName, nonce, loginMethod string) (string, int64, error) {
- expireTime, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAccessTokenExpiryTime)
- if err != nil {
- return "", 0, err
- }
- expiryBound, err := utils.ParseDurationInSeconds(expireTime)
+func (p *provider) CreateAccessToken(cfg *AuthTokenConfig) (string, int64, error) {
+ expiryBound, err := utils.ParseDurationInSeconds(cfg.ExpireTime)
if err != nil {
expiryBound = time.Minute * 30
}
expiresAt := time.Now().Add(expiryBound).Unix()
- clientID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyClientID)
- if err != nil {
- return "", 0, err
- }
customClaims := jwt.MapClaims{
- "iss": hostName,
- "aud": clientID,
- "nonce": nonce,
- "sub": user.ID,
+ "iss": cfg.HostName,
+ "aud": p.config.ClientID,
+ "nonce": cfg.Nonce,
+ "sub": cfg.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, ","),
+ "scope": cfg.Scope,
+ "roles": cfg.Roles,
+ "login_method": cfg.LoginMethod,
+ "allowed_roles": strings.Split(cfg.User.Roles, ","),
}
// check for the extra access token script
- accessTokenScript, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyCustomAccessTokenScript)
- if err != nil {
- log.Debug("Failed to get custom access token script: ", err)
- accessTokenScript = ""
- }
- if accessTokenScript != "" {
- resUser := user.AsAPIUser()
+ if p.config.CustomAccessTokenScript != "" {
+ resUser := cfg.User.AsAPIUser()
userBytes, _ := json.Marshal(&resUser)
var userMap map[string]interface{}
json.Unmarshal(userBytes, &userMap)
@@ -202,16 +195,16 @@ func CreateAccessToken(user *models.User, roles, scopes []string, hostName, nonc
var tokenPayload = %s;
var customFunction = %s;
var functionRes = JSON.stringify(customFunction(user, tokenPayload));
- `, string(userBytes), string(claimBytes), accessTokenScript))
+ `, string(userBytes), string(claimBytes), p.config.CustomAccessTokenScript))
val, err := vm.Get("functionRes")
if err != nil {
- log.Debug("error getting custom access token script: ", err)
+ p.dependencies.Log.Debug().Err(err).Msg("error getting custom access token script")
} else {
extraPayload := make(map[string]interface{})
- err = json.Unmarshal([]byte(fmt.Sprintf("%s", val)), &extraPayload)
+ err = json.Unmarshal([]byte(fmt.Sprintf("%v", val)), &extraPayload)
if err != nil {
- log.Debug("error converting accessTokenScript response to map: ", err)
+ p.dependencies.Log.Debug().Err(err).Msg("error converting accessTokenScript response to map")
} else {
for k, v := range extraPayload {
customClaims[k] = v
@@ -219,7 +212,7 @@ func CreateAccessToken(user *models.User, roles, scopes []string, hostName, nonc
}
}
}
- token, err := SignJWTToken(customClaims)
+ token, err := p.SignJWTToken(customClaims)
if err != nil {
return "", 0, err
}
@@ -228,7 +221,7 @@ func CreateAccessToken(user *models.User, roles, scopes []string, hostName, nonc
}
// GetAccessToken returns the access token from the request (either from header or cookie)
-func GetAccessToken(gc *gin.Context) (string, error) {
+func (p *provider) GetAccessToken(gc *gin.Context) (string, error) {
// try to check in auth header for cookie
auth := gc.Request.Header.Get("Authorization")
if auth == "" {
@@ -249,37 +242,44 @@ func GetAccessToken(gc *gin.Context) (string, error) {
}
// Function to validate access token for authorizer apis (profile, update_profile)
-func ValidateAccessToken(gc *gin.Context, accessToken string) (map[string]interface{}, error) {
+func (p *provider) ValidateAccessToken(gc *gin.Context, accessToken string) (map[string]interface{}, error) {
res := make(map[string]interface{})
if accessToken == "" {
return res, fmt.Errorf(`unauthorized`)
}
- res, err := ParseJWTToken(accessToken)
+ res, err := p.ParseJWTToken(accessToken)
if err != nil {
return res, err
}
userID := res["sub"].(string)
nonce := res["nonce"].(string)
+
loginMethod := res["login_method"]
sessionKey := userID
if loginMethod != nil && loginMethod != "" {
sessionKey = loginMethod.(string) + ":" + userID
}
- token, err := memorystore.Provider.GetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+nonce)
+ token, err := p.dependencies.MemoryStoreProvider.GetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+nonce)
if nonce == "" || err != nil {
+ p.dependencies.Log.Debug().Err(err).Msgf("invalid access token: %v, key: %s", err, sessionKey+":"+constants.TokenTypeAccessToken+"_"+nonce)
return res, fmt.Errorf(`unauthorized`)
}
if token != accessToken {
+ p.dependencies.Log.Debug().Msgf("invalid access token: %s, key: %s", err, sessionKey+":"+constants.TokenTypeAccessToken+"_"+nonce)
return res, fmt.Errorf(`unauthorized`)
}
hostname := parsers.GetHost(gc)
- if ok, err := ValidateJWTClaims(res, hostname, nonce, userID); !ok || err != nil {
+ if ok, err := p.ValidateJWTClaims(res, &AuthTokenConfig{
+ HostName: hostname,
+ Nonce: nonce,
+ User: &schemas.User{ID: userID},
+ }); !ok || err != nil {
return res, err
}
@@ -291,36 +291,43 @@ func ValidateAccessToken(gc *gin.Context, accessToken string) (map[string]interf
}
// Function to validate refreshToken
-func ValidateRefreshToken(gc *gin.Context, refreshToken string) (map[string]interface{}, error) {
+func (p *provider) ValidateRefreshToken(gc *gin.Context, refreshToken string) (map[string]interface{}, error) {
res := make(map[string]interface{})
if refreshToken == "" {
return res, fmt.Errorf(`unauthorized`)
}
- res, err := ParseJWTToken(refreshToken)
+ res, err := p.ParseJWTToken(refreshToken)
if err != nil {
return res, err
}
userID := res["sub"].(string)
nonce := res["nonce"].(string)
+
loginMethod := res["login_method"]
sessionKey := userID
if loginMethod != nil && loginMethod != "" {
sessionKey = loginMethod.(string) + ":" + userID
}
- token, err := memorystore.Provider.GetUserSession(sessionKey, constants.TokenTypeRefreshToken+"_"+nonce)
+ token, err := p.dependencies.MemoryStoreProvider.GetUserSession(sessionKey, constants.TokenTypeRefreshToken+"_"+nonce)
if nonce == "" || err != nil {
+ p.dependencies.Log.Debug().Err(err).Msgf("invalid refresh token: %v, key: %s", err, sessionKey+":"+constants.TokenTypeRefreshToken+"_"+nonce)
return res, fmt.Errorf(`unauthorized`)
}
if token != refreshToken {
+ p.dependencies.Log.Debug().Msgf("invalid refresh token: %s, key: %s", err, sessionKey+":"+constants.TokenTypeRefreshToken+"_"+nonce)
return res, fmt.Errorf(`unauthorized`)
}
hostname := parsers.GetHost(gc)
- if ok, err := ValidateJWTClaims(res, hostname, nonce, userID); !ok || err != nil {
+ if ok, err := p.ValidateJWTClaims(res, &AuthTokenConfig{
+ HostName: hostname,
+ Nonce: nonce,
+ User: &schemas.User{ID: userID},
+ }); !ok || err != nil {
return res, err
}
@@ -331,12 +338,12 @@ func ValidateRefreshToken(gc *gin.Context, refreshToken string) (map[string]inte
return res, nil
}
-func ValidateBrowserSession(gc *gin.Context, encryptedSession string) (*SessionData, error) {
+func (p *provider) ValidateBrowserSession(gc *gin.Context, encryptedSession string) (*SessionData, error) {
if encryptedSession == "" {
return nil, fmt.Errorf(`unauthorized`)
}
- decryptedFingerPrint, err := crypto.DecryptAES(encryptedSession)
+ decryptedFingerPrint, err := crypto.DecryptAES(p.config.ClientSecret, encryptedSession)
if err != nil {
return nil, err
}
@@ -351,9 +358,9 @@ func ValidateBrowserSession(gc *gin.Context, encryptedSession string) (*SessionD
if res.LoginMethod != "" {
sessionStoreKey = res.LoginMethod + ":" + res.Subject
}
- token, err := memorystore.Provider.GetUserSession(sessionStoreKey, constants.TokenTypeSessionToken+"_"+res.Nonce)
+ token, err := p.dependencies.MemoryStoreProvider.GetUserSession(sessionStoreKey, constants.TokenTypeSessionToken+"_"+res.Nonce)
if token == "" || err != nil {
- log.Debugf("invalid browser session: %v, key: %s", err, sessionStoreKey+":"+constants.TokenTypeSessionToken+"_"+res.Nonce)
+ p.dependencies.Log.Debug().Err(err).Msgf("invalid session token: %v, key: %s", err, sessionStoreKey+":"+constants.TokenTypeSessionToken+"_"+res.Nonce)
return nil, fmt.Errorf(`unauthorized`)
}
@@ -361,7 +368,7 @@ func ValidateBrowserSession(gc *gin.Context, encryptedSession string) (*SessionD
return nil, fmt.Errorf(`unauthorized: invalid nonce`)
}
- if res.ExpiresAt < time.Now().Unix() {
+ if res.ExpiresAt <= time.Now().Unix() {
return nil, fmt.Errorf(`unauthorized: token expired`)
}
@@ -372,48 +379,35 @@ func ValidateBrowserSession(gc *gin.Context, encryptedSession string) (*SessionD
// user information, roles config and CUSTOM_ACCESS_TOKEN_SCRIPT
// For response_type (code) / authorization_code grant nonce should be empty
// for implicit flow it should be present to verify with actual state
-func CreateIDToken(user *models.User, roles []string, hostname, nonce, atHash, cHash, loginMethod string) (string, int64, error) {
- expireTime, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAccessTokenExpiryTime)
- if err != nil {
- return "", 0, err
- }
- expiryBound, err := utils.ParseDurationInSeconds(expireTime)
+func (p *provider) CreateIDToken(cfg *AuthTokenConfig) (string, int64, error) {
+ expiryBound, err := utils.ParseDurationInSeconds(cfg.ExpireTime)
if err != nil {
expiryBound = time.Minute * 30
}
expiresAt := time.Now().Add(expiryBound).Unix()
- resUser := user.AsAPIUser()
+ resUser := cfg.User.AsAPIUser()
userBytes, _ := json.Marshal(&resUser)
var userMap map[string]interface{}
json.Unmarshal(userBytes, &userMap)
- claimKey, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyJwtRoleClaim)
- if err != nil {
- claimKey = "roles"
- }
-
- clientID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyClientID)
- if err != nil {
- return "", 0, err
- }
customClaims := jwt.MapClaims{
- "iss": hostname,
- "aud": clientID,
- "sub": user.ID,
- "exp": expiresAt,
- "iat": time.Now().Unix(),
- "token_type": constants.TokenTypeIdentityToken,
- "allowed_roles": strings.Split(user.Roles, ","),
- "login_method": loginMethod,
- claimKey: roles,
+ "iss": cfg.HostName,
+ "aud": p.config.ClientID,
+ "sub": cfg.User.ID,
+ "exp": expiresAt,
+ "iat": time.Now().Unix(),
+ "token_type": constants.TokenTypeIdentityToken,
+ "allowed_roles": strings.Split(cfg.User.Roles, ","),
+ "login_method": cfg.LoginMethod,
+ p.config.JWTRoleClaim: cfg.Roles,
}
// split nonce to see if its authorization code grant method
- if cHash != "" {
- customClaims["at_hash"] = atHash
- customClaims["c_hash"] = cHash
+ if cfg.CodeHash != "" {
+ customClaims["at_hash"] = cfg.AtHash
+ customClaims["c_hash"] = cfg.CodeHash
} else {
- customClaims["nonce"] = nonce
- customClaims["at_hash"] = atHash
+ customClaims["nonce"] = cfg.Nonce
+ customClaims["at_hash"] = cfg.Nonce
}
for k, v := range userMap {
if k != "roles" {
@@ -421,12 +415,7 @@ func CreateIDToken(user *models.User, roles []string, hostname, nonce, atHash, c
}
}
// check for the extra access token script
- accessTokenScript, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyCustomAccessTokenScript)
- if err != nil {
- log.Debug("Failed to get custom access token script: ", err)
- accessTokenScript = ""
- }
- if accessTokenScript != "" {
+ if p.config.CustomAccessTokenScript != "" {
vm := otto.New()
claimBytes, _ := json.Marshal(customClaims)
vm.Run(fmt.Sprintf(`
@@ -434,16 +423,16 @@ func CreateIDToken(user *models.User, roles []string, hostname, nonce, atHash, c
var tokenPayload = %s;
var customFunction = %s;
var functionRes = JSON.stringify(customFunction(user, tokenPayload));
- `, string(userBytes), string(claimBytes), accessTokenScript))
+ `, string(userBytes), string(claimBytes), p.config.CustomAccessTokenScript))
val, err := vm.Get("functionRes")
if err != nil {
- log.Debug("error getting custom access token script: ", err)
+ p.dependencies.Log.Debug().Err(err).Msg("error getting custom access token script")
} else {
extraPayload := make(map[string]interface{})
- err = json.Unmarshal([]byte(fmt.Sprintf("%s", val)), &extraPayload)
+ err = json.Unmarshal([]byte(fmt.Sprintf("%v", val)), &extraPayload)
if err != nil {
- log.Debug("error converting accessTokenScript response to map: ", err)
+ p.dependencies.Log.Debug().Err(err).Msg("error converting accessTokenScript response to map")
} else {
for k, v := range extraPayload {
customClaims[k] = v
@@ -452,7 +441,7 @@ func CreateIDToken(user *models.User, roles []string, hostname, nonce, atHash, c
}
}
- token, err := SignJWTToken(customClaims)
+ token, err := p.SignJWTToken(customClaims)
if err != nil {
return "", 0, err
}
@@ -461,7 +450,7 @@ func CreateIDToken(user *models.User, roles []string, hostname, nonce, atHash, c
}
// GetIDToken returns the id token from the request header
-func GetIDToken(gc *gin.Context) (string, error) {
+func (p *provider) GetIDToken(gc *gin.Context) (string, error) {
// try to check in auth header for cookie
auth := gc.Request.Header.Get("Authorization")
if auth == "" {
@@ -489,23 +478,23 @@ type SessionOrAccessTokenData struct {
}
// GetUserIDFromSessionOrAccessToken returns the user id from the session or access token
-func GetUserIDFromSessionOrAccessToken(gc *gin.Context) (*SessionOrAccessTokenData, error) {
+func (p *provider) GetUserIDFromSessionOrAccessToken(gc *gin.Context) (*SessionOrAccessTokenData, error) {
// First try to get the user id from the session
isSession := true
token, err := cookie.GetSession(gc)
if err != nil || token == "" {
- log.Debug("Failed to get session token: ", err)
+ p.dependencies.Log.Debug().Err(err).Msg("Failed to get session token")
isSession = false
- token, err = GetAccessToken(gc)
+ token, err = p.GetAccessToken(gc)
if err != nil || token == "" {
- log.Debug("Failed to get access token: ", err)
+ p.dependencies.Log.Debug().Err(err).Msg("Failed to get access token")
return nil, fmt.Errorf(`unauthorized`)
}
}
if isSession {
- claims, err := ValidateBrowserSession(gc, token)
+ claims, err := p.ValidateBrowserSession(gc, token)
if err != nil {
- log.Debug("Failed to validate session token: ", err)
+ p.dependencies.Log.Debug().Err(err).Msg("Failed to validate session token")
return nil, fmt.Errorf(`unauthorized`)
}
return &SessionOrAccessTokenData{
@@ -515,9 +504,9 @@ func GetUserIDFromSessionOrAccessToken(gc *gin.Context) (*SessionOrAccessTokenDa
}, nil
}
// If not session, then validate the access token
- claims, err := ValidateAccessToken(gc, token)
+ claims, err := p.ValidateAccessToken(gc, token)
if err != nil {
- log.Debug("Failed to validate access token: ", err)
+ p.dependencies.Log.Debug().Err(err).Msg("Failed to validate access token")
return nil, fmt.Errorf(`unauthorized`)
}
return &SessionOrAccessTokenData{
diff --git a/internal/token/jwt.go b/internal/token/jwt.go
new file mode 100644
index 000000000..ad869fd3c
--- /dev/null
+++ b/internal/token/jwt.go
@@ -0,0 +1,125 @@
+package token
+
+import (
+ "errors"
+
+ "github.com/golang-jwt/jwt/v4"
+
+ "github.com/authorizerdev/authorizer/internal/crypto"
+ "github.com/authorizerdev/authorizer/internal/refs"
+)
+
+// SignJWTToken common util to sing jwt token
+func (p *provider) SignJWTToken(jwtclaims jwt.MapClaims) (string, error) {
+ signingMethod := jwt.GetSigningMethod(p.config.JWTType)
+ if signingMethod == nil {
+ return "", errors.New("unsupported signing method")
+ }
+ t := jwt.New(signingMethod)
+ if t == nil {
+ return "", errors.New("unsupported signing method")
+ }
+ t.Claims = jwtclaims
+
+ switch signingMethod {
+ case jwt.SigningMethodHS256, jwt.SigningMethodHS384, jwt.SigningMethodHS512:
+ return t.SignedString([]byte(p.config.JWTSecret))
+ case jwt.SigningMethodRS256, jwt.SigningMethodRS384, jwt.SigningMethodRS512:
+ key, err := crypto.ParseRsaPrivateKeyFromPemStr(p.config.JWTPublicKey)
+ if err != nil {
+ return "", err
+ }
+ return t.SignedString(key)
+ case jwt.SigningMethodES256, jwt.SigningMethodES384, jwt.SigningMethodES512:
+ key, err := crypto.ParseEcdsaPrivateKeyFromPemStr(p.config.JWTPrivateKey)
+ if err != nil {
+ return "", err
+ }
+
+ return t.SignedString(key)
+ default:
+ return "", errors.New("unsupported signing method")
+ }
+}
+
+// ParseJWTToken common util to parse jwt token
+func (p *provider) ParseJWTToken(token string) (jwt.MapClaims, error) {
+ signingMethod := jwt.GetSigningMethod(p.config.JWTType)
+
+ var claims jwt.MapClaims
+ var err error
+ switch signingMethod {
+ case jwt.SigningMethodHS256, jwt.SigningMethodHS384, jwt.SigningMethodHS512:
+ _, err = jwt.ParseWithClaims(token, &claims, func(token *jwt.Token) (interface{}, error) {
+ return []byte(p.config.JWTSecret), nil
+ })
+ case jwt.SigningMethodRS256, jwt.SigningMethodRS384, jwt.SigningMethodRS512:
+ _, err = jwt.ParseWithClaims(token, &claims, func(token *jwt.Token) (interface{}, error) {
+ key, err := crypto.ParseRsaPublicKeyFromPemStr(p.config.JWTPublicKey)
+ if err != nil {
+ return nil, err
+ }
+ return key, nil
+ })
+ case jwt.SigningMethodES256, jwt.SigningMethodES384, jwt.SigningMethodES512:
+ _, err = jwt.ParseWithClaims(token, &claims, func(token *jwt.Token) (interface{}, error) {
+ key, err := crypto.ParseEcdsaPublicKeyFromPemStr(p.config.JWTSecret)
+ if err != nil {
+ return nil, err
+ }
+ return key, nil
+ })
+ default:
+ err = errors.New("unsupported signing method")
+ }
+ if err != nil {
+ return claims, err
+ }
+
+ // claim parses exp & iat into float 64 with e^10,
+ // but we expect it to be int64
+ // hence we need to assert interface and convert to int64
+ intExp := int64(claims["exp"].(float64))
+ intIat := int64(claims["iat"].(float64))
+ claims["exp"] = intExp
+ claims["iat"] = intIat
+
+ return claims, nil
+}
+
+// ValidateJWTClaims common util to validate claims
+func (p *provider) ValidateJWTClaims(claims jwt.MapClaims, authTokenConfig *AuthTokenConfig) (bool, error) {
+ if claims["aud"] != p.config.ClientID {
+ return false, errors.New("invalid audience")
+ }
+
+ if claims["nonce"] != authTokenConfig.Nonce {
+ return false, errors.New("invalid nonce")
+ }
+
+ if claims["iss"] != authTokenConfig.HostName {
+ return false, errors.New("invalid issuer")
+ }
+
+ if claims["sub"] != authTokenConfig.User.ID && claims["sub"] != refs.StringValue(authTokenConfig.User.Email) {
+ return false, errors.New("invalid subject")
+ }
+
+ return true, nil
+}
+
+// ValidateJWTTokenWithoutNonce common util to validate claims without nonce
+func (p *provider) ValidateJWTTokenWithoutNonce(claims jwt.MapClaims, authTokenConfig *AuthTokenConfig) (bool, error) {
+ if claims["aud"] != p.config.ClientID {
+ return false, errors.New("invalid audience")
+ }
+
+ if claims["iss"] != authTokenConfig.HostName {
+ return false, errors.New("invalid issuer")
+ }
+
+ if claims["sub"] != authTokenConfig.User.ID {
+ return false, errors.New("invalid subject")
+ }
+ return true, nil
+}
diff --git a/internal/token/provider.go b/internal/token/provider.go
new file mode 100644
index 000000000..f6fa29f08
--- /dev/null
+++ b/internal/token/provider.go
@@ -0,0 +1,95 @@
+package token
+
+import (
+ "fmt"
+
+ "github.com/gin-gonic/gin"
+ "github.com/golang-jwt/jwt/v4"
+ "github.com/rs/zerolog"
+
+ "github.com/authorizerdev/authorizer/internal/config"
+ "github.com/authorizerdev/authorizer/internal/memory_store"
+)
+
+// Dependencies struct for twilio provider
+type Dependencies struct {
+ Log *zerolog.Logger
+ MemoryStoreProvider memory_store.Provider
+}
+
+type provider struct {
+ config *config.Config
+ dependencies *Dependencies
+}
+
+var _ Provider = &provider{}
+
+// Provider interface for token provider
+type Provider interface {
+ // CreateAccessToken creates an access token
+ CreateAccessToken(cfg *AuthTokenConfig) (string, int64, error)
+ // CreateAuthToken creates all types of auth token
+ CreateAuthToken(gc *gin.Context, cfg *AuthTokenConfig) (*AuthToken, error)
+ // CreateIDToken creates an id token
+ CreateIDToken(cfg *AuthTokenConfig) (string, int64, error)
+ // CreateRefreshToken creates a refresh token
+ CreateRefreshToken(cfg *AuthTokenConfig) (string, int64, error)
+ // CreateSessionToken creates a session token
+ CreateSessionToken(cfg *AuthTokenConfig) (*SessionData, string, int64, error)
+ // CreateVerificationToken creates a verification token
+ CreateVerificationToken(authTokenConfig *AuthTokenConfig, redirectURL string, tokenType string) (string, error)
+ // GetAd
+ GetAdminAuthToken(gc *gin.Context) (string, error)
+ // GetAccessToken gets access token from request
+ GetAccessToken(gc *gin.Context) (string, error)
+ // GetIDToken gets id token from request
+ GetIDToken(gc *gin.Context) (string, error)
+ // GetUserIDFromSessionOrAccessToken gets user id from session or access token
+ GetUserIDFromSessionOrAccessToken(gc *gin.Context) (*SessionOrAccessTokenData, error)
+ // IsSuperAdmin checks if user is super admin
+ IsSuperAdmin(gc *gin.Context) bool
+ // ParseJWTToken parses jwt token
+ ParseJWTToken(token string) (jwt.MapClaims, error)
+ // SignJWTToken signs jwt token
+ SignJWTToken(jwtclaims jwt.MapClaims) (string, error)
+ // ValidateAccessToken validates access token
+ ValidateAccessToken(gc *gin.Context, accessToken string) (map[string]interface{}, error)
+ // ValidateAdminToken validates session token
+ ValidateBrowserSession(gc *gin.Context, encryptedSession string) (*SessionData, error)
+ // ValidateJWTClaims validates jwt claims
+ ValidateJWTClaims(claims jwt.MapClaims, authTokenConfig *AuthTokenConfig) (bool, error)
+ // ValidateJWTTokenWithoutNonce validates jwt token without nonce
+ ValidateJWTTokenWithoutNonce(claims jwt.MapClaims, authTokenConfig *AuthTokenConfig) (bool, error)
+ // ValidateRefreshToken validates refresh token
+ ValidateRefreshToken(gc *gin.Context, refreshToken string) (map[string]interface{}, error)
+}
+
+// New returns a new token provider
+func New(cfg *config.Config, deps *Dependencies) (Provider, error) {
+ if cfg.JWTType == "" {
+ deps.Log.Debug().Msg("missing jwt type")
+ return nil, fmt.Errorf("missing jwt type")
+ }
+ signingMethod := jwt.GetSigningMethod(cfg.JWTType)
+ switch signingMethod {
+ case jwt.SigningMethodHS256, jwt.SigningMethodHS384, jwt.SigningMethodHS512:
+ if cfg.JWTSecret == "" {
+ deps.Log.Debug().Msg("missing jwt secret")
+ return nil, fmt.Errorf("missing jwt secret")
+ }
+ case jwt.SigningMethodRS256, jwt.SigningMethodRS384, jwt.SigningMethodRS512,
+ jwt.SigningMethodES256, jwt.SigningMethodES384, jwt.SigningMethodES512:
+ if cfg.JWTPrivateKey == "" {
+ deps.Log.Debug().Msg("missing jwt private key")
+ return nil, fmt.Errorf("missing jwt private key")
+ }
+ if cfg.JWTPublicKey == "" {
+ deps.Log.Debug().Msg("missing jwt public key")
+ return nil, fmt.Errorf("missing jwt public key")
+ }
+ }
+ return &provider{
+ config: cfg,
+ dependencies: deps,
+ }, nil
+}
diff --git a/internal/token/verification_token.go b/internal/token/verification_token.go
new file mode 100644
index 000000000..54f737c9e
--- /dev/null
+++ b/internal/token/verification_token.go
@@ -0,0 +1,23 @@
+package token
+
+import (
+ "time"
+
+ "github.com/golang-jwt/jwt/v4"
+)
+
+// CreateVerificationToken creates a verification JWT token
+func (p *provider) CreateVerificationToken(authTokenConfig *AuthTokenConfig, redirectURL, tokenType string) (string, error) {
+ claims := jwt.MapClaims{
+ "iss": authTokenConfig.HostName,
+ "aud": p.config.ClientID,
+ "sub": authTokenConfig.User.Email,
+ "exp": time.Now().Add(time.Minute * 30).Unix(),
+ "iat": time.Now().Unix(),
+ "token_type": tokenType,
+ "nonce": authTokenConfig.Nonce,
+ "redirect_uri": redirectURL,
+ }
+
+ return p.SignJWTToken(claims)
+}
diff --git a/server/tools.go b/internal/tools.go
similarity index 100%
rename from server/tools.go
rename to internal/tools.go
diff --git a/server/types/interface_slice.go b/internal/types/interface_slice.go
similarity index 100%
rename from server/types/interface_slice.go
rename to internal/types/interface_slice.go
diff --git a/server/utils/common.go b/internal/utils/common.go
similarity index 88%
rename from server/utils/common.go
rename to internal/utils/common.go
index b5f81b6ca..c0602a7d8 100644
--- a/server/utils/common.go
+++ b/internal/utils/common.go
@@ -3,8 +3,7 @@ package utils
import (
"reflect"
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/memorystore"
+ "github.com/authorizerdev/authorizer/internal/config"
)
// StringSliceContains checks if a string slice contains a particular string
@@ -63,15 +62,9 @@ func ConvertInterfaceToStringSlice(slice interface{}) []string {
}
// GetOrganization to get organization object
-func GetOrganization() map[string]interface{} {
- orgLogo, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyOrganizationLogo)
- if err != nil {
- return nil
- }
- orgName, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyOrganizationName)
- if err != nil {
- return nil
- }
+func GetOrganization(cfg *config.Config) map[string]interface{} {
+ orgLogo := cfg.OrganizationLogo
+ orgName := cfg.OrganizationName
organization := map[string]interface{}{
"name": orgName,
"logo": orgLogo,
diff --git a/server/utils/file.go b/internal/utils/file.go
similarity index 100%
rename from server/utils/file.go
rename to internal/utils/file.go
diff --git a/server/utils/generate_otp.go b/internal/utils/generate_otp.go
similarity index 100%
rename from server/utils/generate_otp.go
rename to internal/utils/generate_otp.go
diff --git a/server/utils/generate_totp_recovery_code.go b/internal/utils/generate_totp_recovery_code.go
similarity index 100%
rename from server/utils/generate_totp_recovery_code.go
rename to internal/utils/generate_totp_recovery_code.go
diff --git a/server/utils/gin_context.go b/internal/utils/gin_context.go
similarity index 100%
rename from server/utils/gin_context.go
rename to internal/utils/gin_context.go
diff --git a/server/utils/nonce.go b/internal/utils/nonce.go
similarity index 51%
rename from server/utils/nonce.go
rename to internal/utils/nonce.go
index 311b3259f..6cffa1e10 100644
--- a/server/utils/nonce.go
+++ b/internal/utils/nonce.go
@@ -3,32 +3,26 @@ package utils
import (
"github.com/google/uuid"
- "github.com/authorizerdev/authorizer/server/crypto"
+ "github.com/authorizerdev/authorizer/internal/crypto"
)
-// GenerateNonce generats random nonce string and returns
+// GenerateNonce generates random nonce string and returns
// the nonce string, nonce hash, error
func GenerateNonce() (string, string, error) {
nonce := uuid.New().String()
- nonceHash, err := crypto.EncryptAES(nonce)
- if err != nil {
- return "", "", err
- }
- return nonce, nonceHash, err
+ nonceHash := crypto.EncryptB64(nonce)
+ return nonce, nonceHash, nil
}
// EncryptNonce nonce string
func EncryptNonce(nonce string) (string, error) {
- nonceHash, err := crypto.EncryptAES(nonce)
- if err != nil {
- return "", err
- }
- return nonceHash, err
+ nonceHash := crypto.EncryptB64(nonce)
+ return nonceHash, nil
}
// DecryptNonce nonce string
func DecryptNonce(nonceHash string) (string, error) {
- nonce, err := crypto.DecryptAES(nonceHash)
+ nonce, err := crypto.DecryptB64(nonceHash)
if err != nil {
return "", err
}
diff --git a/server/utils/pagination.go b/internal/utils/pagination.go
similarity index 74%
rename from server/utils/pagination.go
rename to internal/utils/pagination.go
index 384eebdb8..35aba6b0b 100644
--- a/server/utils/pagination.go
+++ b/internal/utils/pagination.go
@@ -1,13 +1,13 @@
package utils
import (
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/graph/model"
+ "github.com/authorizerdev/authorizer/internal/constants"
+ "github.com/authorizerdev/authorizer/internal/graph/model"
)
// GetPagination helps getting pagination data from paginated input
// also returns default limit and offset if pagination data is not present
-func GetPagination(paginatedInput *model.PaginatedInput) *model.Pagination {
+func GetPagination(paginatedInput *model.PaginatedRequest) *model.Pagination {
limit := int64(constants.DefaultLimit)
page := int64(1)
if paginatedInput != nil && paginatedInput.Pagination != nil {
diff --git a/server/utils/parser.go b/internal/utils/parser.go
similarity index 100%
rename from server/utils/parser.go
rename to internal/utils/parser.go
diff --git a/server/utils/pkce.go b/internal/utils/pkce.go
similarity index 100%
rename from server/utils/pkce.go
rename to internal/utils/pkce.go
diff --git a/server/utils/request_info.go b/internal/utils/request_info.go
similarity index 100%
rename from server/utils/request_info.go
rename to internal/utils/request_info.go
diff --git a/server/utils/response.go b/internal/utils/response.go
similarity index 100%
rename from server/utils/response.go
rename to internal/utils/response.go
diff --git a/server/validators/common.go b/internal/validators/common.go
similarity index 100%
rename from server/validators/common.go
rename to internal/validators/common.go
diff --git a/server/validators/email.go b/internal/validators/email.go
similarity index 100%
rename from server/validators/email.go
rename to internal/validators/email.go
diff --git a/server/validators/email_template.go b/internal/validators/email_template.go
similarity index 89%
rename from server/validators/email_template.go
rename to internal/validators/email_template.go
index 7b5469b60..0634b0eb9 100644
--- a/server/validators/email_template.go
+++ b/internal/validators/email_template.go
@@ -1,6 +1,6 @@
package validators
-import "github.com/authorizerdev/authorizer/server/constants"
+import "github.com/authorizerdev/authorizer/internal/constants"
// IsValidEmailTemplateEventName function to validate email template events
func IsValidEmailTemplateEventName(eventName string) bool {
diff --git a/server/validators/password.go b/internal/validators/password.go
similarity index 72%
rename from server/validators/password.go
rename to internal/validators/password.go
index 282dd7596..217993e6e 100644
--- a/server/validators/password.go
+++ b/internal/validators/password.go
@@ -2,9 +2,6 @@ package validators
import (
"errors"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/memorystore"
)
// ValidatePassword to validate the password against the following policy
@@ -14,18 +11,11 @@ import (
// at least one lower case letter
// at least one digit
// at least one special character
-func IsValidPassword(password string) error {
+func IsValidPassword(password string, isStrongPasswordDisabled bool) error {
if len(password) < 6 || len(password) > 36 {
return errors.New("password must be of minimum 6 characters and maximum 36 characters")
}
- // if strong password is disabled
- // just check for min 6 chars & max 36
- isStrongPasswordDisabled, _ := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableStrongPassword)
- if isStrongPasswordDisabled {
- return nil
- }
-
hasUpperCase := false
hasLowerCase := false
hasDigit := false
diff --git a/server/validators/roles.go b/internal/validators/roles.go
similarity index 81%
rename from server/validators/roles.go
rename to internal/validators/roles.go
index 9a43a51bb..8a2a3b484 100644
--- a/server/validators/roles.go
+++ b/internal/validators/roles.go
@@ -1,6 +1,6 @@
package validators
-import "github.com/authorizerdev/authorizer/server/utils"
+import "github.com/authorizerdev/authorizer/internal/utils"
// IsValidRoles validates roles
func IsValidRoles(userRoles []string, roles []string) bool {
diff --git a/server/validators/url.go b/internal/validators/url.go
similarity index 68%
rename from server/validators/url.go
rename to internal/validators/url.go
index 6f8a15fe3..505f3fedd 100644
--- a/server/validators/url.go
+++ b/internal/validators/url.go
@@ -4,19 +4,14 @@ import (
"regexp"
"strings"
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/parsers"
+ "github.com/authorizerdev/authorizer/internal/parsers"
)
// IsValidOrigin validates origin based on ALLOWED_ORIGINS
-func IsValidOrigin(url string) bool {
- allowedOriginsString, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAllowedOrigins)
- allowedOrigins := []string{}
- if err != nil {
+func IsValidOrigin(url string, allowedOriginsConfig []string) bool {
+ allowedOrigins := allowedOriginsConfig
+ if len(allowedOrigins) == 0 {
allowedOrigins = []string{"*"}
- } else {
- allowedOrigins = strings.Split(allowedOriginsString, ",")
}
if len(allowedOrigins) == 1 && allowedOrigins[0] == "*" {
return true
diff --git a/server/validators/verification_requests.go b/internal/validators/verification_requests.go
similarity index 86%
rename from server/validators/verification_requests.go
rename to internal/validators/verification_requests.go
index 48c918350..17a64fd8b 100644
--- a/server/validators/verification_requests.go
+++ b/internal/validators/verification_requests.go
@@ -1,6 +1,6 @@
package validators
-import "github.com/authorizerdev/authorizer/server/constants"
+import "github.com/authorizerdev/authorizer/internal/constants"
// IsValidVerificationIdentifier validates verification identifier that is used to identify
// the type of verification request
diff --git a/server/validators/webhook.go b/internal/validators/webhook.go
similarity index 89%
rename from server/validators/webhook.go
rename to internal/validators/webhook.go
index eb2476bc3..b8c920ab1 100644
--- a/server/validators/webhook.go
+++ b/internal/validators/webhook.go
@@ -1,6 +1,6 @@
package validators
-import "github.com/authorizerdev/authorizer/server/constants"
+import "github.com/authorizerdev/authorizer/internal/constants"
// IsValidWebhookEventName to validate webhook event name
func IsValidWebhookEventName(eventName string) bool {
diff --git a/main.go b/main.go
new file mode 100644
index 000000000..161807851
--- /dev/null
+++ b/main.go
@@ -0,0 +1,7 @@
+package main
+
+import "github.com/authorizerdev/authorizer/cmd"
+
+func main() {
+ cmd.RootCmd.Execute()
+}
diff --git a/scripts/build-mac.sh b/scripts/build-mac.sh
deleted file mode 100644
index e41d5298e..000000000
--- a/scripts/build-mac.sh
+++ /dev/null
@@ -1,18 +0,0 @@
-VERSION="$1"
-make clean && make build-app && CGO_ENABLED=1 VERSION=${VERSION} make
-FILE_NAME=authorizer-${VERSION}-darwin-amd64.tar.gz
-tar cvfz ${FILE_NAME} .env app/build build templates dashboard/build
-AUTH="Authorization: token $GITHUB_TOKEN"
-RELASE_INFO=$(curl -sH "$AUTH" https://api.github.com/repos/authorizerdev/authorizer/releases/tags/${VERSION})
-echo $RELASE_INFO
-
-eval $(echo "$RELASE_INFO" | grep -m 1 "id.:" | grep -w id | tr : = | tr -cd '[[:alnum:]]=')
-[ "$id" ] || { echo "Error: Failed to get release id for tag: $VERSION"; echo "$RELASE_INFO" | awk 'length($0)<100' >&2; exit 1; }
-echo $id
-GH_ASSET="https://uploads.github.com/repos/authorizerdev/authorizer/releases/$id/assets?name=$(basename $FILE_NAME)"
-
-echo $GH_ASSET
-
-curl -H $AUTH -H "Content-Type: $(file -b --mime-type $FILE_NAME)" --data-binary @$FILE_NAME $GH_ASSET
-
-curl "$GITHUB_OAUTH_BASIC" --data-binary @"$FILE_NAME" -H "Authorization: token $GITHUB_TOKEN" -H "Content-Type: application/octet-stream" $GH_ASSET
diff --git a/server/authenticators/providers/providers.go b/server/authenticators/providers/providers.go
deleted file mode 100644
index 7f43ef5c7..000000000
--- a/server/authenticators/providers/providers.go
+++ /dev/null
@@ -1,25 +0,0 @@
-package providers
-
-import "context"
-
-// AuthenticatorConfig defines authenticator config
-type AuthenticatorConfig struct {
- // ScannerImage is the base64 of QR code image
- ScannerImage string
- // Secrets is the secret key
- Secret string
- // RecoveryCode is the list of recovery codes
- RecoveryCodes []string
- // RecoveryCodeMap is the map of recovery codes
- RecoveryCodeMap map[string]bool
-}
-
-// Provider defines authenticators provider
-type Provider interface {
- // Generate totp: to generate totp, store secret into db and returns base64 of QR code image
- Generate(ctx context.Context, id string) (*AuthenticatorConfig, error)
- // Validate totp: user passcode with secret stored in our db
- Validate(ctx context.Context, passcode string, userID string) (bool, error)
- // ValidateRecoveryCode totp: allows user to validate using recovery code incase if they lost their device
- ValidateRecoveryCode(ctx context.Context, recoveryCode, userID string) (bool, error)
-}
diff --git a/server/authenticators/providers/totp/provider.go b/server/authenticators/providers/totp/provider.go
deleted file mode 100644
index f3bd9da3b..000000000
--- a/server/authenticators/providers/totp/provider.go
+++ /dev/null
@@ -1,23 +0,0 @@
-package totp
-
-import (
- "context"
-)
-
-type provider struct {
- ctx context.Context
-}
-
-// TOTPConfig defines totp config
-type TOTPConfig struct {
- ScannerImage string
- Secret string
-}
-
-// NewProvider returns a new totp provider
-func NewProvider() (*provider, error) {
- ctx := context.Background()
- return &provider{
- ctx: ctx,
- }, nil
-}
diff --git a/server/authenticators/totp_store.go b/server/authenticators/totp_store.go
deleted file mode 100644
index 268e66eb7..000000000
--- a/server/authenticators/totp_store.go
+++ /dev/null
@@ -1,26 +0,0 @@
-package authenticators
-
-import (
- "github.com/authorizerdev/authorizer/server/authenticators/providers"
- "github.com/authorizerdev/authorizer/server/authenticators/providers/totp"
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/memorystore"
-)
-
-// Provider is the global authenticators provider.
-var Provider providers.Provider
-
-// InitTOTPStore initializes the TOTP authenticator store if it's not disabled in the environment variables.
-// It sets the global Provider variable to a new TOTP provider.
-func InitTOTPStore() error {
- var err error
- isTOTPEnvServiceDisabled, _ := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableTOTPLogin)
-
- if !isTOTPEnvServiceDisabled {
- Provider, err = totp.NewProvider()
- if err != nil {
- return err
- }
- }
- return nil
-}
diff --git a/server/constants/env.go b/server/constants/env.go
deleted file mode 100644
index 983a87fe6..000000000
--- a/server/constants/env.go
+++ /dev/null
@@ -1,215 +0,0 @@
-package constants
-
-var VERSION = "0.0.1"
-
-const (
- // TestEnv is used for testing
- TestEnv = "test"
- // EnvKeyEnv key for env variable ENV
- EnvKeyEnv = "ENV"
- // EnvKeyEnvPath key for cli arg variable ENV_PATH
- EnvKeyEnvPath = "ENV_PATH"
- // EnvKeyAuthorizerURL key for env variable AUTHORIZER_URL
- EnvKeyAuthorizerURL = "AUTHORIZER_URL"
- // EnvKeyPort key for env variable PORT
- EnvKeyPort = "PORT"
- // EnvKeyAccessTokenExpiryTime key for env variable ACCESS_TOKEN_EXPIRY_TIME
- EnvKeyAccessTokenExpiryTime = "ACCESS_TOKEN_EXPIRY_TIME"
- // EnvKeyAdminSecret key for env variable ADMIN_SECRET
- EnvKeyAdminSecret = "ADMIN_SECRET"
- // EnvKeyDatabaseType key for env variable DATABASE_TYPE
- 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
- EnvKeyDatabaseUsername = "DATABASE_USERNAME"
- // EnvKeyDatabasePassword key for env variable DATABASE_PASSWORD
- EnvKeyDatabasePassword = "DATABASE_PASSWORD"
- // EnvKeyDatabasePort key for env variable DATABASE_PORT
- EnvKeyDatabasePort = "DATABASE_PORT"
- // EnvKeyDatabaseHost key for env variable DATABASE_HOST
- EnvKeyDatabaseHost = "DATABASE_HOST"
- // EnvKeyDatabaseCert key for env variable DATABASE_CERT
- EnvKeyDatabaseCert = "DATABASE_CERT"
- // EnvKeyDatabaseCertKey key for env variable DATABASE_KEY
- EnvKeyDatabaseCertKey = "DATABASE_CERT_KEY"
- // EnvKeyDatabaseCACert key for env variable DATABASE_CA_CERT
- EnvKeyDatabaseCACert = "DATABASE_CA_CERT"
- // EnvCouchbaseBucket key for env variable COUCHBASE_BUCKET
- EnvCouchbaseBucket = "COUCHBASE_BUCKET"
- // EnvCouchbaseBucketRAMQuotaMB key for env variable COUCHBASE_BUCKET_RAM_QUOTA
- // This value should be parsed as number
- EnvCouchbaseBucketRAMQuotaMB = "COUCHBASE_BUCKET_RAM_QUOTA"
- // EnvCouchbaseBucket key for env variable COUCHBASE_SCOPE
- EnvCouchbaseScope = "COUCHBASE_SCOPE"
- // EnvKeySmtpHost key for env variable SMTP_HOST
- EnvKeySmtpHost = "SMTP_HOST"
- // EnvKeySmtpPort key for env variable SMTP_PORT
- EnvKeySmtpPort = "SMTP_PORT"
- // EnvKeySmtpUsername key for env variable SMTP_USERNAME
- 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"
- // EnvKeySenderName key for env variable SENDER_NAME
- EnvKeySenderName = "SENDER_NAME"
- // EnvKeyIsEmailServiceEnabled key for env variable IS_EMAIL_SERVICE_ENABLED
- EnvKeyIsEmailServiceEnabled = "IS_EMAIL_SERVICE_ENABLED"
- // EnvKeyIsSMSServiceEnabled key for env variable IS_SMS_SERVICE_ENABLED
- EnvKeyIsSMSServiceEnabled = "IS_SMS_SERVICE_ENABLED"
- // EnvKeyAppCookieSecure key for env variable APP_COOKIE_SECURE
- EnvKeyAppCookieSecure = "APP_COOKIE_SECURE"
- // EnvKeyAdminCookieSecure key for env variable ADMIN_COOKIE_SECURE
- EnvKeyAdminCookieSecure = "ADMIN_COOKIE_SECURE"
- // EnvKeyJwtType key for env variable JWT_TYPE
- EnvKeyJwtType = "JWT_TYPE"
- // EnvKeyJwtSecret key for env variable JWT_SECRET
- EnvKeyJwtSecret = "JWT_SECRET"
- // EnvKeyJwtPrivateKey key for env variable JWT_PRIVATE_KEY
- EnvKeyJwtPrivateKey = "JWT_PRIVATE_KEY"
- // EnvKeyJwtPublicKey key for env variable JWT_PUBLIC_KEY
- EnvKeyJwtPublicKey = "JWT_PUBLIC_KEY"
- // EnvKeyAppURL key for env variable APP_URL
- EnvKeyAppURL = "APP_URL"
- // EnvKeyRedisURL key for env variable REDIS_URL
- EnvKeyRedisURL = "REDIS_URL"
- // EnvKeyResetPasswordURL key for env variable RESET_PASSWORD_URL
- EnvKeyResetPasswordURL = "RESET_PASSWORD_URL"
- // EnvKeyJwtRoleClaim key for env variable JWT_ROLE_CLAIM
- EnvKeyJwtRoleClaim = "JWT_ROLE_CLAIM"
- // EnvKeyGoogleClientID key for env variable GOOGLE_CLIENT_ID
- EnvKeyGoogleClientID = "GOOGLE_CLIENT_ID"
- // EnvKeyGoogleClientSecret key for env variable GOOGLE_CLIENT_SECRET
- EnvKeyGoogleClientSecret = "GOOGLE_CLIENT_SECRET"
- // EnvKeyGithubClientID key for env variable GITHUB_CLIENT_ID
- EnvKeyGithubClientID = "GITHUB_CLIENT_ID"
- // EnvKeyGithubClientSecret key for env variable GITHUB_CLIENT_SECRET
- EnvKeyGithubClientSecret = "GITHUB_CLIENT_SECRET"
- // EnvKeyFacebookClientID key for env variable FACEBOOK_CLIENT_ID
- EnvKeyFacebookClientID = "FACEBOOK_CLIENT_ID"
- // EnvKeyFacebookClientSecret key for env variable FACEBOOK_CLIENT_SECRET
- EnvKeyFacebookClientSecret = "FACEBOOK_CLIENT_SECRET"
- // EnvKeyLinkedinClientID key for env variable LINKEDIN_CLIENT_ID
- EnvKeyLinkedInClientID = "LINKEDIN_CLIENT_ID"
- // EnvKeyLinkedinClientSecret key for env variable LINKEDIN_CLIENT_SECRET
- EnvKeyLinkedInClientSecret = "LINKEDIN_CLIENT_SECRET"
- // EnvKeyAppleClientID key for env variable APPLE_CLIENT_ID
- EnvKeyAppleClientID = "APPLE_CLIENT_ID"
- // EnvKeyAppleClientSecret key for env variable APPLE_CLIENT_SECRET
- EnvKeyAppleClientSecret = "APPLE_CLIENT_SECRET"
- // EnvKeyDiscordClientID key for env variable DISCORD_CLIENT_ID
- EnvKeyDiscordClientID = "DISCORD_CLIENT_ID"
- // EnvKeyDiscordClientSecret key for env variable DISCORD_CLIENT_SECRET
- EnvKeyDiscordClientSecret = "DISCORD_CLIENT_SECRET"
- // EnvKeyTwitterClientID key for env variable TWITTER_CLIENT_ID
- EnvKeyTwitterClientID = "TWITTER_CLIENT_ID"
- // EnvKeyTwitterClientSecret key for env variable TWITTER_CLIENT_SECRET
- EnvKeyTwitterClientSecret = "TWITTER_CLIENT_SECRET"
- // EnvKeyMicrosoftClientID key for env variable MICROSOFT_CLIENT_ID
- EnvKeyMicrosoftClientID = "MICROSOFT_CLIENT_ID"
- // EnvKeyMicrosoftActiveDirectoryTenantID key for env variable MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID
- EnvKeyMicrosoftActiveDirectoryTenantID = "MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID"
- // EnvKeyMicrosoftClientSecret key for env variable MICROSOFT_CLIENT_SECRET
- EnvKeyMicrosoftClientSecret = "MICROSOFT_CLIENT_SECRET"
- // EnvKeyTwitchClientID key for env variable TWITCH_CLIENT_ID
- EnvKeyTwitchClientID = "TWITCH_CLIENT_ID"
- // EnvKeyTwitchClientSecret key for env variable TWITCH_CLIENT_SECRET
- EnvKeyTwitchClientSecret = "TWITCH_CLIENT_SECRET"
- // EnvKeyRobloxClientID key for env variable ROBLOX_CLIENT_ID
- EnvKeyRobloxClientID = "ROBLOX_CLIENT_ID"
- // EnvKeyRobloxClientSecret key for env variable ROBLOX_CLIENT_SECRET
- EnvKeyRobloxClientSecret = "ROBLOX_CLIENT_SECRET"
- // EnvKeyOrganizationName key for env variable ORGANIZATION_NAME
- EnvKeyOrganizationName = "ORGANIZATION_NAME"
- // EnvKeyOrganizationLogo key for env variable ORGANIZATION_LOGO
- EnvKeyOrganizationLogo = "ORGANIZATION_LOGO"
- // EnvKeyCustomAccessTokenScript key for env variable CUSTOM_ACCESS_TOKEN_SCRIPT
- EnvKeyCustomAccessTokenScript = "CUSTOM_ACCESS_TOKEN_SCRIPT"
-
- // Not Exposed Keys
- // EnvKeyClientID key for env variable CLIENT_ID
- EnvKeyClientID = "CLIENT_ID"
- // EnvKeyClientSecret key for env variable CLIENT_SECRET
- EnvKeyClientSecret = "CLIENT_SECRET"
- // EnvKeyEncryptionKey key for env variable ENCRYPTION_KEY
- EnvKeyEncryptionKey = "ENCRYPTION_KEY"
- // EnvKeyJWK key for env variable JWK
- EnvKeyJWK = "JWK"
-
- // Boolean variables
- // EnvKeyIsProd key for env variable IS_PROD
- EnvKeyIsProd = "IS_PROD"
- // EnvKeyDisableEmailVerification key for env variable DISABLE_EMAIL_VERIFICATION
- EnvKeyDisableEmailVerification = "DISABLE_EMAIL_VERIFICATION"
- // EnvKeyDisableBasicAuthentication key for env variable DISABLE_BASIC_AUTH
- EnvKeyDisableBasicAuthentication = "DISABLE_BASIC_AUTHENTICATION"
- // EnvKeyDisableBasicAuthentication key for env variable DISABLE_MOBILE_BASIC_AUTH
- EnvKeyDisableMobileBasicAuthentication = "DISABLE_MOBILE_BASIC_AUTHENTICATION"
- // EnvKeyDisableMagicLinkLogin key for env variable DISABLE_MAGIC_LINK_LOGIN
- EnvKeyDisableMagicLinkLogin = "DISABLE_MAGIC_LINK_LOGIN"
- // EnvKeyDisableLoginPage key for env variable DISABLE_LOGIN_PAGE
- EnvKeyDisableLoginPage = "DISABLE_LOGIN_PAGE"
- // EnvKeyDisableSignUp key for env variable DISABLE_SIGN_UP
- EnvKeyDisableSignUp = "DISABLE_SIGN_UP"
- // EnvKeyDisableRedisForEnv key for env variable DISABLE_REDIS_FOR_ENV
- EnvKeyDisableRedisForEnv = "DISABLE_REDIS_FOR_ENV"
- // EnvKeyDisableStrongPassword key for env variable DISABLE_STRONG_PASSWORD
- EnvKeyDisableStrongPassword = "DISABLE_STRONG_PASSWORD"
- // EnvKeyEnforceMultiFactorAuthentication is key for env variable ENFORCE_MULTI_FACTOR_AUTHENTICATION
- // If enforced and changed later on, existing user will have MFA but new user will not have MFA
- EnvKeyEnforceMultiFactorAuthentication = "ENFORCE_MULTI_FACTOR_AUTHENTICATION"
- // EnvKeyDisableMultiFactorAuthentication is key for env variable DISABLE_MULTI_FACTOR_AUTHENTICATION
- // this variable is used to completely disable multi factor authentication. It will have no effect on profile preference
- EnvKeyDisableMultiFactorAuthentication = "DISABLE_MULTI_FACTOR_AUTHENTICATION"
- // EnvKeyDisableTOTPLogin is key for env variable DISABLE_TOTP_LOGIN
- // this variable is used to completely disable totp verification
- EnvKeyDisableTOTPLogin = "DISABLE_TOTP_LOGIN"
- // EnvKeyDisableMailOTPLogin is key for env variable DISABLE_MAIL_OTP_LOGIN
- // this variable is used to completely disable totp verification
- EnvKeyDisableMailOTPLogin = "DISABLE_MAIL_OTP_LOGIN"
- // EnvKeyDisablePhoneVerification is key for env variable DISABLE_PHONE_VERIFICATION
- // this variable is used to disable phone verification
- EnvKeyDisablePhoneVerification = "DISABLE_PHONE_VERIFICATION"
- // EnvKeyDisablePlayGround is key for env variable DISABLE_PLAYGROUND
- // this variable will disable or enable playground use in dashboard
- EnvKeyDisablePlayGround = "DISABLE_PLAYGROUND"
-
- // Slice variables
- // EnvKeyRoles key for env variable ROLES
- EnvKeyRoles = "ROLES"
- // EnvKeyProtectedRoles key for env variable PROTECTED_ROLES
- EnvKeyProtectedRoles = "PROTECTED_ROLES"
- // EnvKeyDefaultRoles key for env variable DEFAULT_ROLES
- EnvKeyDefaultRoles = "DEFAULT_ROLES"
- // EnvKeyAllowedOrigins key for env variable ALLOWED_ORIGINS
- EnvKeyAllowedOrigins = "ALLOWED_ORIGINS"
-
- // For oauth/openid/authorize
- // EnvKeyDefaultAuthorizeResponseType key for env variable DEFAULT_AUTHORIZE_RESPONSE_TYPE
- // This env is used for setting default response type in authorize handler
- EnvKeyDefaultAuthorizeResponseType = "DEFAULT_AUTHORIZE_RESPONSE_TYPE"
- // EnvKeyDefaultAuthorizeResponseMode key for env variable DEFAULT_AUTHORIZE_RESPONSE_MODE
- // This env is used for setting default response mode in authorize handler
- EnvKeyDefaultAuthorizeResponseMode = "DEFAULT_AUTHORIZE_RESPONSE_MODE"
-
- // Twilio env variables
- // EnvKeyTwilioAPIKey key for env variable TWILIO_API_KEY
- EnvKeyTwilioAPIKey = "TWILIO_API_KEY"
- // EnvKeyTwilioAPISecret key for env variable TWILIO_API_SECRET
- EnvKeyTwilioAPISecret = "TWILIO_API_SECRET"
- // EnvKeyTwilioAccountSID key for env variable TWILIO_ACCOUNT_SID
- EnvKeyTwilioAccountSID = "TWILIO_ACCOUNT_SID"
- // EnvKeyTwilioSender key for env variable TWILIO_SENDER
- EnvKeyTwilioSender = "TWILIO_SENDER"
-)
diff --git a/server/crypto/aes.go b/server/crypto/aes.go
deleted file mode 100644
index 422f694dd..000000000
--- a/server/crypto/aes.go
+++ /dev/null
@@ -1,124 +0,0 @@
-package crypto
-
-import (
- "crypto/aes"
- "crypto/cipher"
- "crypto/rand"
- "io"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/memorystore"
-)
-
-var bytes = []byte{35, 46, 57, 24, 85, 35, 24, 74, 87, 35, 88, 98, 66, 32, 14, 0o5}
-
-// EncryptAES method is to encrypt or hide any classified text
-func EncryptAES(text string) (string, error) {
- k, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyEncryptionKey)
- if err != nil {
- return "", err
- }
- key := []byte(k)
- block, err := aes.NewCipher(key)
- if err != nil {
- return "", err
- }
- plainText := []byte(text)
- cfb := cipher.NewCFBEncrypter(block, bytes)
- cipherText := make([]byte, len(plainText))
- cfb.XORKeyStream(cipherText, plainText)
- return EncryptB64(string(cipherText)), nil
-}
-
-// DecryptAES method is to extract back the encrypted text
-func DecryptAES(text string) (string, error) {
- k, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyEncryptionKey)
- if err != nil {
- return "", err
- }
- key := []byte(k)
- block, err := aes.NewCipher(key)
- if err != nil {
- return "", err
- }
- cipherText, err := DecryptB64(text)
- if err != nil {
- return "", err
- }
- cfb := cipher.NewCFBDecrypter(block, bytes)
- plainText := make([]byte, len(cipherText))
- cfb.XORKeyStream(plainText, []byte(cipherText))
- return string(plainText), nil
-}
-
-// EncryptAESEnv encrypts data using AES algorithm
-// kept for the backward compatibility of env data encryption
-func EncryptAESEnv(text []byte) ([]byte, error) {
- var res []byte
- k, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyEncryptionKey)
- if err != nil {
- return res, err
- }
- key := []byte(k)
- c, err := aes.NewCipher(key)
- if err != nil {
- return res, err
- }
-
- // gcm or Galois/Counter Mode, is a mode of operation
- // for symmetric key cryptographic block ciphers
- // - https://en.wikipedia.org/wiki/Galois/Counter_Mode
- gcm, err := cipher.NewGCM(c)
- if err != nil {
- return res, err
- }
-
- // creates a new byte array the size of the nonce
- // which must be passed to Seal
- nonce := make([]byte, gcm.NonceSize())
- // populates our nonce with a cryptographically secure
- // random sequence
- if _, err = io.ReadFull(rand.Reader, nonce); err != nil {
- return res, err
- }
-
- // here we encrypt our text using the Seal function
- // Seal encrypts and authenticates plaintext, authenticates the
- // additional data and appends the result to dst, returning the updated
- // slice. The nonce must be NonceSize() bytes long and unique for all
- // time, for a given key.
- return gcm.Seal(nonce, nonce, text, nil), nil
-}
-
-// DecryptAES decrypts data using AES algorithm
-// Kept for the backward compatibility of env data decryption
-func DecryptAESEnv(ciphertext []byte) ([]byte, error) {
- var res []byte
- k, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyEncryptionKey)
- if err != nil {
- return res, err
- }
- key := []byte(k)
- c, err := aes.NewCipher(key)
- if err != nil {
- return res, err
- }
-
- gcm, err := cipher.NewGCM(c)
- if err != nil {
- return res, err
- }
-
- nonceSize := gcm.NonceSize()
- if len(ciphertext) < nonceSize {
- return res, err
- }
-
- nonce, ciphertext := ciphertext[:nonceSize], ciphertext[nonceSize:]
- plaintext, err := gcm.Open(nil, nonce, ciphertext, nil)
- if err != nil {
- return res, err
- }
-
- return plaintext, nil
-}
diff --git a/server/crypto/common.go b/server/crypto/common.go
deleted file mode 100644
index 91aed06ad..000000000
--- a/server/crypto/common.go
+++ /dev/null
@@ -1,136 +0,0 @@
-package crypto
-
-import (
- "crypto/x509"
- "encoding/json"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "golang.org/x/crypto/bcrypt"
- "gopkg.in/square/go-jose.v2"
-)
-
-// GetPubJWK returns JWK for given keys
-func GetPubJWK(algo, keyID string, publicKey interface{}) (string, error) {
- jwk := &jose.JSONWebKeySet{
- Keys: []jose.JSONWebKey{
- {
- Algorithm: algo,
- Key: publicKey,
- Use: "sig",
- KeyID: keyID,
- Certificates: []*x509.Certificate{},
- CertificateThumbprintSHA1: []uint8{},
- CertificateThumbprintSHA256: []uint8{},
- },
- },
- }
- jwkPublicKey, err := jwk.Keys[0].MarshalJSON()
- if err != nil {
- return "", err
- }
- return string(jwkPublicKey), nil
-}
-
-// GenerateJWKBasedOnEnv generates JWK based on env
-// make sure clientID, jwtType, jwtSecret / public & private key pair is set
-// this is called while initializing app / when env is updated
-func GenerateJWKBasedOnEnv() (string, error) {
- jwk := ""
- algo, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyJwtType)
- if err != nil {
- return jwk, err
- }
- clientID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyClientID)
- if err != nil {
- return jwk, err
- }
-
- jwtSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyJwtSecret)
- if err != nil {
- return jwk, err
- }
-
- // check if jwt secret is provided
- if IsHMACA(algo) {
- jwk, err = GetPubJWK(algo, clientID, []byte(jwtSecret))
- if err != nil {
- return "", err
- }
- }
-
- jwtPublicKey, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyJwtPublicKey)
- if err != nil {
- return jwk, err
- }
-
- if IsRSA(algo) {
- publicKeyInstance, err := ParseRsaPublicKeyFromPemStr(jwtPublicKey)
- if err != nil {
- return "", err
- }
-
- jwk, err = GetPubJWK(algo, clientID, publicKeyInstance)
- if err != nil {
- return "", err
- }
- }
-
- if IsECDSA(algo) {
- jwtPublicKey, err = memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyJwtPublicKey)
- if err != nil {
- return jwk, err
- }
- publicKeyInstance, err := ParseEcdsaPublicKeyFromPemStr(jwtPublicKey)
- if err != nil {
- return "", err
- }
-
- jwk, err = GetPubJWK(algo, clientID, publicKeyInstance)
- if err != nil {
- return "", err
- }
- }
-
- return jwk, nil
-}
-
-// EncryptEnvData is used to encrypt the env data
-func EncryptEnvData(data map[string]interface{}) (string, error) {
- jsonBytes, err := json.Marshal(data)
- if err != nil {
- return "", err
- }
-
- storeData, err := memorystore.Provider.GetEnvStore()
- if err != nil {
- return "", err
- }
-
- err = json.Unmarshal(jsonBytes, &storeData)
- if err != nil {
- return "", err
- }
-
- configData, err := json.Marshal(storeData)
- if err != nil {
- return "", err
- }
-
- encryptedConfig, err := EncryptAESEnv(configData)
- if err != nil {
- return "", err
- }
-
- return EncryptB64(string(encryptedConfig)), nil
-}
-
-// EncryptPassword is used for encrypting password
-func EncryptPassword(password string) (string, error) {
- pw, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
- if err != nil {
- return "", err
- }
-
- return string(pw), nil
-}
diff --git a/server/db/db.go b/server/db/db.go
deleted file mode 100644
index 80b3309f1..000000000
--- a/server/db/db.go
+++ /dev/null
@@ -1,86 +0,0 @@
-package db
-
-import (
- log "github.com/sirupsen/logrus"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "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/couchbase"
- "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"
-)
-
-// Provider returns the current database provider
-var Provider providers.Provider
-
-func InitDB() error {
- var err error
-
- envs := memorystore.RequiredEnvStoreObj.GetRequiredEnv()
-
- isSQL := envs.DatabaseType != constants.DbTypeArangodb && envs.DatabaseType != constants.DbTypeMongodb && envs.DatabaseType != constants.DbTypeCassandraDB && envs.DatabaseType != constants.DbTypeScyllaDB && envs.DatabaseType != constants.DbTypeDynamoDB && envs.DatabaseType != constants.DbTypeCouchbaseDB
- isArangoDB := envs.DatabaseType == constants.DbTypeArangodb
- isMongoDB := envs.DatabaseType == constants.DbTypeMongodb
- isCassandra := envs.DatabaseType == constants.DbTypeCassandraDB || envs.DatabaseType == constants.DbTypeScyllaDB
- isDynamoDB := envs.DatabaseType == constants.DbTypeDynamoDB
- isCouchbaseDB := envs.DatabaseType == constants.DbTypeCouchbaseDB
-
- if isSQL {
- log.Info("Initializing SQL Driver for: ", envs.DatabaseType)
- Provider, err = sql.NewProvider()
- if err != nil {
- log.Fatal("Failed to initialize SQL driver: ", err)
- return err
- }
- }
- if isArangoDB {
- log.Info("Initializing ArangoDB Driver")
- Provider, err = arangodb.NewProvider()
- if err != nil {
- log.Fatal("Failed to initialize ArangoDB driver: ", err)
- return err
- }
- }
-
- if isMongoDB {
- log.Info("Initializing MongoDB Driver")
- Provider, err = mongodb.NewProvider()
- if err != nil {
- log.Fatal("Failed to initialize MongoDB driver: ", err)
- return err
- }
- }
-
- if isCassandra {
- log.Info("Initializing CassandraDB Driver")
- Provider, err = cassandradb.NewProvider()
- if err != nil {
- log.Fatal("Failed to initialize CassandraDB driver: ", err)
- return err
- }
- }
-
- 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
- }
- }
-
- if isCouchbaseDB {
- log.Info("Initializing CouchbaseDB Driver for: ", envs.DatabaseType)
- Provider, err = couchbase.NewProvider()
- if err != nil {
- log.Fatal("Failed to initialize Couchbase driver: ", err)
- return err
- }
- }
-
- return nil
-}
diff --git a/server/db/providers/dynamodb/provider.go b/server/db/providers/dynamodb/provider.go
deleted file mode 100644
index 70a893068..000000000
--- a/server/db/providers/dynamodb/provider.go
+++ /dev/null
@@ -1,59 +0,0 @@
-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 != "" {
- log.Debug("Tring to use database url for dynamodb")
- // 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()
- db.CreateTable(models.Collections.Authenticators, models.Authenticator{}).Wait()
- return &provider{
- db: db,
- }, nil
-}
diff --git a/server/db/providers/provider_template/provider.go b/server/db/providers/provider_template/provider.go
deleted file mode 100644
index 30490b4f2..000000000
--- a/server/db/providers/provider_template/provider.go
+++ /dev/null
@@ -1,20 +0,0 @@
-package provider_template
-
-import (
- "gorm.io/gorm"
-)
-
-// TODO change following provider to new db provider
-type provider struct {
- db *gorm.DB
-}
-
-// NewProvider returns a new SQL provider
-// TODO change following provider to new db provider
-func NewProvider() (*provider, error) {
- var sqlDB *gorm.DB
-
- return &provider{
- db: sqlDB,
- }, nil
-}
diff --git a/server/db/providers/providers.go b/server/db/providers/providers.go
deleted file mode 100644
index 6ea95cc41..000000000
--- a/server/db/providers/providers.go
+++ /dev/null
@@ -1,102 +0,0 @@
-package providers
-
-import (
- "context"
-
- "github.com/authorizerdev/authorizer/server/db/models"
- "github.com/authorizerdev/authorizer/server/graph/model"
-)
-
-type Provider interface {
- // AddUser to save user information in database
- AddUser(ctx context.Context, user *models.User) (*models.User, error)
- // UpdateUser to update user information in database
- UpdateUser(ctx context.Context, user *models.User) (*models.User, error)
- // DeleteUser to delete user information from database
- DeleteUser(ctx context.Context, user *models.User) error
- // ListUsers to get list of users from database
- ListUsers(ctx context.Context, pagination *model.Pagination) (*model.Users, error)
- // GetUserByEmail to get user information from database using email address
- GetUserByEmail(ctx context.Context, email string) (*models.User, error)
- // GetUserByPhoneNumber to get user information from database using phone number
- GetUserByPhoneNumber(ctx context.Context, phoneNumber string) (*models.User, error)
- // GetUserByID to get user information from database using user ID
- GetUserByID(ctx context.Context, id string) (*models.User, error)
- // UpdateUsers to update multiple users, with parameters of user IDs slice
- // If ids set to nil / empty all the users will be updated
- UpdateUsers(ctx context.Context, data map[string]interface{}, ids []string) error
-
- // AddVerificationRequest to save verification request in database
- AddVerificationRequest(ctx context.Context, verificationRequest *models.VerificationRequest) (*models.VerificationRequest, error)
- // GetVerificationRequestByToken to get verification request from database using token
- GetVerificationRequestByToken(ctx context.Context, token string) (*models.VerificationRequest, error)
- // GetVerificationRequestByEmail to get verification request by email from database
- GetVerificationRequestByEmail(ctx context.Context, email string, identifier string) (*models.VerificationRequest, error)
- // ListVerificationRequests to get list of verification requests from database
- ListVerificationRequests(ctx context.Context, pagination *model.Pagination) (*model.VerificationRequests, error)
- // DeleteVerificationRequest to delete verification request from database
- DeleteVerificationRequest(ctx context.Context, verificationRequest *models.VerificationRequest) error
-
- // AddSession to save session information in database
- AddSession(ctx context.Context, session *models.Session) error
- // DeleteSession to delete session information from database
- DeleteSession(ctx context.Context, userId string) error
-
- // AddEnv to save environment information in database
- AddEnv(ctx context.Context, env *models.Env) (*models.Env, error)
- // UpdateEnv to update environment information in database
- UpdateEnv(ctx context.Context, env *models.Env) (*models.Env, error)
- // GetEnv to get environment information from database
- GetEnv(ctx context.Context) (*models.Env, error)
-
- // AddWebhook to add webhook
- AddWebhook(ctx context.Context, webhook *models.Webhook) (*model.Webhook, error)
- // UpdateWebhook to update webhook
- UpdateWebhook(ctx context.Context, webhook *models.Webhook) (*model.Webhook, error)
- // ListWebhook to list webhook
- ListWebhook(ctx context.Context, pagination *model.Pagination) (*model.Webhooks, error)
- // GetWebhookByID to get webhook by id
- GetWebhookByID(ctx context.Context, webhookID string) (*model.Webhook, error)
- // GetWebhookByEventName to get webhook by event_name
- GetWebhookByEventName(ctx context.Context, eventName string) ([]*model.Webhook, error)
- // DeleteWebhook to delete webhook
- DeleteWebhook(ctx context.Context, webhook *model.Webhook) error
-
- // AddWebhookLog to add webhook log
- AddWebhookLog(ctx context.Context, webhookLog *models.WebhookLog) (*model.WebhookLog, error)
- // ListWebhookLogs to list webhook logs
- ListWebhookLogs(ctx context.Context, pagination *model.Pagination, webhookID string) (*model.WebhookLogs, error)
-
- // AddEmailTemplate to add EmailTemplate
- AddEmailTemplate(ctx context.Context, emailTemplate *models.EmailTemplate) (*model.EmailTemplate, error)
- // UpdateEmailTemplate to update EmailTemplate
- UpdateEmailTemplate(ctx context.Context, emailTemplate *models.EmailTemplate) (*model.EmailTemplate, error)
- // ListEmailTemplate to list EmailTemplate
- ListEmailTemplate(ctx context.Context, pagination *model.Pagination) (*model.EmailTemplates, error)
- // GetEmailTemplateByID to get EmailTemplate by id
- GetEmailTemplateByID(ctx context.Context, emailTemplateID string) (*model.EmailTemplate, error)
- // GetEmailTemplateByEventName to get EmailTemplate by event_name
- GetEmailTemplateByEventName(ctx context.Context, eventName string) (*model.EmailTemplate, error)
- // DeleteEmailTemplate to delete EmailTemplate
- DeleteEmailTemplate(ctx context.Context, emailTemplate *model.EmailTemplate) error
-
- // UpsertOTP to add or update otp
- UpsertOTP(ctx context.Context, otp *models.OTP) (*models.OTP, error)
- // GetOTPByEmail to get otp for a given email address
- GetOTPByEmail(ctx context.Context, emailAddress string) (*models.OTP, error)
- // GetOTPByPhoneNumber to get otp for a given phone number
- GetOTPByPhoneNumber(ctx context.Context, phoneNumber string) (*models.OTP, error)
- // DeleteOTP to delete otp
- DeleteOTP(ctx context.Context, otp *models.OTP) error
-
- // AddAuthenticator adds a new authenticator document to the database.
- // If the authenticator doesn't have an ID, a new one is generated.
- // The created document is returned, or an error if the operation fails.
- AddAuthenticator(ctx context.Context, totp *models.Authenticator) (*models.Authenticator, error)
- // UpdateAuthenticator updates an existing authenticator document in the database.
- // The updated document is returned, or an error if the operation fails.
- UpdateAuthenticator(ctx context.Context, totp *models.Authenticator) (*models.Authenticator, error)
- // GetAuthenticatorDetailsByUserId retrieves details of an authenticator document based on user ID and authenticator type.
- // If found, the authenticator document is returned, or an error if not found or an error occurs during the retrieval.
- GetAuthenticatorDetailsByUserId(ctx context.Context, userId string, authenticatorType string) (*models.Authenticator, error)
-}
diff --git a/server/email/email.go b/server/email/email.go
deleted file mode 100644
index 8376931d8..000000000
--- a/server/email/email.go
+++ /dev/null
@@ -1,166 +0,0 @@
-package email
-
-import (
- "bytes"
- "context"
- "crypto/tls"
- "strconv"
- "strings"
- "text/template"
-
- log "github.com/sirupsen/logrus"
- gomail "gopkg.in/mail.v2"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
-)
-
-func getDefaultTemplate(event string) *model.EmailTemplate {
- switch event {
- case constants.VerificationTypeBasicAuthSignup, constants.VerificationTypeMagicLinkLogin, constants.VerificationTypeUpdateEmail:
- return &model.EmailTemplate{
- Subject: emailVerificationSubject,
- Template: emailVerificationTemplate,
- }
- case constants.VerificationTypeForgotPassword:
- return &model.EmailTemplate{
- Subject: forgotPasswordSubject,
- Template: forgotPasswordTemplate,
- }
- case constants.VerificationTypeInviteMember:
- return &model.EmailTemplate{
- Subject: inviteEmailSubject,
- Template: inviteEmailTemplate,
- }
- case constants.VerificationTypeOTP:
- return &model.EmailTemplate{
- Subject: otpEmailSubject,
- Template: otpEmailTemplate,
- }
- default:
- return nil
- }
-}
-
-func getEmailTemplate(event string, data map[string]interface{}) (*model.EmailTemplate, error) {
- ctx := context.Background()
- tmp, err := db.Provider.GetEmailTemplateByEventName(ctx, event)
- if err != nil || tmp == nil {
- tmp = getDefaultTemplate(event)
- }
-
- templ, err := template.New(event + "_template.tmpl").Parse(tmp.Template)
- if err != nil {
- return nil, err
- }
- buf := &bytes.Buffer{}
- err = templ.Execute(buf, data)
- if err != nil {
- return nil, err
- }
- templateString := buf.String()
-
- subject, err := template.New(event + "_subject.tmpl").Parse(tmp.Subject)
- if err != nil {
- return nil, err
- }
- buf = &bytes.Buffer{}
- err = subject.Execute(buf, data)
- if err != nil {
- return nil, err
- }
- subjectString := buf.String()
- return &model.EmailTemplate{
- Template: templateString,
- Subject: subjectString,
- }, nil
-}
-
-// SendEmail function to send mail
-func SendEmail(to []string, event string, data map[string]interface{}) error {
- // dont trigger email sending in case of test
- envKey, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyEnv)
- if err != nil {
- return err
- }
- if envKey == constants.TestEnv {
- return nil
- }
-
- tmp, err := getEmailTemplate(event, data)
- if err != nil {
- log.Error("Failed to get event template: ", err)
- return err
- }
-
- m := gomail.NewMessage()
- senderEmail, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeySenderEmail)
- if err != nil {
- log.Errorf("Error while getting sender email from env variable: %v", err)
- return err
- }
-
- senderName, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeySenderName)
- if err != nil {
- log.Errorf("Error while getting sender name from env variable: %v", err)
- return err
- }
-
- smtpPort, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeySmtpPort)
- if err != nil {
- log.Errorf("Error while getting smtp port from env variable: %v", err)
- return err
- }
-
- smtpHost, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeySmtpHost)
- if err != nil {
- log.Errorf("Error while getting smtp host from env variable: %v", err)
- return err
- }
-
- smtpUsername, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeySmtpUsername)
- if err != nil {
- log.Errorf("Error while getting smtp username from env variable: %v", err)
- return err
- }
-
- smtpPassword, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeySmtpPassword)
- if err != nil {
- log.Errorf("Error while getting smtp password from env variable: %v", err)
- 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)
- return err
- }
-
- m.SetAddressHeader("From", senderEmail, senderName)
- m.SetHeader("To", to...)
- m.SetHeader("Subject", tmp.Subject)
- m.SetBody("text/html", tmp.Template)
- port, _ := strconv.Atoi(smtpPort)
- d := gomail.NewDialer(smtpHost, port, smtpUsername, smtpPassword)
- 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
- }
- return nil
-}
diff --git a/server/env/env.go b/server/env/env.go
deleted file mode 100644
index 110e0c5af..000000000
--- a/server/env/env.go
+++ /dev/null
@@ -1,903 +0,0 @@
-package env
-
-import (
- "errors"
- "fmt"
- "os"
- "strconv"
- "strings"
-
- "github.com/google/uuid"
- log "github.com/sirupsen/logrus"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/crypto"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/utils"
-)
-
-// InitEnv to initialize EnvData and through error if required env are not present
-func InitAllEnv() error {
- envData, err := GetEnvData()
- if err != nil || envData == nil {
- log.Info("No env data found in db, using local clone of env data")
- // get clone of current store
- envData, err = memorystore.Provider.GetEnvStore()
- if err != nil {
- log.Debug("Error while getting env data from memorystore: ", err)
- return err
- }
- }
-
- // unique client id for each instance
- cid, ok := envData[constants.EnvKeyClientID]
- clientID := ""
- if !ok || cid == "" {
- clientID = uuid.New().String()
- envData[constants.EnvKeyClientID] = clientID
- } else {
- clientID = cid.(string)
- }
-
- // unique client secret for each instance
- if val, ok := envData[constants.EnvKeyClientSecret]; !ok || val != "" {
- envData[constants.EnvKeyClientSecret] = uuid.New().String()
- }
-
- // os string envs
- osEnv := os.Getenv(constants.EnvKeyEnv)
- osAppURL := os.Getenv(constants.EnvKeyAppURL)
- osAuthorizerURL := os.Getenv(constants.EnvKeyAuthorizerURL)
- osPort := os.Getenv(constants.EnvKeyPort)
- osAccessTokenExpiryTime := os.Getenv(constants.EnvKeyAccessTokenExpiryTime)
- osAdminSecret := os.Getenv(constants.EnvKeyAdminSecret)
- osSmtpHost := os.Getenv(constants.EnvKeySmtpHost)
- 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)
- osSenderName := os.Getenv(constants.EnvKeySenderName)
- osJwtType := os.Getenv(constants.EnvKeyJwtType)
- osJwtSecret := os.Getenv(constants.EnvKeyJwtSecret)
- osJwtPrivateKey := os.Getenv(constants.EnvKeyJwtPrivateKey)
- osJwtPublicKey := os.Getenv(constants.EnvKeyJwtPublicKey)
- osJwtRoleClaim := os.Getenv(constants.EnvKeyJwtRoleClaim)
- osCustomAccessTokenScript := os.Getenv(constants.EnvKeyCustomAccessTokenScript)
- osGoogleClientID := os.Getenv(constants.EnvKeyGoogleClientID)
- osGoogleClientSecret := os.Getenv(constants.EnvKeyGoogleClientSecret)
- osGithubClientID := os.Getenv(constants.EnvKeyGithubClientID)
- osGithubClientSecret := os.Getenv(constants.EnvKeyGithubClientSecret)
- osFacebookClientID := os.Getenv(constants.EnvKeyFacebookClientID)
- osFacebookClientSecret := os.Getenv(constants.EnvKeyFacebookClientSecret)
- osLinkedInClientID := os.Getenv(constants.EnvKeyLinkedInClientID)
- osLinkedInClientSecret := os.Getenv(constants.EnvKeyLinkedInClientSecret)
- osAppleClientID := os.Getenv(constants.EnvKeyAppleClientID)
- osAppleClientSecret := os.Getenv(constants.EnvKeyAppleClientSecret)
- osTwitterClientID := os.Getenv(constants.EnvKeyTwitterClientID)
- osTwitterClientSecret := os.Getenv(constants.EnvKeyTwitterClientSecret)
- osMicrosoftClientID := os.Getenv(constants.EnvKeyMicrosoftClientID)
- osMicrosoftClientSecret := os.Getenv(constants.EnvKeyMicrosoftClientSecret)
- osMicrosoftActiveDirectoryTenantID := os.Getenv(constants.EnvKeyMicrosoftActiveDirectoryTenantID)
- osTwitchClientID := os.Getenv(constants.EnvKeyTwitchClientID)
- osTwitchClientSecret := os.Getenv(constants.EnvKeyTwitchClientSecret)
- osRobloxClientID := os.Getenv(constants.EnvKeyTwitchClientID)
- osRobloxClientSecret := os.Getenv(constants.EnvKeyTwitchClientSecret)
- 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)
- osCouchbaseBucket := os.Getenv(constants.EnvCouchbaseBucket)
- osCouchbaseScope := os.Getenv(constants.EnvCouchbaseScope)
- osCouchbaseBucketRAMQuotaMB := os.Getenv(constants.EnvCouchbaseBucketRAMQuotaMB)
- osAuthorizeResponseType := os.Getenv(constants.EnvKeyDefaultAuthorizeResponseType)
- osAuthorizeResponseMode := os.Getenv(constants.EnvKeyDefaultAuthorizeResponseMode)
-
- // os bool vars
- osAppCookieSecure := os.Getenv(constants.EnvKeyAppCookieSecure)
- osAdminCookieSecure := os.Getenv(constants.EnvKeyAdminCookieSecure)
- osDisableBasicAuthentication := os.Getenv(constants.EnvKeyDisableBasicAuthentication)
- osDisableMobileBasicAuthentication := os.Getenv(constants.AuthRecipeMethodMobileBasicAuth)
- osDisableEmailVerification := os.Getenv(constants.EnvKeyDisableEmailVerification)
- osDisableMagicLinkLogin := os.Getenv(constants.EnvKeyDisableMagicLinkLogin)
- osDisableLoginPage := os.Getenv(constants.EnvKeyDisableLoginPage)
- osDisableSignUp := os.Getenv(constants.EnvKeyDisableSignUp)
- osDisableRedisForEnv := os.Getenv(constants.EnvKeyDisableRedisForEnv)
- osDisableStrongPassword := os.Getenv(constants.EnvKeyDisableStrongPassword)
- osEnforceMultiFactorAuthentication := os.Getenv(constants.EnvKeyEnforceMultiFactorAuthentication)
- osDisableMultiFactorAuthentication := os.Getenv(constants.EnvKeyDisableMultiFactorAuthentication)
- osDisableTOTPLogin := os.Getenv(constants.EnvKeyDisableTOTPLogin)
- osDisableMailOTPLogin := os.Getenv(constants.EnvKeyDisableMailOTPLogin)
- // phone verification var
- osDisablePhoneVerification := os.Getenv(constants.EnvKeyDisablePhoneVerification)
- osDisablePlayground := os.Getenv(constants.EnvKeyDisablePlayGround)
-
- // twilio vars
- osTwilioApiKey := os.Getenv(constants.EnvKeyTwilioAPIKey)
- osTwilioApiSecret := os.Getenv(constants.EnvKeyTwilioAPISecret)
- osTwilioAccountSid := os.Getenv(constants.EnvKeyTwilioAccountSID)
- osTwilioSender := os.Getenv(constants.EnvKeyTwilioSender)
-
- // os slice vars
- osAllowedOrigins := os.Getenv(constants.EnvKeyAllowedOrigins)
- osRoles := os.Getenv(constants.EnvKeyRoles)
- osDefaultRoles := os.Getenv(constants.EnvKeyDefaultRoles)
- osProtectedRoles := os.Getenv(constants.EnvKeyProtectedRoles)
-
- ienv, ok := envData[constants.EnvKeyEnv]
- if !ok || ienv == "" {
- envData[constants.EnvKeyEnv] = osEnv
- if envData[constants.EnvKeyEnv] == "" {
- envData[constants.EnvKeyEnv] = "production"
- }
-
- if envData[constants.EnvKeyEnv] == "production" {
- envData[constants.EnvKeyIsProd] = true
- } else {
- envData[constants.EnvKeyIsProd] = false
- }
- }
- if osEnv != "" && osEnv != envData[constants.EnvKeyEnv] {
- envData[constants.EnvKeyEnv] = osEnv
- if envData[constants.EnvKeyEnv] == "production" {
- envData[constants.EnvKeyIsProd] = true
- } else {
- envData[constants.EnvKeyIsProd] = false
- }
- }
-
- 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] != osAwsAccessKey {
- envData[constants.EnvAwsAccessKeyID] = osAwsAccessKey
- }
-
- if val, ok := envData[constants.EnvAwsSecretAccessKey]; !ok || val == "" {
- envData[constants.EnvAwsSecretAccessKey] = osAwsSecretKey
- }
- if osAwsSecretKey != "" && envData[constants.EnvAwsSecretAccessKey] != osAwsSecretKey {
- envData[constants.EnvAwsSecretAccessKey] = osAwsSecretKey
- }
-
- if val, ok := envData[constants.EnvCouchbaseBucket]; !ok || val == "" {
- envData[constants.EnvCouchbaseBucket] = osCouchbaseBucket
- }
- if osCouchbaseBucket != "" && envData[constants.EnvCouchbaseBucket] != osCouchbaseBucket {
- envData[constants.EnvCouchbaseBucket] = osCouchbaseBucket
- }
-
- if val, ok := envData[constants.EnvCouchbaseBucketRAMQuotaMB]; !ok || val == "" {
- envData[constants.EnvCouchbaseBucketRAMQuotaMB] = osCouchbaseBucketRAMQuotaMB
- }
- if osCouchbaseBucketRAMQuotaMB != "" && envData[constants.EnvCouchbaseBucketRAMQuotaMB] != osCouchbaseBucketRAMQuotaMB {
- envData[constants.EnvCouchbaseBucketRAMQuotaMB] = osCouchbaseBucketRAMQuotaMB
- }
-
- if val, ok := envData[constants.EnvCouchbaseScope]; !ok || val == "" {
- envData[constants.EnvCouchbaseScope] = osCouchbaseScope
- }
- if osCouchbaseScope != "" && envData[constants.EnvCouchbaseScope] != osCouchbaseScope {
- envData[constants.EnvCouchbaseScope] = osCouchbaseScope
- }
-
- if val, ok := envData[constants.EnvKeyAppURL]; !ok || val == "" {
- envData[constants.EnvKeyAppURL] = osAppURL
- }
- if osAppURL != "" && envData[constants.EnvKeyAppURL] != osAppURL {
- envData[constants.EnvKeyAppURL] = osAppURL
- }
-
- if val, ok := envData[constants.EnvKeyAuthorizerURL]; !ok || val == "" {
- envData[constants.EnvKeyAuthorizerURL] = osAuthorizerURL
- }
- if osAuthorizerURL != "" && envData[constants.EnvKeyAuthorizerURL] != osAuthorizerURL {
- envData[constants.EnvKeyAuthorizerURL] = osAuthorizerURL
- }
-
- if val, ok := envData[constants.EnvKeyPort]; !ok || val == "" {
- envData[constants.EnvKeyPort] = osPort
- if envData[constants.EnvKeyPort] == "" {
- envData[constants.EnvKeyPort] = "8080"
- }
- }
- if osPort != "" && envData[constants.EnvKeyPort] != osPort {
- envData[constants.EnvKeyPort] = osPort
- }
-
- if val, ok := envData[constants.EnvKeyAccessTokenExpiryTime]; !ok || val == "" {
- envData[constants.EnvKeyAccessTokenExpiryTime] = osAccessTokenExpiryTime
- if envData[constants.EnvKeyAccessTokenExpiryTime] == "" {
- envData[constants.EnvKeyAccessTokenExpiryTime] = "30m"
- }
- }
- if osAccessTokenExpiryTime != "" && envData[constants.EnvKeyAccessTokenExpiryTime] != osAccessTokenExpiryTime {
- envData[constants.EnvKeyAccessTokenExpiryTime] = osAccessTokenExpiryTime
- }
-
- if val, ok := envData[constants.EnvKeyAdminSecret]; !ok || val == "" {
- envData[constants.EnvKeyAdminSecret] = osAdminSecret
- }
- if osAdminSecret != "" && envData[constants.EnvKeyAdminSecret] != osAdminSecret {
- envData[constants.EnvKeyAdminSecret] = osAdminSecret
- }
-
- if val, ok := envData[constants.EnvKeySmtpHost]; !ok || val == "" {
- envData[constants.EnvKeySmtpHost] = osSmtpHost
- }
- if osSmtpHost != "" && envData[constants.EnvKeySmtpHost] != osSmtpHost {
- envData[constants.EnvKeySmtpHost] = osSmtpHost
- }
-
- if val, ok := envData[constants.EnvKeySmtpPort]; !ok || val == "" {
- envData[constants.EnvKeySmtpPort] = osSmtpPort
- }
- if osSmtpPort != "" && envData[constants.EnvKeySmtpPort] != osSmtpPort {
- envData[constants.EnvKeySmtpPort] = osSmtpPort
- }
-
- if val, ok := envData[constants.EnvKeySmtpUsername]; !ok || val == "" {
- envData[constants.EnvKeySmtpUsername] = osSmtpUsername
- }
- if osSmtpUsername != "" && envData[constants.EnvKeySmtpUsername] != osSmtpUsername {
- 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
- }
- if osSmtpPassword != "" && envData[constants.EnvKeySmtpPassword] != osSmtpPassword {
- envData[constants.EnvKeySmtpPassword] = osSmtpPassword
- }
-
- if val, ok := envData[constants.EnvKeySenderEmail]; !ok || val == "" {
- envData[constants.EnvKeySenderEmail] = osSenderEmail
- }
- if osSenderEmail != "" && envData[constants.EnvKeySenderEmail] != osSenderEmail {
- envData[constants.EnvKeySenderEmail] = osSenderEmail
- }
-
- if val, ok := envData[constants.EnvKeySenderName]; !ok || val == "" {
- envData[constants.EnvKeySenderName] = osSenderName
- }
- if osSenderName != "" && envData[constants.EnvKeySenderName] != osSenderName {
- envData[constants.EnvKeySenderName] = osSenderName
- }
-
- algoVal, ok := envData[constants.EnvKeyJwtType]
- algo := ""
- if !ok || algoVal == "" {
- envData[constants.EnvKeyJwtType] = osJwtType
- if envData[constants.EnvKeyJwtType] == "" {
- envData[constants.EnvKeyJwtType] = "RS256"
- algo = envData[constants.EnvKeyJwtType].(string)
- }
- } else {
- algo = algoVal.(string)
- if !crypto.IsHMACA(algo) && !crypto.IsRSA(algo) && !crypto.IsECDSA(algo) {
- log.Debug("Invalid JWT Algorithm")
- return errors.New("invalid JWT_TYPE")
- }
- }
- if osJwtType != "" && osJwtType != algo {
- if !crypto.IsHMACA(osJwtType) && !crypto.IsRSA(osJwtType) && !crypto.IsECDSA(osJwtType) {
- log.Debug("Invalid JWT Algorithm")
- return errors.New("invalid JWT_TYPE")
- }
- algo = osJwtType
- envData[constants.EnvKeyJwtType] = osJwtType
- }
-
- if crypto.IsHMACA(algo) {
- if val, ok := envData[constants.EnvKeyJwtSecret]; !ok || val == "" {
- envData[constants.EnvKeyJwtSecret] = osJwtSecret
- if envData[constants.EnvKeyJwtSecret] == "" {
- envData[constants.EnvKeyJwtSecret], _, err = crypto.NewHMACKey(algo, clientID)
- if err != nil {
- return err
- }
- }
- }
- if osJwtSecret != "" && envData[constants.EnvKeyJwtSecret] != osJwtSecret {
- envData[constants.EnvKeyJwtSecret] = osJwtSecret
- }
- }
-
- if crypto.IsRSA(algo) || crypto.IsECDSA(algo) {
- privateKey, publicKey := "", ""
-
- if val, ok := envData[constants.EnvKeyJwtPrivateKey]; !ok || val == "" {
- privateKey = osJwtPrivateKey
- }
- if osJwtPrivateKey != "" && privateKey != osJwtPrivateKey {
- privateKey = osJwtPrivateKey
- }
-
- if val, ok := envData[constants.EnvKeyJwtPublicKey]; !ok || val == "" {
- publicKey = osJwtPublicKey
- }
- if osJwtPublicKey != "" && publicKey != osJwtPublicKey {
- publicKey = osJwtPublicKey
- }
-
- // if algo is RSA / ECDSA, then we need to have both private and public key
- // if either of them is not present generate new keys
- if privateKey == "" || publicKey == "" {
- if crypto.IsRSA(algo) {
- _, privateKey, publicKey, _, err = crypto.NewRSAKey(algo, clientID)
- if err != nil {
- return err
- }
- } else if crypto.IsECDSA(algo) {
- _, privateKey, publicKey, _, err = crypto.NewECDSAKey(algo, clientID)
- if err != nil {
- return err
- }
- }
- } else {
- // parse keys to make sure they are valid
- if crypto.IsRSA(algo) {
- _, err = crypto.ParseRsaPrivateKeyFromPemStr(privateKey)
- if err != nil {
- return err
- }
-
- _, err := crypto.ParseRsaPublicKeyFromPemStr(publicKey)
- if err != nil {
- return err
- }
-
- } else if crypto.IsECDSA(algo) {
- _, err = crypto.ParseEcdsaPrivateKeyFromPemStr(privateKey)
- if err != nil {
- return err
- }
-
- _, err := crypto.ParseEcdsaPublicKeyFromPemStr(publicKey)
- if err != nil {
- return err
- }
- }
- }
-
- envData[constants.EnvKeyJwtPrivateKey] = privateKey
- envData[constants.EnvKeyJwtPublicKey] = publicKey
-
- }
-
- if val, ok := envData[constants.EnvKeyJwtRoleClaim]; !ok || val == "" {
- envData[constants.EnvKeyJwtRoleClaim] = osJwtRoleClaim
-
- if envData[constants.EnvKeyJwtRoleClaim] == "" {
- envData[constants.EnvKeyJwtRoleClaim] = "roles"
- }
- }
- if osJwtRoleClaim != "" && envData[constants.EnvKeyJwtRoleClaim] != osJwtRoleClaim {
- envData[constants.EnvKeyJwtRoleClaim] = osJwtRoleClaim
- }
-
- if val, ok := envData[constants.EnvKeyCustomAccessTokenScript]; !ok || val == "" {
- envData[constants.EnvKeyCustomAccessTokenScript] = osCustomAccessTokenScript
- }
- if osCustomAccessTokenScript != "" && envData[constants.EnvKeyCustomAccessTokenScript] != osCustomAccessTokenScript {
- envData[constants.EnvKeyCustomAccessTokenScript] = osCustomAccessTokenScript
- }
-
- if val, ok := envData[constants.EnvKeyGoogleClientID]; !ok || val == "" {
- envData[constants.EnvKeyGoogleClientID] = osGoogleClientID
- }
- if osGoogleClientID != "" && envData[constants.EnvKeyGoogleClientID] != osGoogleClientID {
- envData[constants.EnvKeyGoogleClientID] = osGoogleClientID
- }
-
- if val, ok := envData[constants.EnvKeyGoogleClientSecret]; !ok || val == "" {
- envData[constants.EnvKeyGoogleClientSecret] = osGoogleClientSecret
- }
- if osGoogleClientSecret != "" && envData[constants.EnvKeyGoogleClientSecret] != osGoogleClientSecret {
- envData[constants.EnvKeyGoogleClientSecret] = osGoogleClientSecret
- }
-
- if val, ok := envData[constants.EnvKeyGithubClientID]; !ok || val == "" {
- envData[constants.EnvKeyGithubClientID] = osGithubClientID
- }
- if osGithubClientID != "" && envData[constants.EnvKeyGithubClientID] != osGithubClientID {
- envData[constants.EnvKeyGithubClientID] = osGithubClientID
- }
-
- if val, ok := envData[constants.EnvKeyGithubClientSecret]; !ok || val == "" {
- envData[constants.EnvKeyGithubClientSecret] = osGithubClientSecret
- }
- if osGithubClientSecret != "" && envData[constants.EnvKeyGithubClientSecret] != osGithubClientSecret {
- envData[constants.EnvKeyGithubClientSecret] = osGithubClientSecret
- }
-
- if val, ok := envData[constants.EnvKeyFacebookClientID]; !ok || val == "" {
- envData[constants.EnvKeyFacebookClientID] = osFacebookClientID
- }
- if osFacebookClientID != "" && envData[constants.EnvKeyFacebookClientID] != osFacebookClientID {
- envData[constants.EnvKeyFacebookClientID] = osFacebookClientID
- }
-
- if val, ok := envData[constants.EnvKeyFacebookClientSecret]; !ok || val == "" {
- envData[constants.EnvKeyFacebookClientSecret] = osFacebookClientSecret
- }
- if osFacebookClientSecret != "" && envData[constants.EnvKeyFacebookClientSecret] != osFacebookClientSecret {
- envData[constants.EnvKeyFacebookClientSecret] = osFacebookClientSecret
- }
-
- if val, ok := envData[constants.EnvKeyLinkedInClientID]; !ok || val == "" {
- envData[constants.EnvKeyLinkedInClientID] = osLinkedInClientID
- }
- if osLinkedInClientID != "" && envData[constants.EnvKeyLinkedInClientID] != osLinkedInClientID {
- envData[constants.EnvKeyLinkedInClientID] = osLinkedInClientID
- }
-
- if val, ok := envData[constants.EnvKeyLinkedInClientSecret]; !ok || val == "" {
- envData[constants.EnvKeyLinkedInClientSecret] = osLinkedInClientSecret
- }
- if osLinkedInClientSecret != "" && envData[constants.EnvKeyLinkedInClientSecret] != osLinkedInClientSecret {
- envData[constants.EnvKeyLinkedInClientSecret] = osLinkedInClientSecret
- }
-
- if val, ok := envData[constants.EnvKeyAppleClientID]; !ok || val == "" {
- envData[constants.EnvKeyAppleClientID] = osAppleClientID
- }
- if osAppleClientID != "" && envData[constants.EnvKeyAppleClientID] != osAppleClientID {
- envData[constants.EnvKeyAppleClientID] = osAppleClientID
- }
-
- if val, ok := envData[constants.EnvKeyAppleClientSecret]; !ok || val == "" {
- envData[constants.EnvKeyAppleClientSecret] = osAppleClientSecret
- }
- if osAppleClientSecret != "" && envData[constants.EnvKeyAppleClientSecret] != osAppleClientSecret {
- envData[constants.EnvKeyAppleClientSecret] = osAppleClientSecret
- }
-
- if val, ok := envData[constants.EnvKeyTwitterClientID]; !ok || val == "" {
- envData[constants.EnvKeyTwitterClientID] = osTwitterClientID
- }
- if osTwitterClientID != "" && envData[constants.EnvKeyTwitterClientID] != osTwitterClientID {
- envData[constants.EnvKeyTwitterClientID] = osTwitterClientID
- }
-
- if val, ok := envData[constants.EnvKeyTwitterClientSecret]; !ok || val == "" {
- envData[constants.EnvKeyTwitterClientSecret] = osTwitterClientSecret
- }
- if osTwitterClientSecret != "" && envData[constants.EnvKeyTwitterClientSecret] != osTwitterClientSecret {
- envData[constants.EnvKeyTwitterClientSecret] = osTwitterClientSecret
- }
-
- if val, ok := envData[constants.EnvKeyMicrosoftClientID]; !ok || val == "" {
- envData[constants.EnvKeyMicrosoftClientID] = osMicrosoftClientID
- }
- if osMicrosoftClientID != "" && envData[constants.EnvKeyMicrosoftClientID] != osMicrosoftClientID {
- envData[constants.EnvKeyMicrosoftClientID] = osMicrosoftClientID
- }
-
- if val, ok := envData[constants.EnvKeyMicrosoftClientSecret]; !ok || val == "" {
- envData[constants.EnvKeyMicrosoftClientSecret] = osMicrosoftClientSecret
- }
- if osMicrosoftClientSecret != "" && envData[constants.EnvKeyMicrosoftClientSecret] != osMicrosoftClientSecret {
- envData[constants.EnvKeyMicrosoftClientSecret] = osMicrosoftClientSecret
- }
-
- if val, ok := envData[constants.EnvKeyMicrosoftActiveDirectoryTenantID]; !ok || val == "" {
- envData[constants.EnvKeyMicrosoftActiveDirectoryTenantID] = osMicrosoftActiveDirectoryTenantID
- }
- if osMicrosoftActiveDirectoryTenantID != "" && envData[constants.EnvKeyMicrosoftActiveDirectoryTenantID] != osMicrosoftActiveDirectoryTenantID {
- envData[constants.EnvKeyMicrosoftActiveDirectoryTenantID] = osMicrosoftActiveDirectoryTenantID
- }
-
- if val, ok := envData[constants.EnvKeyTwitchClientID]; !ok || val == "" {
- envData[constants.EnvKeyTwitchClientID] = osTwitchClientID
- }
- if osTwitchClientID != "" && envData[constants.EnvKeyTwitchClientID] != osTwitchClientID {
- envData[constants.EnvKeyTwitchClientID] = osTwitchClientID
- }
-
- if val, ok := envData[constants.EnvKeyTwitchClientSecret]; !ok || val == "" {
- envData[constants.EnvKeyTwitchClientSecret] = osTwitchClientSecret
- }
- if osTwitchClientSecret != "" && envData[constants.EnvKeyTwitchClientSecret] != osTwitchClientSecret {
- envData[constants.EnvKeyTwitchClientSecret] = osTwitchClientSecret
- }
-
- if val, ok := envData[constants.EnvKeyRobloxClientID]; !ok || val == "" {
- envData[constants.EnvKeyRobloxClientID] = osRobloxClientID
- }
- if osRobloxClientID != "" && envData[constants.EnvKeyRobloxClientID] != osRobloxClientID {
- envData[constants.EnvKeyRobloxClientID] = osRobloxClientID
- }
-
- if val, ok := envData[constants.EnvKeyRobloxClientSecret]; !ok || val == "" {
- envData[constants.EnvKeyRobloxClientSecret] = osRobloxClientSecret
- }
- if osRobloxClientSecret != "" && envData[constants.EnvKeyRobloxClientSecret] != osRobloxClientSecret {
- envData[constants.EnvKeyRobloxClientSecret] = osRobloxClientSecret
- }
-
- if val, ok := envData[constants.EnvKeyResetPasswordURL]; !ok || val == "" {
- envData[constants.EnvKeyResetPasswordURL] = strings.TrimPrefix(osResetPasswordURL, "/")
- }
- if osResetPasswordURL != "" && envData[constants.EnvKeyResetPasswordURL] != osResetPasswordURL {
- envData[constants.EnvKeyResetPasswordURL] = osResetPasswordURL
- }
-
- if val, ok := envData[constants.EnvKeyOrganizationName]; !ok || val == "" {
- envData[constants.EnvKeyOrganizationName] = osOrganizationName
- }
- if osOrganizationName != "" && envData[constants.EnvKeyOrganizationName] != osOrganizationName {
- envData[constants.EnvKeyOrganizationName] = osOrganizationName
- }
-
- if val, ok := envData[constants.EnvKeyOrganizationLogo]; !ok || val == "" {
- envData[constants.EnvKeyOrganizationLogo] = osOrganizationLogo
- }
- if osOrganizationLogo != "" && envData[constants.EnvKeyOrganizationLogo] != osOrganizationLogo {
- envData[constants.EnvKeyOrganizationLogo] = osOrganizationLogo
- }
-
- if _, ok := envData[constants.EnvKeyAppCookieSecure]; !ok {
- if osAppCookieSecure == "" {
- envData[constants.EnvKeyAppCookieSecure] = true
- } else {
- envData[constants.EnvKeyAppCookieSecure] = osAppCookieSecure == "true"
- }
- }
- if osAppCookieSecure != "" {
- boolValue, err := strconv.ParseBool(osAppCookieSecure)
- if err != nil {
- return err
- }
- if boolValue != envData[constants.EnvKeyAppCookieSecure].(bool) {
- envData[constants.EnvKeyAppCookieSecure] = boolValue
- }
- }
-
- if _, ok := envData[constants.EnvKeyAdminCookieSecure]; !ok {
- if osAdminCookieSecure == "" {
- envData[constants.EnvKeyAdminCookieSecure] = true
- } else {
- envData[constants.EnvKeyAdminCookieSecure] = osAdminCookieSecure == "true"
- }
- }
- if osAdminCookieSecure != "" {
- boolValue, err := strconv.ParseBool(osAdminCookieSecure)
- if err != nil {
- return err
- }
- if boolValue != envData[constants.EnvKeyAdminCookieSecure].(bool) {
- envData[constants.EnvKeyAdminCookieSecure] = boolValue
- }
- }
-
- if _, ok := envData[constants.EnvKeyDisableBasicAuthentication]; !ok {
- envData[constants.EnvKeyDisableBasicAuthentication] = osDisableBasicAuthentication == "true"
- }
- if osDisableBasicAuthentication != "" {
- boolValue, err := strconv.ParseBool(osDisableBasicAuthentication)
- if err != nil {
- return err
- }
- if boolValue != envData[constants.EnvKeyDisableBasicAuthentication].(bool) {
- envData[constants.EnvKeyDisableBasicAuthentication] = boolValue
- }
- }
-
- if _, ok := envData[constants.EnvKeyDisableMobileBasicAuthentication]; !ok {
- envData[constants.EnvKeyDisableMobileBasicAuthentication] = osDisableBasicAuthentication == "true"
- }
- if osDisableMobileBasicAuthentication != "" {
- boolValue, err := strconv.ParseBool(osDisableMobileBasicAuthentication)
- if err != nil {
- return err
- }
- if boolValue != envData[constants.EnvKeyDisableMobileBasicAuthentication].(bool) {
- envData[constants.EnvKeyDisableMobileBasicAuthentication] = boolValue
- }
- }
-
- if _, ok := envData[constants.EnvKeyDisableEmailVerification]; !ok {
- envData[constants.EnvKeyDisableEmailVerification] = osDisableEmailVerification == "true"
- }
- if osDisableEmailVerification != "" {
- boolValue, err := strconv.ParseBool(osDisableEmailVerification)
- if err != nil {
- return err
- }
- if boolValue != envData[constants.EnvKeyDisableEmailVerification].(bool) {
- envData[constants.EnvKeyDisableEmailVerification] = boolValue
- }
- }
-
- if _, ok := envData[constants.EnvKeyDisableMagicLinkLogin]; !ok {
- envData[constants.EnvKeyDisableMagicLinkLogin] = osDisableMagicLinkLogin == "true"
- }
- if osDisableMagicLinkLogin != "" {
- boolValue, err := strconv.ParseBool(osDisableMagicLinkLogin)
- if err != nil {
- return err
- }
- if boolValue != envData[constants.EnvKeyDisableMagicLinkLogin] {
- envData[constants.EnvKeyDisableMagicLinkLogin] = boolValue
- }
- }
-
- if _, ok := envData[constants.EnvKeyDisableLoginPage]; !ok {
- envData[constants.EnvKeyDisableLoginPage] = osDisableLoginPage == "true"
- }
- if osDisableLoginPage != "" {
- boolValue, err := strconv.ParseBool(osDisableLoginPage)
- if err != nil {
- return err
- }
- if boolValue != envData[constants.EnvKeyDisableLoginPage].(bool) {
- envData[constants.EnvKeyDisableLoginPage] = boolValue
- }
- }
-
- if _, ok := envData[constants.EnvKeyDisableSignUp]; !ok {
- envData[constants.EnvKeyDisableSignUp] = osDisableSignUp == "true"
- }
- if osDisableSignUp != "" {
- boolValue, err := strconv.ParseBool(osDisableSignUp)
- if err != nil {
- return err
- }
- if boolValue != envData[constants.EnvKeyDisableSignUp].(bool) {
- envData[constants.EnvKeyDisableSignUp] = boolValue
- }
- }
-
- if _, ok := envData[constants.EnvKeyDisableRedisForEnv]; !ok {
- envData[constants.EnvKeyDisableRedisForEnv] = osDisableRedisForEnv == "true"
- }
- if osDisableRedisForEnv != "" {
- boolValue, err := strconv.ParseBool(osDisableRedisForEnv)
- if err != nil {
- return err
- }
- if boolValue != envData[constants.EnvKeyDisableRedisForEnv].(bool) {
- envData[constants.EnvKeyDisableRedisForEnv] = boolValue
- }
- }
-
- if _, ok := envData[constants.EnvKeyDisableStrongPassword]; !ok {
- envData[constants.EnvKeyDisableStrongPassword] = osDisableStrongPassword == "true"
- }
- if osDisableStrongPassword != "" {
- boolValue, err := strconv.ParseBool(osDisableStrongPassword)
- if err != nil {
- return err
- }
- if boolValue != envData[constants.EnvKeyDisableStrongPassword].(bool) {
- envData[constants.EnvKeyDisableStrongPassword] = boolValue
- }
- }
-
- if _, ok := envData[constants.EnvKeyEnforceMultiFactorAuthentication]; !ok {
- envData[constants.EnvKeyEnforceMultiFactorAuthentication] = osEnforceMultiFactorAuthentication == "true"
- }
- if osEnforceMultiFactorAuthentication != "" {
- boolValue, err := strconv.ParseBool(osEnforceMultiFactorAuthentication)
- if err != nil {
- return err
- }
- if boolValue != envData[constants.EnvKeyEnforceMultiFactorAuthentication].(bool) {
- envData[constants.EnvKeyEnforceMultiFactorAuthentication] = boolValue
- }
- }
-
- if _, ok := envData[constants.EnvKeyDisableMultiFactorAuthentication]; !ok {
- envData[constants.EnvKeyDisableMultiFactorAuthentication] = osDisableMultiFactorAuthentication == "true"
- }
- if osDisableMultiFactorAuthentication != "" {
- boolValue, err := strconv.ParseBool(osDisableMultiFactorAuthentication)
- if err != nil {
- return err
- }
- if boolValue != envData[constants.EnvKeyDisableMultiFactorAuthentication].(bool) {
- envData[constants.EnvKeyDisableMultiFactorAuthentication] = boolValue
- }
- }
-
- // no need to add nil check as its already done above
- if envData[constants.EnvKeySmtpHost] == "" || envData[constants.EnvKeySmtpUsername] == "" || envData[constants.EnvKeySmtpPassword] == "" || envData[constants.EnvKeySenderEmail] == "" && envData[constants.EnvKeySmtpPort] == "" {
- envData[constants.EnvKeyDisableEmailVerification] = true
- envData[constants.EnvKeyDisableMagicLinkLogin] = true
- envData[constants.EnvKeyIsEmailServiceEnabled] = false
- envData[constants.EnvKeyDisableMailOTPLogin] = true
- }
-
- if envData[constants.EnvKeySmtpHost] != "" && envData[constants.EnvKeySmtpUsername] != "" && envData[constants.EnvKeySmtpPassword] != "" && envData[constants.EnvKeySenderEmail] != "" && envData[constants.EnvKeySmtpPort] != "" {
- envData[constants.EnvKeyIsEmailServiceEnabled] = true
- }
-
- if envData[constants.EnvKeyDisableEmailVerification].(bool) {
- envData[constants.EnvKeyDisableMagicLinkLogin] = true
- }
-
- if val, ok := envData[constants.EnvKeyAllowedOrigins]; !ok || val == "" {
- envData[constants.EnvKeyAllowedOrigins] = osAllowedOrigins
- if envData[constants.EnvKeyAllowedOrigins] == "" {
- envData[constants.EnvKeyAllowedOrigins] = "*"
- }
- }
- if osAllowedOrigins != "" && envData[constants.EnvKeyAllowedOrigins] != osAllowedOrigins {
- envData[constants.EnvKeyAllowedOrigins] = osAllowedOrigins
- }
-
- if val, ok := envData[constants.EnvKeyRoles]; !ok || val == "" {
- envData[constants.EnvKeyRoles] = osRoles
- if envData[constants.EnvKeyRoles] == "" {
- envData[constants.EnvKeyRoles] = "user"
- }
- }
- if osRoles != "" && envData[constants.EnvKeyRoles] != osRoles {
- envData[constants.EnvKeyRoles] = osRoles
- }
- roles := strings.Split(envData[constants.EnvKeyRoles].(string), ",")
-
- if val, ok := envData[constants.EnvKeyDefaultRoles]; !ok || val == "" {
- envData[constants.EnvKeyDefaultRoles] = osDefaultRoles
- if envData[constants.EnvKeyDefaultRoles] == "" {
- envData[constants.EnvKeyDefaultRoles] = "user"
- }
- }
- if osDefaultRoles != "" && envData[constants.EnvKeyDefaultRoles] != osDefaultRoles {
- envData[constants.EnvKeyDefaultRoles] = osDefaultRoles
- }
- defaultRoles := strings.Split(envData[constants.EnvKeyDefaultRoles].(string), ",")
- if len(defaultRoles) == 0 {
- defaultRoles = []string{roles[0]}
- }
-
- for _, role := range defaultRoles {
- if !utils.StringSliceContains(roles, role) {
- return fmt.Errorf("Default role %s is not defined in roles", role)
- }
- }
-
- if val, ok := envData[constants.EnvKeyProtectedRoles]; !ok || val == "" {
- envData[constants.EnvKeyProtectedRoles] = osProtectedRoles
- }
- if osProtectedRoles != "" && envData[constants.EnvKeyProtectedRoles] != osProtectedRoles {
- envData[constants.EnvKeyProtectedRoles] = osProtectedRoles
- }
-
- if val, ok := envData[constants.EnvKeyDefaultAuthorizeResponseType]; !ok || val == "" {
- envData[constants.EnvKeyDefaultAuthorizeResponseType] = osAuthorizeResponseType
- // Set the default value to token type
- if envData[constants.EnvKeyDefaultAuthorizeResponseType] == "" {
- envData[constants.EnvKeyDefaultAuthorizeResponseType] = constants.ResponseTypeToken
- }
- }
- if osAuthorizeResponseType != "" && envData[constants.EnvKeyDefaultAuthorizeResponseType] != osAuthorizeResponseType {
- envData[constants.EnvKeyDefaultAuthorizeResponseType] = osAuthorizeResponseType
- }
-
- if val, ok := envData[constants.EnvKeyDefaultAuthorizeResponseMode]; !ok || val == "" {
- envData[constants.EnvKeyDefaultAuthorizeResponseMode] = osAuthorizeResponseMode
- // Set the default value to token type
- if envData[constants.EnvKeyDefaultAuthorizeResponseMode] == "" {
- envData[constants.EnvKeyDefaultAuthorizeResponseMode] = constants.ResponseModeQuery
- }
- }
- if osAuthorizeResponseMode != "" && envData[constants.EnvKeyDefaultAuthorizeResponseMode] != osAuthorizeResponseMode {
- envData[constants.EnvKeyDefaultAuthorizeResponseMode] = osAuthorizeResponseMode
- }
-
- if val, ok := envData[constants.EnvKeyTwilioAPISecret]; !ok || val == "" {
- envData[constants.EnvKeyTwilioAPISecret] = osTwilioApiSecret
- }
- if osTwilioApiSecret != "" && envData[constants.EnvKeyTwilioAPISecret] != osTwilioApiSecret {
- envData[constants.EnvKeyTwilioAPISecret] = osTwilioApiSecret
- }
-
- if val, ok := envData[constants.EnvKeyTwilioAPIKey]; !ok || val == "" {
- envData[constants.EnvKeyTwilioAPIKey] = osTwilioApiKey
- }
- if osTwilioApiKey != "" && envData[constants.EnvKeyTwilioAPIKey] != osTwilioApiKey {
- envData[constants.EnvKeyTwilioAPIKey] = osTwilioApiKey
- }
-
- if val, ok := envData[constants.EnvKeyTwilioAccountSID]; !ok || val == "" {
- envData[constants.EnvKeyTwilioAccountSID] = osTwilioAccountSid
- }
- if osTwilioAccountSid != "" && envData[constants.EnvKeyTwilioAccountSID] != osTwilioAccountSid {
- envData[constants.EnvKeyTwilioAccountSID] = osTwilioAccountSid
- }
-
- if val, ok := envData[constants.EnvKeyTwilioSender]; !ok || val == "" {
- envData[constants.EnvKeyTwilioSender] = osTwilioSender
- }
- if osTwilioSender != "" && envData[constants.EnvKeyTwilioSender] != osTwilioSender {
- envData[constants.EnvKeyTwilioSender] = osTwilioSender
- }
-
- if _, ok := envData[constants.EnvKeyDisablePhoneVerification]; !ok {
- envData[constants.EnvKeyDisablePhoneVerification] = osDisablePhoneVerification == "false"
- }
- if osDisablePhoneVerification != "" {
- boolValue, err := strconv.ParseBool(osDisablePhoneVerification)
- if err != nil {
- return err
- }
- if boolValue != envData[constants.EnvKeyDisablePhoneVerification] {
- envData[constants.EnvKeyDisablePhoneVerification] = boolValue
- }
- }
-
- if envData[constants.EnvKeyTwilioAPIKey] == "" || envData[constants.EnvKeyTwilioAPISecret] == "" || envData[constants.EnvKeyTwilioAccountSID] == "" || envData[constants.EnvKeyTwilioSender] == "" {
- envData[constants.EnvKeyDisablePhoneVerification] = true
- envData[constants.EnvKeyIsSMSServiceEnabled] = false
- }
- if envData[constants.EnvKeyTwilioAPIKey] != "" && envData[constants.EnvKeyTwilioAPISecret] != "" && envData[constants.EnvKeyTwilioAccountSID] != "" && envData[constants.EnvKeyTwilioSender] != "" {
- envData[constants.EnvKeyDisablePhoneVerification] = false
- envData[constants.EnvKeyIsSMSServiceEnabled] = true
- }
-
- if _, ok := envData[constants.EnvKeyDisablePlayGround]; !ok {
- envData[constants.EnvKeyDisablePlayGround] = osDisablePlayground == "true"
- }
- if osDisablePlayground != "" {
- boolValue, err := strconv.ParseBool(osDisablePlayground)
- if err != nil {
- return err
- }
- if boolValue != envData[constants.EnvKeyDisablePlayGround].(bool) {
- envData[constants.EnvKeyDisablePlayGround] = boolValue
- }
- }
- // TODO: remove after beta launch
- envData[constants.EnvKeyDisableTOTPLogin] = true
- if _, ok := envData[constants.EnvKeyDisableTOTPLogin]; !ok {
- envData[constants.EnvKeyDisableTOTPLogin] = osDisableTOTPLogin == "true"
- }
- if osDisableTOTPLogin != "" {
- boolValue, err := strconv.ParseBool(osDisableTOTPLogin)
- if err != nil {
- return err
- }
- if boolValue != envData[constants.EnvKeyDisableTOTPLogin].(bool) {
- envData[constants.EnvKeyDisableTOTPLogin] = boolValue
- }
- }
-
- if _, ok := envData[constants.EnvKeyDisableMailOTPLogin]; !ok {
- envData[constants.EnvKeyDisableMailOTPLogin] = osDisableMailOTPLogin == "true"
- }
- if osDisableMailOTPLogin != "" {
- boolValue, err := strconv.ParseBool(osDisableMailOTPLogin)
- if err != nil {
- return err
- }
- if boolValue != envData[constants.EnvKeyDisableMailOTPLogin].(bool) {
- envData[constants.EnvKeyDisableMailOTPLogin] = boolValue
- }
- }
-
- err = memorystore.Provider.UpdateEnvStore(envData)
- if err != nil {
- log.Debug("Error while updating env store: ", err)
- return err
- }
- return nil
-}
diff --git a/server/env/persist_env.go b/server/env/persist_env.go
deleted file mode 100644
index a594d78eb..000000000
--- a/server/env/persist_env.go
+++ /dev/null
@@ -1,268 +0,0 @@
-package env
-
-import (
- "context"
- "encoding/json"
- "os"
- "reflect"
- "strconv"
- "strings"
-
- "github.com/google/uuid"
- log "github.com/sirupsen/logrus"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/crypto"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/db/models"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/utils"
-)
-
-func fixBackwardCompatibility(data map[string]interface{}) (bool, map[string]interface{}) {
- result := data
- // check if env data is stored in older format
- hasOlderFormat := false
- if _, ok := result["bool_env"]; ok {
- for key, value := range result["bool_env"].(map[string]interface{}) {
- result[key] = value
- }
- hasOlderFormat = true
- delete(result, "bool_env")
- }
-
- if _, ok := result["string_env"]; ok {
- for key, value := range result["string_env"].(map[string]interface{}) {
- result[key] = value
- }
- hasOlderFormat = true
- delete(result, "string_env")
- }
-
- if _, ok := result["slice_env"]; ok {
- for key, value := range result["slice_env"].(map[string]interface{}) {
- typeOfValue := reflect.TypeOf(value)
- if strings.Contains(typeOfValue.String(), "[]string") {
- result[key] = strings.Join(value.([]string), ",")
- }
- if strings.Contains(typeOfValue.String(), "[]interface") {
- result[key] = strings.Join(utils.ConvertInterfaceToStringSlice(value), ",")
- }
- }
- hasOlderFormat = true
- delete(result, "slice_env")
- }
-
- return hasOlderFormat, result
-}
-
-// GetEnvData returns the env data from database
-func GetEnvData() (map[string]interface{}, error) {
- var result map[string]interface{}
- ctx := context.Background()
- env, err := db.Provider.GetEnv(ctx)
- // config not found in db
- if err != nil || env == nil {
- log.Debug("Error while getting env data from db: ", err)
- return result, err
- }
-
- encryptionKey := env.Hash
- decryptedEncryptionKey, err := crypto.DecryptB64(encryptionKey)
- if err != nil {
- log.Debug("Error while decrypting encryption key: ", err)
- return result, err
- }
-
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyEncryptionKey, decryptedEncryptionKey)
- b64DecryptedConfig, err := crypto.DecryptB64(env.EnvData)
- if err != nil {
- log.Debug("Error while decrypting env data from B64: ", err)
- return result, err
- }
-
- decryptedConfigs, err := crypto.DecryptAESEnv([]byte(b64DecryptedConfig))
- if err != nil {
- log.Debug("Error while decrypting env data from AES: ", err)
- return result, err
- }
-
- err = json.Unmarshal(decryptedConfigs, &result)
- if err != nil {
- log.Debug("Error while unmarshalling env data: ", err)
- return result, err
- }
-
- hasOlderFormat, result := fixBackwardCompatibility(result)
-
- if hasOlderFormat {
- err = memorystore.Provider.UpdateEnvStore(result)
- if err != nil {
- log.Debug("Error while updating env store: ", err)
- return result, err
- }
-
- }
-
- return result, err
-}
-
-// PersistEnv persists the environment variables to the database
-func PersistEnv() error {
- ctx := context.Background()
- env, err := db.Provider.GetEnv(ctx)
- // config not found in db
- if err != nil || env == nil {
- // AES encryption needs 32 bit key only, so we chop off last 4 characters from 36 bit uuid
- hash := uuid.New().String()[:36-4]
- err := memorystore.Provider.UpdateEnvVariable(constants.EnvKeyEncryptionKey, hash)
- if err != nil {
- log.Debug("Error while updating encryption env variable: ", err)
- return err
- }
- encodedHash := crypto.EncryptB64(hash)
- res, err := memorystore.Provider.GetEnvStore()
- if err != nil {
- log.Debug("Error while getting env store: ", err)
- return err
- }
- encryptedConfig, err := crypto.EncryptEnvData(res)
- if err != nil {
- log.Debug("Error while encrypting env data: ", err)
- return err
- }
- env = &models.Env{
- Hash: encodedHash,
- EnvData: encryptedConfig,
- }
- _, err = db.Provider.AddEnv(ctx, env)
- if err != nil {
- log.Debug("Error while persisting env data to db: ", err)
- return err
- }
- } else {
- // decrypt the config data from db
- // decryption can be done using the hash stored in db
- encryptionKey := env.Hash
- decryptedEncryptionKey, err := crypto.DecryptB64(encryptionKey)
- if err != nil {
- log.Debug("Error while decrypting encryption key: ", err)
- return err
- }
-
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyEncryptionKey, decryptedEncryptionKey)
-
- b64DecryptedConfig, err := crypto.DecryptB64(env.EnvData)
- if err != nil {
- log.Debug("Error while decrypting env data from B64: ", err)
- return err
- }
-
- decryptedConfigs, err := crypto.DecryptAESEnv([]byte(b64DecryptedConfig))
- if err != nil {
- log.Debug("Error while decrypting env data from AES: ", err)
- return err
- }
-
- // temp store variable
- storeData := map[string]interface{}{}
-
- err = json.Unmarshal(decryptedConfigs, &storeData)
- if err != nil {
- log.Debug("Error while un-marshalling env data: ", err)
- return err
- }
-
- hasOlderFormat, result := fixBackwardCompatibility(storeData)
- if hasOlderFormat {
- err = memorystore.Provider.UpdateEnvStore(result)
- if err != nil {
- log.Debug("Error while updating env store: ", err)
- return err
- }
-
- }
-
- // if env is changed via env file or OS env
- // give that higher preference and update db, but we don't recommend it
-
- hasChanged := false
- for key, value := range storeData {
- // don't override unexposed envs
- // check only for derivative keys
- // No need to check for ENCRYPTION_KEY which special key we use for encrypting config data
- // as we have removed it from json
- if key != constants.EnvKeyEncryptionKey {
- envValue := strings.TrimSpace(os.Getenv(key))
- if envValue != "" {
- switch key {
- case constants.EnvKeyIsProd, constants.EnvKeyDisableBasicAuthentication, constants.EnvKeyDisableMobileBasicAuthentication, constants.EnvKeyDisableEmailVerification, constants.EnvKeyDisableLoginPage, constants.EnvKeyDisableMagicLinkLogin, constants.EnvKeyDisableSignUp, constants.EnvKeyDisableRedisForEnv, constants.EnvKeyDisableStrongPassword, constants.EnvKeyIsEmailServiceEnabled, constants.EnvKeyIsSMSServiceEnabled, constants.EnvKeyEnforceMultiFactorAuthentication, constants.EnvKeyDisableMultiFactorAuthentication, constants.EnvKeyAdminCookieSecure, constants.EnvKeyAppCookieSecure, constants.EnvKeyDisablePhoneVerification, constants.EnvKeyDisablePlayGround, constants.EnvKeyDisableTOTPLogin, constants.EnvKeyDisableMailOTPLogin:
- if envValueBool, err := strconv.ParseBool(envValue); err == nil {
- if value.(bool) != envValueBool {
- storeData[key] = envValueBool
- hasChanged = true
- }
- }
- default:
- if value != nil && value.(string) != envValue {
- storeData[key] = envValue
- hasChanged = true
- }
- }
- }
- }
- }
-
- // handle derivative cases like disabling email verification & magic login
- // in case SMTP is off but env is set to true
- if storeData[constants.EnvKeySmtpHost] == "" || storeData[constants.EnvKeySmtpUsername] == "" || storeData[constants.EnvKeySmtpPassword] == "" || storeData[constants.EnvKeySenderEmail] == "" && storeData[constants.EnvKeySmtpPort] == "" {
- storeData[constants.EnvKeyIsEmailServiceEnabled] = false
-
- if val, ok := storeData[constants.EnvKeyDisableEmailVerification]; ok && val != nil && !val.(bool) {
- storeData[constants.EnvKeyDisableEmailVerification] = true
- hasChanged = true
- }
-
- if val, ok := storeData[constants.EnvKeyDisableMagicLinkLogin]; ok && val != nil && !val.(bool) {
- storeData[constants.EnvKeyDisableMagicLinkLogin] = true
- hasChanged = true
- }
-
- if val, ok := storeData[constants.EnvKeyDisableMailOTPLogin]; ok && val != nil && !val.(bool) {
- storeData[constants.EnvKeyDisableMailOTPLogin] = true
- hasChanged = true
- }
- }
-
- err = memorystore.Provider.UpdateEnvStore(storeData)
- if err != nil {
- log.Debug("Error while updating env store: ", err)
- return err
- }
-
- jwk, err := crypto.GenerateJWKBasedOnEnv()
- if err != nil {
- log.Debug("Error while generating JWK: ", err)
- return err
- }
- // updating jwk
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyJWK, jwk)
-
- if hasChanged {
- encryptedConfig, err := crypto.EncryptEnvData(storeData)
- if err != nil {
- log.Debug("Error while encrypting env data: ", err)
- return err
- }
-
- env.EnvData = encryptedConfig
- _, err = db.Provider.UpdateEnv(ctx, env)
- if err != nil {
- log.Debug("Failed to Update Config: ", err)
- return err
- }
- }
- }
-
- return nil
-}
diff --git a/server/handlers/dashboard.go b/server/handlers/dashboard.go
deleted file mode 100644
index 55d1534de..000000000
--- a/server/handlers/dashboard.go
+++ /dev/null
@@ -1,26 +0,0 @@
-package handlers
-
-import (
- "net/http"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/gin-gonic/gin"
-)
-
-// DashboardHandler is the handler for the /dashboard route
-func DashboardHandler() gin.HandlerFunc {
- return func(c *gin.Context) {
- isOnboardingCompleted := false
- adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
- if err != nil || adminSecret != "" {
- isOnboardingCompleted = true
- }
-
- c.HTML(http.StatusOK, "dashboard.tmpl", gin.H{
- "data": map[string]interface{}{
- "isOnboardingCompleted": isOnboardingCompleted,
- },
- })
- }
-}
diff --git a/server/handlers/graphql.go b/server/handlers/graphql.go
deleted file mode 100644
index 367a9569a..000000000
--- a/server/handlers/graphql.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package handlers
-
-import (
- "github.com/99designs/gqlgen/graphql/handler"
- "github.com/authorizerdev/authorizer/server/graph"
- "github.com/authorizerdev/authorizer/server/graph/generated"
- "github.com/gin-gonic/gin"
-)
-
-// GraphqlHandler is the main handler that handels all the graphql requests
-func GraphqlHandler() gin.HandlerFunc {
- // NewExecutableSchema and Config are in the generated.go file
- // Resolver is in the resolver.go file
- h := handler.NewDefaultServer(generated.NewExecutableSchema(generated.Config{Resolvers: &graph.Resolver{}}))
-
- return func(c *gin.Context) {
- h.ServeHTTP(c.Writer, c.Request)
- }
-}
diff --git a/server/handlers/jwks.go b/server/handlers/jwks.go
deleted file mode 100644
index 1d71967d6..000000000
--- a/server/handlers/jwks.go
+++ /dev/null
@@ -1,38 +0,0 @@
-package handlers
-
-import (
- "encoding/json"
-
- "github.com/gin-gonic/gin"
- log "github.com/sirupsen/logrus"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/memorystore"
-)
-
-func JWKsHandler() gin.HandlerFunc {
- return func(c *gin.Context) {
- var data map[string]string
- jwk, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyJWK)
- if err != nil {
- log.Debug("Error getting JWK from memorystore: ", err)
- c.JSON(500, gin.H{
- "error": err.Error(),
- })
- return
- }
- err = json.Unmarshal([]byte(jwk), &data)
- if err != nil {
- log.Debug("Failed to parse JWK: ", err)
- c.JSON(500, gin.H{
- "error": err.Error(),
- })
- return
- }
- c.JSON(200, gin.H{
- "keys": []map[string]string{
- data,
- },
- })
- }
-}
diff --git a/server/handlers/oauth_login.go b/server/handlers/oauth_login.go
deleted file mode 100644
index b41485f0a..000000000
--- a/server/handlers/oauth_login.go
+++ /dev/null
@@ -1,296 +0,0 @@
-package handlers
-
-import (
- "net/http"
- "strings"
-
- "golang.org/x/oauth2"
-
- "github.com/gin-gonic/gin"
- "github.com/google/uuid"
- log "github.com/sirupsen/logrus"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/oauth"
- "github.com/authorizerdev/authorizer/server/parsers"
- "github.com/authorizerdev/authorizer/server/utils"
- "github.com/authorizerdev/authorizer/server/validators"
-)
-
-// OAuthLoginHandler set host in the oauth state that is useful for redirecting to oauth_callback
-func OAuthLoginHandler() gin.HandlerFunc {
- return func(c *gin.Context) {
- hostname := parsers.GetHost(c)
- // deprecating redirectURL instead use redirect_uri
- redirectURI := strings.TrimSpace(c.Query("redirectURL"))
- if redirectURI == "" {
- redirectURI = strings.TrimSpace(c.Query("redirect_uri"))
- }
- roles := strings.TrimSpace(c.Query("roles"))
- state := strings.TrimSpace(c.Query("state"))
- scopeString := strings.TrimSpace(c.Query("scope"))
-
- if redirectURI == "" {
- log.Debug("redirect_uri is empty")
- c.JSON(400, gin.H{
- "error": "invalid redirect uri",
- })
- return
- }
-
- if state == "" {
- log.Debug("state is empty. creating a new state")
- state = uuid.New().String()
- }
-
- var scope []string
- if scopeString == "" {
- scope = []string{"openid", "profile", "email"}
- } else {
- scope = strings.Split(scopeString, " ")
- }
-
- if roles != "" {
- // validate role
- rolesSplit := strings.Split(roles, ",")
-
- // use protected roles verification for admin login only.
- // though if not associated with user, it will be rejected from oauth_callback
- rolesString, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyRoles)
- roles := []string{}
- if err != nil {
- log.Debug("Error getting roles: ", err)
- rolesString = ""
- } else {
- roles = strings.Split(rolesString, ",")
- }
-
- protectedRolesString, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyProtectedRoles)
- protectedRoles := []string{}
- if err != nil {
- log.Debug("Error getting protected roles: ", err)
- protectedRolesString = ""
- } else {
- protectedRoles = strings.Split(protectedRolesString, ",")
- }
-
- if !validators.IsValidRoles(rolesSplit, append([]string{}, append(roles, protectedRoles...)...)) {
- log.Debug("Invalid roles: ", roles)
- c.JSON(400, gin.H{
- "error": "invalid role",
- })
- return
- }
- } else {
- defaultRoles, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyDefaultRoles)
- if err != nil {
- log.Debug("Error getting default roles: ", err)
- c.JSON(400, gin.H{
- "error": "invalid role",
- })
- return
- }
- roles = defaultRoles
-
- }
-
- oauthStateString := state + "___" + redirectURI + "___" + roles + "___" + strings.Join(scope, " ")
-
- provider := c.Param("oauth_provider")
- isProviderConfigured := true
- switch provider {
- case constants.AuthRecipeMethodGoogle:
- if oauth.OAuthProviders.GoogleConfig == nil {
- log.Debug("Google OAuth provider is not configured")
- isProviderConfigured = false
- break
- }
- err := memorystore.Provider.SetState(oauthStateString, constants.AuthRecipeMethodGoogle)
- if err != nil {
- log.Debug("Error setting state: ", err)
- c.JSON(500, gin.H{
- "error": "internal server error",
- })
- return
- }
- // during the init of OAuthProvider authorizer url might be empty
- oauth.OAuthProviders.GoogleConfig.RedirectURL = hostname + "/oauth_callback/" + constants.AuthRecipeMethodGoogle
- url := oauth.OAuthProviders.GoogleConfig.AuthCodeURL(oauthStateString)
- c.Redirect(http.StatusTemporaryRedirect, url)
- case constants.AuthRecipeMethodGithub:
- if oauth.OAuthProviders.GithubConfig == nil {
- log.Debug("Github OAuth provider is not configured")
- isProviderConfigured = false
- break
- }
- err := memorystore.Provider.SetState(oauthStateString, constants.AuthRecipeMethodGithub)
- if err != nil {
- log.Debug("Error setting state: ", err)
- c.JSON(500, gin.H{
- "error": "internal server error",
- })
- return
- }
- oauth.OAuthProviders.GithubConfig.RedirectURL = hostname + "/oauth_callback/" + constants.AuthRecipeMethodGithub
- url := oauth.OAuthProviders.GithubConfig.AuthCodeURL(oauthStateString)
- c.Redirect(http.StatusTemporaryRedirect, url)
- case constants.AuthRecipeMethodFacebook:
- if oauth.OAuthProviders.FacebookConfig == nil {
- log.Debug("Facebook OAuth provider is not configured")
- isProviderConfigured = false
- break
- }
- err := memorystore.Provider.SetState(oauthStateString, constants.AuthRecipeMethodFacebook)
- if err != nil {
- log.Debug("Error setting state: ", err)
- c.JSON(500, gin.H{
- "error": "internal server error",
- })
- return
- }
- oauth.OAuthProviders.FacebookConfig.RedirectURL = hostname + "/oauth_callback/" + constants.AuthRecipeMethodFacebook
- url := oauth.OAuthProviders.FacebookConfig.AuthCodeURL(oauthStateString)
- c.Redirect(http.StatusTemporaryRedirect, url)
- case constants.AuthRecipeMethodLinkedIn:
- if oauth.OAuthProviders.LinkedInConfig == nil {
- log.Debug("Linkedin OAuth provider is not configured")
- isProviderConfigured = false
- break
- }
- err := memorystore.Provider.SetState(oauthStateString, constants.AuthRecipeMethodLinkedIn)
- if err != nil {
- log.Debug("Error setting state: ", err)
- c.JSON(500, gin.H{
- "error": "internal server error",
- })
- return
- }
- oauth.OAuthProviders.LinkedInConfig.RedirectURL = hostname + "/oauth_callback/" + constants.AuthRecipeMethodLinkedIn
- url := oauth.OAuthProviders.LinkedInConfig.AuthCodeURL(oauthStateString)
- c.Redirect(http.StatusTemporaryRedirect, url)
- case constants.AuthRecipeMethodTwitter:
- if oauth.OAuthProviders.TwitterConfig == nil {
- log.Debug("Twitter OAuth provider is not configured")
- isProviderConfigured = false
- break
- }
-
- verifier, challenge := utils.GenerateCodeChallenge()
-
- err := memorystore.Provider.SetState(oauthStateString, verifier)
- if err != nil {
- log.Debug("Error setting state: ", err)
- c.JSON(500, gin.H{
- "error": "internal server error",
- })
- return
- }
- oauth.OAuthProviders.TwitterConfig.RedirectURL = hostname + "/oauth_callback/" + constants.AuthRecipeMethodTwitter
- url := oauth.OAuthProviders.TwitterConfig.AuthCodeURL(oauthStateString, oauth2.SetAuthURLParam("code_challenge", challenge), oauth2.SetAuthURLParam("code_challenge_method", "S256"))
- c.Redirect(http.StatusTemporaryRedirect, url)
-
- case constants.AuthRecipeMethodDiscord:
- if oauth.OAuthProviders.DiscordConfig == nil {
- log.Debug("Discord OAuth provider is not configured")
- isProviderConfigured = false
- break
- }
- err := memorystore.Provider.SetState(oauthStateString, constants.AuthRecipeMethodDiscord)
- if err != nil {
- log.Debug("Error setting state: ", err)
- c.JSON(500, gin.H{
- "error": "internal server error",
- })
- return
- }
- oauth.OAuthProviders.DiscordConfig.RedirectURL = hostname + "/oauth_callback/" + constants.AuthRecipeMethodDiscord
- url := oauth.OAuthProviders.DiscordConfig.AuthCodeURL(oauthStateString)
- c.Redirect(http.StatusTemporaryRedirect, url)
- case constants.AuthRecipeMethodApple:
- if oauth.OAuthProviders.AppleConfig == nil {
- log.Debug("Apple OAuth provider is not configured")
- isProviderConfigured = false
- break
- }
- err := memorystore.Provider.SetState(oauthStateString, constants.AuthRecipeMethodApple)
- if err != nil {
- log.Debug("Error setting state: ", err)
- c.JSON(500, gin.H{
- "error": "internal server error",
- })
- return
- }
- oauth.OAuthProviders.AppleConfig.RedirectURL = hostname + "/oauth_callback/" + constants.AuthRecipeMethodApple
- // there is scope encoding issue with oauth2 and how apple expects, hence added scope manually
- // check: https://github.com/golang/oauth2/issues/449
- url := oauth.OAuthProviders.AppleConfig.AuthCodeURL(oauthStateString, oauth2.SetAuthURLParam("response_mode", "form_post")) + "&scope=name email"
- c.Redirect(http.StatusTemporaryRedirect, url)
- case constants.AuthRecipeMethodMicrosoft:
- if oauth.OAuthProviders.MicrosoftConfig == nil {
- log.Debug("Microsoft OAuth provider is not configured")
- isProviderConfigured = false
- break
- }
- err := memorystore.Provider.SetState(oauthStateString, constants.AuthRecipeMethodMicrosoft)
- if err != nil {
- log.Debug("Error setting state: ", err)
- c.JSON(500, gin.H{
- "error": "internal server error",
- })
- return
- }
- // during the init of OAuthProvider authorizer url might be empty
- oauth.OAuthProviders.MicrosoftConfig.RedirectURL = hostname + "/oauth_callback/" + constants.AuthRecipeMethodMicrosoft
- url := oauth.OAuthProviders.MicrosoftConfig.AuthCodeURL(oauthStateString)
- c.Redirect(http.StatusTemporaryRedirect, url)
- case constants.AuthRecipeMethodTwitch:
- if oauth.OAuthProviders.TwitchConfig == nil {
- log.Debug("Twitch OAuth provider is not configured")
- isProviderConfigured = false
- break
- }
- err := memorystore.Provider.SetState(oauthStateString, constants.AuthRecipeMethodTwitch)
- if err != nil {
- log.Debug("Error setting state: ", err)
- c.JSON(500, gin.H{
- "error": "internal server error",
- })
- return
- }
- // during the init of OAuthProvider authorizer url might be empty
- oauth.OAuthProviders.TwitchConfig.RedirectURL = hostname + "/oauth_callback/" + constants.AuthRecipeMethodTwitch
- url := oauth.OAuthProviders.TwitchConfig.AuthCodeURL(oauthStateString)
- c.Redirect(http.StatusTemporaryRedirect, url)
- case constants.AuthRecipeMethodRoblox:
- if oauth.OAuthProviders.RobloxConfig == nil {
- log.Debug("RobloxConfig OAuth provider is not configured")
- isProviderConfigured = false
- break
- }
- err := memorystore.Provider.SetState(oauthStateString, constants.AuthRecipeMethodRoblox)
- if err != nil {
- log.Debug("Error setting state: ", err)
- c.JSON(500, gin.H{
- "error": "internal server error",
- })
- return
- }
- // during the init of OAuthProvider authorizer url might be empty
- oauth.OAuthProviders.RobloxConfig.RedirectURL = hostname + "/oauth_callback/" + constants.AuthRecipeMethodRoblox
- url := oauth.OAuthProviders.RobloxConfig.AuthCodeURL(oauthStateString)
- c.Redirect(http.StatusTemporaryRedirect, url)
- default:
- log.Debug("Invalid oauth provider: ", provider)
- c.JSON(422, gin.H{
- "message": "Invalid oauth provider",
- })
- }
-
- if !isProviderConfigured {
- c.JSON(422, gin.H{
- "message": provider + " not configured",
- })
- }
- }
-}
diff --git a/server/handlers/playground.go b/server/handlers/playground.go
deleted file mode 100644
index 14ce52fc2..000000000
--- a/server/handlers/playground.go
+++ /dev/null
@@ -1,44 +0,0 @@
-package handlers
-
-import (
- "net/http"
-
- "github.com/99designs/gqlgen/graphql/playground"
- "github.com/gin-gonic/gin"
-
- log "github.com/sirupsen/logrus"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/token"
-)
-
-// PlaygroundHandler is the handler for the /playground route
-func PlaygroundHandler() gin.HandlerFunc {
- return func(c *gin.Context) {
- var h http.HandlerFunc
-
- disablePlayground, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisablePlayGround)
- if err != nil {
- log.Debug("error while getting disable playground value")
- disablePlayground = false
- }
-
- // if env set to false, then check if logged in as super admin, if logged in then return graphql else 401 error
- // if env set to true, then disabled the playground with 404 error
- if !disablePlayground {
- if token.IsSuperAdmin(c) {
- h = playground.Handler("GraphQL", "/graphql")
- } else {
- log.Debug("not logged in as super admin")
- c.JSON(http.StatusUnauthorized, gin.H{"error": "not logged in as super admin"})
- return
- }
- } else {
- log.Debug("playground is disabled")
- c.JSON(http.StatusNotFound, gin.H{"error": "playground is disabled"})
- return
- }
- h.ServeHTTP(c.Writer, c.Request)
- }
-}
diff --git a/server/handlers/revoke_refresh_token.go b/server/handlers/revoke_refresh_token.go
deleted file mode 100644
index 366efd72c..000000000
--- a/server/handlers/revoke_refresh_token.go
+++ /dev/null
@@ -1,76 +0,0 @@
-package handlers
-
-import (
- "net/http"
- "strings"
-
- "github.com/gin-gonic/gin"
- log "github.com/sirupsen/logrus"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/token"
-)
-
-// RevokeRefreshTokenHandler handler to revoke refresh token
-func RevokeRefreshTokenHandler() gin.HandlerFunc {
- return func(gc *gin.Context) {
- var reqBody map[string]string
- if err := gc.BindJSON(&reqBody); err != nil {
- log.Debug("Error binding JSON: ", err)
- gc.JSON(http.StatusBadRequest, gin.H{
- "error": "error_binding_json",
- "error_description": err.Error(),
- })
- return
- }
- // get client ID
- clientID := strings.TrimSpace(reqBody["client_id"]) // kept for backward compatibility // else we expect to be present as header
- if clientID == "" {
- clientID = gc.Request.Header.Get("x-authorizer-client-id")
- }
- // get fingerprint hash
- refreshToken := strings.TrimSpace(reqBody["refresh_token"])
-
- if clientID == "" {
- log.Debug("Client ID is empty")
- gc.JSON(http.StatusBadRequest, gin.H{
- "error": "client_id_required",
- "error_description": "The client id is required",
- })
- return
- }
-
- if client, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyClientID); client != clientID || err != nil {
- log.Debug("Client ID is invalid: ", clientID)
- gc.JSON(http.StatusBadRequest, gin.H{
- "error": "invalid_client_id",
- "error_description": "The client id is invalid",
- })
- return
- }
-
- claims, err := token.ParseJWTToken(refreshToken)
- if err != nil {
- log.Debug("Client ID is invalid: ", clientID)
- gc.JSON(http.StatusBadRequest, gin.H{
- "error": err.Error(),
- "error_description": "Failed to parse jwt",
- })
- return
- }
-
- userID := claims["sub"].(string)
- loginMethod := claims["login_method"]
- sessionToken := userID
- if loginMethod != nil && loginMethod != "" {
- sessionToken = loginMethod.(string) + ":" + userID
- }
-
- memorystore.Provider.DeleteUserSession(sessionToken, claims["nonce"].(string))
-
- gc.JSON(http.StatusOK, gin.H{
- "message": "Token revoked successfully",
- })
- }
-}
diff --git a/server/logs/logs.go b/server/logs/logs.go
deleted file mode 100644
index 924548c4c..000000000
--- a/server/logs/logs.go
+++ /dev/null
@@ -1,61 +0,0 @@
-package logs
-
-import (
- "os"
-
- "github.com/sirupsen/logrus"
- log "github.com/sirupsen/logrus"
-)
-
-// 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)
-}
-
-func InitLog(cliLogLevel string) *log.Logger {
-
- // log instance for gin server
- log := logrus.New()
- log.SetFormatter(LogUTCFormatter{&logrus.JSONFormatter{}})
-
- if cliLogLevel == "" {
- cliLogLevel = os.Getenv("LOG_LEVEL")
- }
-
- var logLevel logrus.Level
- switch cliLogLevel {
- case "debug":
- logLevel = logrus.DebugLevel
- case "info":
- logLevel = logrus.InfoLevel
- case "warn":
- logLevel = logrus.WarnLevel
- case "error":
- logLevel = logrus.ErrorLevel
- case "fatal":
- logLevel = logrus.FatalLevel
- case "panic":
- logLevel = logrus.PanicLevel
- 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.
- if logLevel != logrus.InfoLevel {
- logrus.SetReportCaller(true)
- log.SetReportCaller(true)
- }
-
- return log
-}
diff --git a/server/main.go b/server/main.go
deleted file mode 100644
index 0348d2aa8..000000000
--- a/server/main.go
+++ /dev/null
@@ -1,89 +0,0 @@
-package main
-
-import (
- "flag"
- "github.com/authorizerdev/authorizer/server/authenticators"
-
- "github.com/authorizerdev/authorizer/server/cli"
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/env"
- "github.com/authorizerdev/authorizer/server/logs"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/oauth"
- "github.com/authorizerdev/authorizer/server/refs"
- "github.com/authorizerdev/authorizer/server/routes"
- "github.com/sirupsen/logrus"
-)
-
-// VERSION is used to define the version of authorizer from build tags
-var VERSION string
-
-func main() {
- cli.ARG_DB_URL = flag.String("database_url", "", "Database connection string")
- cli.ARG_DB_TYPE = flag.String("database_type", "", "Database type, possible values are postgres,mysql,sqlite")
- cli.ARG_ENV_FILE = flag.String("env_file", "", "Env file path")
- cli.ARG_LOG_LEVEL = flag.String("log_level", "", "Log level, possible values are debug,info,warn,error,fatal,panic")
- cli.ARG_REDIS_URL = flag.String("redis_url", "", "Redis connection string")
- flag.Parse()
-
- // global log level
- logrus.SetFormatter(logs.LogUTCFormatter{&logrus.JSONFormatter{}})
-
- constants.VERSION = VERSION
-
- // initialize required envs (mainly db, env file path and redis)
- err := memorystore.InitRequiredEnv()
- if err != nil {
- logrus.Fatal("Error while initializing required envs: ", err)
- }
-
- log := logs.InitLog(refs.StringValue(cli.ARG_LOG_LEVEL))
-
- // initialize memory store
- err = memorystore.InitMemStore()
- if err != nil {
- log.Fatal("Error while initializing memory store: ", err)
- }
-
- // initialize db provider
- err = db.InitDB()
- if err != nil {
- log.Fatalln("Error while initializing db: ", err)
- }
-
- // initialize all envs
- // (get if present from db else construct from os env + defaults)
- err = env.InitAllEnv()
- if err != nil {
- log.Fatalln("Error while initializing env: ", err)
- }
-
- // persist all envs
- err = env.PersistEnv()
- if err != nil {
- log.Fatalln("Error while persisting env: ", err)
- }
-
- // initialize oauth providers based on env
- err = oauth.InitOAuth()
- if err != nil {
- log.Fatalln("Error while initializing oauth: ", err)
- }
-
- err = authenticators.InitTOTPStore()
- if err != nil {
- log.Fatalln("Error while initializing authenticator: ", err)
- }
-
- router := routes.InitRouter(log)
- log.Info("Starting Authorizer: ", VERSION)
- port, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyPort)
- log.Info("Authorizer running at PORT: ", port)
- if err != nil {
- log.Info("Error while getting port from env using default port 8080: ", err)
- port = "8080"
- }
-
- router.Run(":" + port)
-}
diff --git a/server/memorystore/memory_store.go b/server/memorystore/memory_store.go
deleted file mode 100644
index a143d041c..000000000
--- a/server/memorystore/memory_store.go
+++ /dev/null
@@ -1,87 +0,0 @@
-package memorystore
-
-import (
- "encoding/json"
-
- log "github.com/sirupsen/logrus"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/memorystore/providers"
- "github.com/authorizerdev/authorizer/server/memorystore/providers/inmemory"
- "github.com/authorizerdev/authorizer/server/memorystore/providers/redis"
-)
-
-// Provider returns the current database provider
-var Provider providers.Provider
-
-// InitMemStore initializes the memory store
-func InitMemStore() error {
- var err error
-
- defaultEnvs := map[string]interface{}{
- // string envs
- constants.EnvKeyJwtRoleClaim: "role",
- constants.EnvKeyOrganizationName: "Authorizer",
- constants.EnvKeyOrganizationLogo: "https://www.authorizer.dev/images/logo.png",
-
- // boolean envs
- constants.EnvKeyDisableBasicAuthentication: false,
- constants.EnvKeyDisableMobileBasicAuthentication: false,
- constants.EnvKeyDisableMagicLinkLogin: false,
- constants.EnvKeyDisableEmailVerification: false,
- constants.EnvKeyDisableLoginPage: false,
- constants.EnvKeyDisableSignUp: false,
- constants.EnvKeyDisableStrongPassword: false,
- constants.EnvKeyIsEmailServiceEnabled: false,
- constants.EnvKeyIsSMSServiceEnabled: false,
- constants.EnvKeyEnforceMultiFactorAuthentication: false,
- constants.EnvKeyDisableMultiFactorAuthentication: false,
- constants.EnvKeyDisableTOTPLogin: false,
- constants.EnvKeyAppCookieSecure: true,
- constants.EnvKeyAdminCookieSecure: true,
- constants.EnvKeyDisablePlayGround: true,
- constants.EnvKeyDisableMailOTPLogin: true,
- }
-
- requiredEnvs := RequiredEnvStoreObj.GetRequiredEnv()
- requiredEnvMap := make(map[string]interface{})
- requiredEnvBytes, err := json.Marshal(requiredEnvs)
- if err != nil {
- log.Debug("Error while marshalling required envs: ", err)
- return err
- }
- err = json.Unmarshal(requiredEnvBytes, &requiredEnvMap)
- if err != nil {
- log.Debug("Error while unmarshalling required envs: ", err)
- return err
- }
-
- // merge default envs with required envs
- for key, val := range requiredEnvMap {
- defaultEnvs[key] = val
- }
-
- redisURL := requiredEnvs.RedisURL
- if redisURL != "" && !requiredEnvs.DisableRedisForEnv {
- log.Info("Initializing Redis memory store")
- Provider, err = redis.NewRedisProvider(redisURL)
- if err != nil {
- return err
- }
-
- // set default envs in redis
- Provider.UpdateEnvStore(defaultEnvs)
-
- return nil
- }
-
- log.Info("using in memory store to save sessions")
- // if redis url is not set use in memory store
- Provider, err = inmemory.NewInMemoryProvider()
- if err != nil {
- return err
- }
- // set default envs in local env
- Provider.UpdateEnvStore(defaultEnvs)
- return nil
-}
diff --git a/server/memorystore/providers/inmemory/provider.go b/server/memorystore/providers/inmemory/provider.go
deleted file mode 100644
index e726502a1..000000000
--- a/server/memorystore/providers/inmemory/provider.go
+++ /dev/null
@@ -1,26 +0,0 @@
-package inmemory
-
-import (
- "sync"
-
- "github.com/authorizerdev/authorizer/server/memorystore/providers/inmemory/stores"
-)
-
-type provider struct {
- mutex sync.Mutex
- sessionStore *stores.SessionStore
- mfasessionStore *stores.SessionStore
- stateStore *stores.StateStore
- envStore *stores.EnvStore
-}
-
-// NewInMemoryStore returns a new in-memory store.
-func NewInMemoryProvider() (*provider, error) {
- return &provider{
- mutex: sync.Mutex{},
- envStore: stores.NewEnvStore(),
- sessionStore: stores.NewSessionStore(),
- mfasessionStore: stores.NewSessionStore(),
- stateStore: stores.NewStateStore(),
- }, nil
-}
diff --git a/server/memorystore/providers/inmemory/provider_test.go b/server/memorystore/providers/inmemory/provider_test.go
deleted file mode 100644
index 99446a19e..000000000
--- a/server/memorystore/providers/inmemory/provider_test.go
+++ /dev/null
@@ -1,14 +0,0 @@
-package inmemory
-
-import (
- "testing"
-
- "github.com/authorizerdev/authorizer/server/memorystore/providers"
- "github.com/stretchr/testify/assert"
-)
-
-func TestInMemoryProvider(t *testing.T) {
- p, err := NewInMemoryProvider()
- assert.NoError(t, err)
- providers.ProviderTests(t, p)
-}
diff --git a/server/memorystore/providers/inmemory/stores/env_store.go b/server/memorystore/providers/inmemory/stores/env_store.go
deleted file mode 100644
index 46a909abc..000000000
--- a/server/memorystore/providers/inmemory/stores/env_store.go
+++ /dev/null
@@ -1,52 +0,0 @@
-package stores
-
-import (
- "sync"
-)
-
-// EnvStore struct to store the env variables
-type EnvStore struct {
- mutex sync.Mutex
- store map[string]interface{}
-}
-
-// NewEnvStore create a new env store
-func NewEnvStore() *EnvStore {
- return &EnvStore{
- mutex: sync.Mutex{},
- store: make(map[string]interface{}),
- }
-}
-
-// UpdateEnvStore to update the whole env store object
-func (e *EnvStore) UpdateStore(store map[string]interface{}) {
- e.mutex.Lock()
- defer e.mutex.Unlock()
-
- // just override the keys + new keys
- for key, value := range store {
- e.store[key] = value
- }
-}
-
-// GetStore returns the env store
-func (e *EnvStore) GetStore() map[string]interface{} {
- e.mutex.Lock()
- defer e.mutex.Unlock()
- return e.store
-}
-
-// Get returns the value of the key in evn store
-func (e *EnvStore) Get(key string) interface{} {
- e.mutex.Lock()
- defer e.mutex.Unlock()
- return e.store[key]
-}
-
-// Set sets the value of the key in env store
-func (e *EnvStore) Set(key string, value interface{}) {
- e.mutex.Lock()
- defer e.mutex.Unlock()
-
- e.store[key] = value
-}
diff --git a/server/memorystore/providers/provider_tests.go b/server/memorystore/providers/provider_tests.go
deleted file mode 100644
index 47f4dba66..000000000
--- a/server/memorystore/providers/provider_tests.go
+++ /dev/null
@@ -1,126 +0,0 @@
-package providers
-
-import (
- "testing"
- "time"
-
- "github.com/stretchr/testify/assert"
-)
-
-// ProviderTests runs all provider tests
-func ProviderTests(t *testing.T, p Provider) {
-
- err := p.SetUserSession("auth_provider:123", "session_token_key", "test_hash123", time.Now().Add(60*time.Second).Unix())
- assert.NoError(t, err)
- err = p.SetUserSession("auth_provider:123", "access_token_key", "test_jwt123", time.Now().Add(60*time.Second).Unix())
- assert.NoError(t, err)
- // Same user multiple session
- err = p.SetUserSession("auth_provider:123", "session_token_key1", "test_hash1123", time.Now().Add(60*time.Second).Unix())
- assert.NoError(t, err)
- err = p.SetUserSession("auth_provider:123", "access_token_key1", "test_jwt1123", time.Now().Add(60*time.Second).Unix())
- assert.NoError(t, err)
- // Different user session
- err = p.SetUserSession("auth_provider:124", "session_token_key", "test_hash124", time.Now().Add(5*time.Second).Unix())
- assert.NoError(t, err)
- err = p.SetUserSession("auth_provider:124", "access_token_key", "test_jwt124", time.Now().Add(5*time.Second).Unix())
- assert.NoError(t, err)
- // Different provider session
- err = p.SetUserSession("auth_provider1:124", "session_token_key", "test_hash124", time.Now().Add(60*time.Second).Unix())
- assert.NoError(t, err)
- err = p.SetUserSession("auth_provider1:124", "access_token_key", "test_jwt124", time.Now().Add(60*time.Second).Unix())
- assert.NoError(t, err)
- // Different provider session
- err = p.SetUserSession("auth_provider1:123", "session_token_key", "test_hash1123", time.Now().Add(60*time.Second).Unix())
- assert.NoError(t, err)
- err = p.SetUserSession("auth_provider1:123", "access_token_key", "test_jwt1123", time.Now().Add(60*time.Second).Unix())
- assert.NoError(t, err)
- // Get session
- key, err := p.GetUserSession("auth_provider:123", "session_token_key")
- assert.NoError(t, err)
- assert.Equal(t, "test_hash123", key)
- key, err = p.GetUserSession("auth_provider:123", "access_token_key")
- assert.NoError(t, err)
- assert.Equal(t, "test_jwt123", key)
- key, err = p.GetUserSession("auth_provider:124", "session_token_key")
- assert.NoError(t, err)
- assert.Equal(t, "test_hash124", key)
- key, err = p.GetUserSession("auth_provider:124", "access_token_key")
- assert.NoError(t, err)
- assert.Equal(t, "test_jwt124", key)
- // Expire some tokens and make sure they are empty
- time.Sleep(5 * time.Second)
- key, err = p.GetUserSession("auth_provider:124", "session_token_key")
- assert.Empty(t, key)
- assert.Error(t, err)
- key, err = p.GetUserSession("auth_provider:124", "access_token_key")
- assert.Empty(t, key)
- assert.Error(t, err)
- // Delete user session
- err = p.DeleteUserSession("auth_provider:123", "key")
- assert.NoError(t, err)
- err = p.DeleteUserSession("auth_provider:123", "key")
- assert.NoError(t, err)
- key, err = p.GetUserSession("auth_provider:123", "key")
- assert.Empty(t, key)
- assert.Error(t, err)
- key, err = p.GetUserSession("auth_provider:123", "access_token_key")
- assert.Empty(t, key)
- assert.Error(t, err)
- // Delete all user session
- err = p.DeleteAllUserSessions("123")
- assert.NoError(t, err)
- err = p.DeleteAllUserSessions("123")
- assert.NoError(t, err)
- key, err = p.GetUserSession("auth_provider:123", "session_token_key1")
- assert.Empty(t, key)
- assert.Error(t, err)
- key, err = p.GetUserSession("auth_provider:123", "access_token_key1")
- assert.Empty(t, key)
- assert.Error(t, err)
- key, err = p.GetUserSession("auth_provider1:123", "session_token_key")
- assert.Empty(t, key)
- assert.Error(t, err)
- key, err = p.GetUserSession("auth_provider1:123", "access_token_key")
- assert.Empty(t, key)
- assert.Error(t, err)
- // Delete namespace
- err = p.DeleteSessionForNamespace("auth_provider")
- assert.NoError(t, err)
- err = p.DeleteSessionForNamespace("auth_provider1")
- assert.NoError(t, err)
- key, err = p.GetUserSession("auth_provider:123", "session_token_key1")
- assert.Empty(t, key)
- assert.Error(t, err)
- key, err = p.GetUserSession("auth_provider:123", "access_token_key1")
- assert.Empty(t, key)
- assert.Error(t, err)
- key, err = p.GetUserSession("auth_provider1:123", "session_token_key")
- assert.Empty(t, key)
- assert.Error(t, err)
- key, err = p.GetUserSession("auth_provider1:123", "access_token_key")
- assert.Empty(t, key)
- assert.Error(t, err)
- key, err = p.GetUserSession("auth_provider:124", "session_token_key1")
- assert.Empty(t, key)
- assert.Error(t, err)
- key, err = p.GetUserSession("auth_provider:124", "access_token_key1")
- assert.Empty(t, key)
- assert.Error(t, err)
- key, err = p.GetUserSession("auth_provider1:124", "session_token_key")
- assert.Empty(t, key)
- assert.Error(t, err)
- key, err = p.GetUserSession("auth_provider1:124", "access_token_key")
- assert.Empty(t, key)
- assert.Error(t, err)
-
- err = p.SetMfaSession("auth_provider:123", "session123", time.Now().Add(60*time.Second).Unix())
- assert.NoError(t, err)
- key, err = p.GetMfaSession("auth_provider:123", "session123")
- assert.NoError(t, err)
- assert.Equal(t, "auth_provider:123", key)
- err = p.DeleteMfaSession("auth_provider:123", "session123")
- assert.NoError(t, err)
- key, err = p.GetMfaSession("auth_provider:123", "session123")
- assert.Error(t, err)
- assert.Empty(t, key)
-}
diff --git a/server/memorystore/providers/redis/provider_test.go b/server/memorystore/providers/redis/provider_test.go
deleted file mode 100644
index 280616cfb..000000000
--- a/server/memorystore/providers/redis/provider_test.go
+++ /dev/null
@@ -1,15 +0,0 @@
-package redis
-
-import (
- "testing"
-
- "github.com/stretchr/testify/assert"
-
- "github.com/authorizerdev/authorizer/server/memorystore/providers"
-)
-
-func TestRedisProvider(t *testing.T) {
- p, err := NewRedisProvider("redis://127.0.0.1:6379")
- assert.NoError(t, err)
- providers.ProviderTests(t, p)
-}
diff --git a/server/memorystore/providers/redis/store.go b/server/memorystore/providers/redis/store.go
deleted file mode 100644
index a1b21db65..000000000
--- a/server/memorystore/providers/redis/store.go
+++ /dev/null
@@ -1,220 +0,0 @@
-package redis
-
-import (
- "fmt"
- "strconv"
- "time"
-
- "github.com/authorizerdev/authorizer/server/constants"
- log "github.com/sirupsen/logrus"
-)
-
-var (
- // state store prefix
- stateStorePrefix = "authorizer_state:"
- // env store prefix
- envStorePrefix = "authorizer_env"
-)
-
-const mfaSessionPrefix = "mfa_sess_"
-
-// SetUserSession sets the user session for given user identifier in form recipe:user_id
-func (c *provider) SetUserSession(userId, key, token string, expiration int64) error {
- currentTime := time.Now()
- expireTime := time.Unix(expiration, 0)
- duration := expireTime.Sub(currentTime)
- err := c.store.Set(c.ctx, fmt.Sprintf("%s:%s", userId, key), token, duration).Err()
- if err != nil {
- log.Debug("Error saving user session to redis: ", err)
- return err
- }
- return nil
-}
-
-// GetUserSession returns the user session from redis store.
-func (c *provider) GetUserSession(userId, key string) (string, error) {
- data, err := c.store.Get(c.ctx, fmt.Sprintf("%s:%s", userId, key)).Result()
- if err != nil {
- return "", err
- }
- return data, nil
-}
-
-// DeleteUserSession deletes the user session from redis store.
-func (c *provider) DeleteUserSession(userId, key string) error {
- if err := c.store.Del(c.ctx, fmt.Sprintf("%s:%s", userId, constants.TokenTypeSessionToken+"_"+key)).Err(); err != nil {
- log.Debug("Error deleting user session from redis: ", err)
- // continue
- }
- if err := c.store.Del(c.ctx, fmt.Sprintf("%s:%s", userId, constants.TokenTypeAccessToken+"_"+key)).Err(); err != nil {
- log.Debug("Error deleting user session from redis: ", err)
- // continue
- }
- if err := c.store.Del(c.ctx, fmt.Sprintf("%s:%s", userId, constants.TokenTypeRefreshToken+"_"+key)).Err(); err != nil {
- log.Debug("Error deleting user session from redis: ", err)
- // continue
- }
- return nil
-}
-
-// DeleteAllUserSessions deletes all the user session from redis
-func (c *provider) DeleteAllUserSessions(userID string) error {
- res := c.store.Keys(c.ctx, fmt.Sprintf("*%s*", userID))
- if res.Err() != nil {
- log.Debug("Error getting all user sessions from redis: ", res.Err())
- return res.Err()
- }
- keys := res.Val()
- for _, key := range keys {
- err := c.store.Del(c.ctx, key).Err()
- if err != nil {
- log.Debug("Error deleting all user sessions from redis: ", err)
- continue
- }
- }
- return nil
-}
-
-// DeleteSessionForNamespace to delete session for a given namespace example google,github
-func (c *provider) DeleteSessionForNamespace(namespace string) error {
- res := c.store.Keys(c.ctx, fmt.Sprintf("%s:*", namespace))
- if res.Err() != nil {
- log.Debug("Error getting all user sessions from redis: ", res.Err())
- return res.Err()
- }
- keys := res.Val()
- for _, key := range keys {
- err := c.store.Del(c.ctx, key).Err()
- if err != nil {
- log.Debug("Error deleting all user sessions from redis: ", err)
- continue
- }
- }
- return nil
-}
-
-// SetMfaSession sets the mfa session with key and value of userId
-func (c *provider) SetMfaSession(userId, key string, expiration int64) error {
- currentTime := time.Now()
- expireTime := time.Unix(expiration, 0)
- duration := expireTime.Sub(currentTime)
- err := c.store.Set(c.ctx, fmt.Sprintf("%s%s:%s", mfaSessionPrefix, userId, key), userId, duration).Err()
- if err != nil {
- log.Debug("Error saving user session to redis: ", err)
- return err
- }
- return nil
-}
-
-// GetMfaSession returns value of given mfa session
-func (c *provider) GetMfaSession(userId, key string) (string, error) {
- data, err := c.store.Get(c.ctx, fmt.Sprintf("%s%s:%s", mfaSessionPrefix, userId, key)).Result()
- if err != nil {
- return "", err
- }
- return data, nil
-}
-
-// DeleteMfaSession deletes given mfa session from in-memory store.
-func (c *provider) DeleteMfaSession(userId, key string) error {
- if err := c.store.Del(c.ctx, fmt.Sprintf("%s%s:%s", mfaSessionPrefix, userId, key)).Err(); err != nil {
- log.Debug("Error deleting user session from redis: ", err)
- // continue
- }
- return nil
-}
-
-// SetState sets the state in redis store.
-func (c *provider) SetState(key, value string) error {
- err := c.store.Set(c.ctx, stateStorePrefix+key, value, 0).Err()
- if err != nil {
- log.Debug("Error saving redis token: ", err)
- return err
- }
-
- return nil
-}
-
-// GetState gets the state from redis store.
-func (c *provider) GetState(key string) (string, error) {
- data, err := c.store.Get(c.ctx, stateStorePrefix+key).Result()
- if err != nil {
- log.Debug("error getting token from redis store: ", err)
- return "", err
- }
-
- return data, err
-}
-
-// RemoveState removes the state from redis store.
-func (c *provider) RemoveState(key string) error {
- err := c.store.Del(c.ctx, stateStorePrefix+key).Err()
- if err != nil {
- log.Fatalln("Error deleting redis token: ", err)
- return err
- }
-
- return nil
-}
-
-// UpdateEnvStore to update the whole env store object
-func (c *provider) UpdateEnvStore(store map[string]interface{}) error {
- for key, value := range store {
- err := c.store.HSet(c.ctx, envStorePrefix, key, value).Err()
- if err != nil {
- return err
- }
- }
- return nil
-}
-
-// GetEnvStore returns the whole env store object
-func (c *provider) GetEnvStore() (map[string]interface{}, error) {
- res := make(map[string]interface{})
- data, err := c.store.HGetAll(c.ctx, envStorePrefix).Result()
- if err != nil {
- return nil, err
- }
- for key, value := range data {
- if key == constants.EnvKeyDisableBasicAuthentication || key == constants.EnvKeyDisableMobileBasicAuthentication || key == constants.EnvKeyDisableEmailVerification || key == constants.EnvKeyDisableLoginPage || key == constants.EnvKeyDisableMagicLinkLogin || key == constants.EnvKeyDisableRedisForEnv || key == constants.EnvKeyDisableSignUp || key == constants.EnvKeyDisableStrongPassword || key == constants.EnvKeyIsEmailServiceEnabled || key == constants.EnvKeyIsSMSServiceEnabled || key == constants.EnvKeyEnforceMultiFactorAuthentication || key == constants.EnvKeyDisableMultiFactorAuthentication || key == constants.EnvKeyAppCookieSecure || key == constants.EnvKeyAdminCookieSecure || key == constants.EnvKeyDisablePlayGround || key == constants.EnvKeyDisableTOTPLogin || key == constants.EnvKeyDisableMailOTPLogin {
- boolValue, err := strconv.ParseBool(value)
- if err != nil {
- return res, err
- }
- res[key] = boolValue
- } else {
- res[key] = value
- }
- }
- return res, nil
-}
-
-// UpdateEnvVariable to update the particular env variable
-func (c *provider) UpdateEnvVariable(key string, value interface{}) error {
- err := c.store.HSet(c.ctx, envStorePrefix, key, value).Err()
- if err != nil {
- log.Debug("Error saving redis token: ", err)
- return err
- }
- return nil
-}
-
-// GetStringStoreEnvVariable to get the string env variable from env store
-func (c *provider) GetStringStoreEnvVariable(key string) (string, error) {
- data, err := c.store.HGet(c.ctx, envStorePrefix, key).Result()
- if err != nil {
- return "", nil
- }
-
- return data, nil
-}
-
-// GetBoolStoreEnvVariable to get the bool env variable from env store
-func (c *provider) GetBoolStoreEnvVariable(key string) (bool, error) {
- data, err := c.store.HGet(c.ctx, envStorePrefix, key).Result()
- if err != nil {
- return false, nil
- }
-
- return data == "1", nil
-}
diff --git a/server/memorystore/required_env_store.go b/server/memorystore/required_env_store.go
deleted file mode 100644
index 1bd105f37..000000000
--- a/server/memorystore/required_env_store.go
+++ /dev/null
@@ -1,171 +0,0 @@
-package memorystore
-
-import (
- "errors"
- "os"
- "strings"
- "sync"
-
- "github.com/joho/godotenv"
- log "github.com/sirupsen/logrus"
-
- "github.com/authorizerdev/authorizer/server/cli"
- "github.com/authorizerdev/authorizer/server/constants"
-)
-
-// RequiredEnv holds information about required envs
-type RequiredEnv struct {
- EnvPath string `json:"ENV_PATH"`
- DatabaseURL string `json:"DATABASE_URL"`
- DatabaseType string `json:"DATABASE_TYPE"`
- DatabaseName string `json:"DATABASE_NAME"`
- DatabaseHost string `json:"DATABASE_HOST"`
- DatabasePort string `json:"DATABASE_PORT"`
- DatabaseUsername string `json:"DATABASE_USERNAME"`
- DatabasePassword string `json:"DATABASE_PASSWORD"`
- DatabaseCert string `json:"DATABASE_CERT"`
- DatabaseCertKey string `json:"DATABASE_CERT_KEY"`
- DatabaseCACert string `json:"DATABASE_CA_CERT"`
- RedisURL string `json:"REDIS_URL"`
- 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"`
- // Couchbase related envs
- CouchbaseBucket string `json:"COUCHBASE_BUCKET"`
- CouchbaseScope string `json:"COUCHBASE_SCOPE"`
- CouchbaseBucketRAMQuotaMB string `json:"COUCHBASE_BUCKET_RAM_QUOTA"`
-}
-
-// RequiredEnvStore is a simple in-memory store for sessions.
-type RequiredEnvStore struct {
- mutex sync.Mutex
- requiredEnv RequiredEnv
-}
-
-// GetRequiredEnv to get required env
-func (r *RequiredEnvStore) GetRequiredEnv() RequiredEnv {
- r.mutex.Lock()
- defer r.mutex.Unlock()
-
- return r.requiredEnv
-}
-
-// SetRequiredEnv to set required env
-func (r *RequiredEnvStore) SetRequiredEnv(requiredEnv RequiredEnv) {
- r.mutex.Lock()
- defer r.mutex.Unlock()
- r.requiredEnv = requiredEnv
-}
-
-var RequiredEnvStoreObj *RequiredEnvStore
-
-// 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)
-
- if envPath == "" {
- if envPath == "" {
- envPath = `.env`
- }
- }
-
- if cli.ARG_ENV_FILE != nil && *cli.ARG_ENV_FILE != "" {
- envPath = *cli.ARG_ENV_FILE
- }
- log.Info("env path: ", envPath)
-
- err := godotenv.Load(envPath)
- if err != nil {
- log.Infof("using OS env instead of %s file", envPath)
- }
-
- dbURL := os.Getenv(constants.EnvKeyDatabaseURL)
- dbType := os.Getenv(constants.EnvKeyDatabaseType)
- dbName := os.Getenv(constants.EnvKeyDatabaseName)
- dbPort := os.Getenv(constants.EnvKeyDatabasePort)
- dbHost := os.Getenv(constants.EnvKeyDatabaseHost)
- dbUsername := os.Getenv(constants.EnvKeyDatabaseUsername)
- dbPassword := os.Getenv(constants.EnvKeyDatabasePassword)
- dbCert := os.Getenv(constants.EnvKeyDatabaseCert)
- dbCertKey := os.Getenv(constants.EnvKeyDatabaseCertKey)
- 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)
- couchbaseBucket := os.Getenv(constants.EnvCouchbaseBucket)
- couchbaseScope := os.Getenv(constants.EnvCouchbaseScope)
- couchbaseBucketRAMQuotaMB := os.Getenv(constants.EnvCouchbaseBucketRAMQuotaMB)
-
- if strings.TrimSpace(redisURL) == "" {
- if cli.ARG_REDIS_URL != nil && *cli.ARG_REDIS_URL != "" {
- redisURL = *cli.ARG_REDIS_URL
- }
- }
-
- // set default db name for non sql dbs
- if dbName == "" {
- dbName = "authorizer"
- }
-
- if strings.TrimSpace(dbType) == "" {
- if cli.ARG_DB_TYPE != nil && *cli.ARG_DB_TYPE != "" {
- dbType = strings.TrimSpace(*cli.ARG_DB_TYPE)
- }
-
- if dbType == "" {
- log.Debug("DATABASE_TYPE is not set")
- return errors.New("invalid database type. DATABASE_TYPE is empty")
- }
- }
-
- if strings.TrimSpace(dbURL) == "" {
- if cli.ARG_DB_URL != nil && *cli.ARG_DB_URL != "" {
- dbURL = strings.TrimSpace(*cli.ARG_DB_URL)
- }
-
- // 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")
- }
- }
-
- if dbName == "" {
- if dbName == "" {
- dbName = "authorizer"
- }
- }
-
- requiredEnv := RequiredEnv{
- EnvPath: envPath,
- DatabaseURL: dbURL,
- DatabaseType: dbType,
- DatabaseName: dbName,
- DatabaseHost: dbHost,
- DatabasePort: dbPort,
- DatabaseUsername: dbUsername,
- DatabasePassword: dbPassword,
- DatabaseCert: dbCert,
- DatabaseCertKey: dbCertKey,
- DatabaseCACert: dbCACert,
- RedisURL: redisURL,
- DisableRedisForEnv: disableRedisForEnv,
- AwsRegion: awsRegion,
- AwsAccessKeyID: awsAccessKeyID,
- AwsSecretAccessKey: awsSecretAccessKey,
- CouchbaseBucket: couchbaseBucket,
- CouchbaseScope: couchbaseScope,
- CouchbaseBucketRAMQuotaMB: couchbaseBucketRAMQuotaMB,
- }
-
- RequiredEnvStoreObj = &RequiredEnvStore{
- requiredEnv: requiredEnv,
- }
-
- return nil
-}
diff --git a/server/middlewares/context.go b/server/middlewares/context.go
deleted file mode 100644
index 8da697de0..000000000
--- a/server/middlewares/context.go
+++ /dev/null
@@ -1,16 +0,0 @@
-package middlewares
-
-import (
- "context"
-
- "github.com/gin-gonic/gin"
-)
-
-// GinContextToContextMiddleware is a middleware to add gin context in context
-func GinContextToContextMiddleware() gin.HandlerFunc {
- return func(c *gin.Context) {
- ctx := context.WithValue(c.Request.Context(), "GinContextKey", c)
- c.Request = c.Request.WithContext(ctx)
- c.Next()
- }
-}
diff --git a/server/middlewares/log.go b/server/middlewares/log.go
deleted file mode 100644
index 357b4b2b4..000000000
--- a/server/middlewares/log.go
+++ /dev/null
@@ -1,78 +0,0 @@
-package middlewares
-
-import (
- "fmt"
- "math"
- "net/http"
- "os"
- "time"
-
- "github.com/gin-gonic/gin"
- "github.com/sirupsen/logrus"
-)
-
-var timeFormat = "02/Jan/2006:15:04:05 -0700"
-
-// Logger is the logrus logger handler
-func Logger(logger logrus.FieldLogger, notLogged ...string) gin.HandlerFunc {
- hostname, err := os.Hostname()
- if err != nil {
- hostname = "unknown"
- }
-
- var skip map[string]struct{}
-
- if length := len(notLogged); length > 0 {
- skip = make(map[string]struct{}, length)
-
- for _, p := range notLogged {
- skip[p] = struct{}{}
- }
- }
-
- return func(c *gin.Context) {
- // other handler can change c.Path so:
- path := c.Request.URL.Path
- start := time.Now()
- c.Next()
- stop := time.Since(start)
- latency := int(math.Ceil(float64(stop.Nanoseconds()) / 1000000.0))
- statusCode := c.Writer.Status()
- clientIP := c.ClientIP()
- clientUserAgent := c.Request.UserAgent()
- referer := c.Request.Referer()
- dataLength := c.Writer.Size()
- if dataLength < 0 {
- dataLength = 0
- }
-
- if _, ok := skip[path]; ok {
- return
- }
-
- entry := logger.WithFields(logrus.Fields{
- "hostname": hostname,
- "statusCode": statusCode,
- "latency": latency, // time to process
- "clientIP": clientIP,
- "method": c.Request.Method,
- "path": path,
- "referer": referer,
- "dataLength": dataLength,
- "userAgent": clientUserAgent,
- })
-
- if len(c.Errors) > 0 {
- entry.Error(c.Errors.ByType(gin.ErrorTypePrivate).String())
- } else {
- msg := fmt.Sprintf("%s - %s [%s] \"%s %s\" %d %d \"%s\" \"%s\" (%dms)", clientIP, hostname, time.Now().Format(timeFormat), c.Request.Method, path, statusCode, dataLength, referer, clientUserAgent, latency)
- if statusCode >= http.StatusInternalServerError {
- entry.Error(msg)
- } else if statusCode >= http.StatusBadRequest {
- entry.Warn(msg)
- } else {
- entry.Info(msg)
- }
- }
- }
-}
diff --git a/server/oauth/oauth.go b/server/oauth/oauth.go
deleted file mode 100644
index 8f64feea9..000000000
--- a/server/oauth/oauth.go
+++ /dev/null
@@ -1,276 +0,0 @@
-package oauth
-
-import (
- "context"
- "fmt"
-
- "golang.org/x/oauth2"
- "google.golang.org/appengine/log"
-
- facebookOAuth2 "golang.org/x/oauth2/facebook"
- githubOAuth2 "golang.org/x/oauth2/github"
- linkedInOAuth2 "golang.org/x/oauth2/linkedin"
- microsoftOAuth2 "golang.org/x/oauth2/microsoft"
- twitchOAuth2 "golang.org/x/oauth2/twitch"
-
- "github.com/coreos/go-oidc/v3/oidc"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/memorystore"
-)
-
-const (
- microsoftCommonTenant = "common"
-)
-
-// OAuthProviders is a struct that contains reference all the OAuth providers
-type OAuthProvider struct {
- GoogleConfig *oauth2.Config
- GithubConfig *oauth2.Config
- FacebookConfig *oauth2.Config
- LinkedInConfig *oauth2.Config
- AppleConfig *oauth2.Config
- DiscordConfig *oauth2.Config
- TwitterConfig *oauth2.Config
- MicrosoftConfig *oauth2.Config
- TwitchConfig *oauth2.Config
- RobloxConfig *oauth2.Config
-}
-
-// OIDCProviders is a struct that contains reference all the OpenID providers
-type OIDCProvider struct {
- GoogleOIDC *oidc.Provider
- MicrosoftOIDC *oidc.Provider
- TwitchOIDC *oidc.Provider
-}
-
-var (
- // OAuthProviders is a global variable that contains instance for all enabled the OAuth providers
- OAuthProviders OAuthProvider
- // OIDCProviders is a global variable that contains instance for all enabled the OpenID providers
- OIDCProviders OIDCProvider
-)
-
-// InitOAuth initializes the OAuth providers based on EnvData
-func InitOAuth() error {
- ctx := context.Background()
- googleClientID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyGoogleClientID)
- if err != nil {
- googleClientID = ""
- }
- googleClientSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyGoogleClientSecret)
- if err != nil {
- googleClientSecret = ""
- }
- if googleClientID != "" && googleClientSecret != "" {
- p, err := oidc.NewProvider(ctx, "https://accounts.google.com")
- if err != nil {
- return err
- }
- OIDCProviders.GoogleOIDC = p
- OAuthProviders.GoogleConfig = &oauth2.Config{
- ClientID: googleClientID,
- ClientSecret: googleClientSecret,
- RedirectURL: "/oauth_callback/google",
- Endpoint: OIDCProviders.GoogleOIDC.Endpoint(),
- Scopes: []string{oidc.ScopeOpenID, "profile", "email"},
- }
- }
-
- githubClientID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyGithubClientID)
- if err != nil {
- githubClientID = ""
- }
- githubClientSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyGithubClientSecret)
- if err != nil {
- githubClientSecret = ""
- }
- if githubClientID != "" && githubClientSecret != "" {
- OAuthProviders.GithubConfig = &oauth2.Config{
- ClientID: githubClientID,
- ClientSecret: githubClientSecret,
- RedirectURL: "/oauth_callback/github",
- Endpoint: githubOAuth2.Endpoint,
- Scopes: []string{"read:user", "user:email"},
- }
- }
-
- facebookClientID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyFacebookClientID)
- if err != nil {
- facebookClientID = ""
- }
- facebookClientSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyFacebookClientSecret)
- if err != nil {
- facebookClientSecret = ""
- }
- if facebookClientID != "" && facebookClientSecret != "" {
- OAuthProviders.FacebookConfig = &oauth2.Config{
- ClientID: facebookClientID,
- ClientSecret: facebookClientSecret,
- RedirectURL: "/oauth_callback/facebook",
- Endpoint: facebookOAuth2.Endpoint,
- Scopes: []string{"public_profile", "email"},
- }
- }
-
- linkedInClientID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyLinkedInClientID)
- if err != nil {
- linkedInClientID = ""
- }
- linkedInClientSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyLinkedInClientSecret)
- if err != nil {
- linkedInClientSecret = ""
- }
- if linkedInClientID != "" && linkedInClientSecret != "" {
- OAuthProviders.LinkedInConfig = &oauth2.Config{
- ClientID: linkedInClientID,
- ClientSecret: linkedInClientSecret,
- RedirectURL: "/oauth_callback/linkedin",
- Endpoint: linkedInOAuth2.Endpoint,
- Scopes: []string{"r_liteprofile", "r_emailaddress"},
- }
- }
-
- appleClientID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAppleClientID)
- if err != nil {
- appleClientID = ""
- }
- appleClientSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAppleClientSecret)
- if err != nil {
- appleClientSecret = ""
- }
- if appleClientID != "" && appleClientSecret != "" {
- OAuthProviders.AppleConfig = &oauth2.Config{
- ClientID: appleClientID,
- ClientSecret: appleClientSecret,
- RedirectURL: "/oauth_callback/apple",
- Endpoint: oauth2.Endpoint{
- AuthURL: "https://appleid.apple.com/auth/authorize",
- TokenURL: "https://appleid.apple.com/auth/token",
- },
- }
- }
-
- discordClientID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyDiscordClientID)
- if err != nil {
- discordClientID = ""
- }
- discordClientSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyDiscordClientSecret)
- if err != nil {
- discordClientSecret = ""
- }
- if discordClientID != "" && discordClientSecret != "" {
- OAuthProviders.DiscordConfig = &oauth2.Config{
- ClientID: discordClientID,
- ClientSecret: discordClientSecret,
- RedirectURL: "/oauth_callback/discord",
- Endpoint: oauth2.Endpoint{
- AuthURL: "https://discord.com/oauth2/authorize",
- TokenURL: "https://discord.com/api/oauth2/token",
- },
- Scopes: []string{"identify", "email"},
- }
- }
-
- twitterClientID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyTwitterClientID)
- if err != nil {
- twitterClientID = ""
- }
- twitterClientSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyTwitterClientSecret)
- if err != nil {
- twitterClientSecret = ""
- }
- if twitterClientID != "" && twitterClientSecret != "" {
- OAuthProviders.TwitterConfig = &oauth2.Config{
- ClientID: twitterClientID,
- ClientSecret: twitterClientSecret,
- RedirectURL: "/oauth_callback/twitter",
- Endpoint: oauth2.Endpoint{
- // Endpoint is currently not yet part of oauth2-package. See https://go-review.googlesource.com/c/oauth2/+/350889 for status
- AuthURL: "https://twitter.com/i/oauth2/authorize",
- TokenURL: "https://api.twitter.com/2/oauth2/token",
- AuthStyle: oauth2.AuthStyleInHeader,
- },
- Scopes: []string{"tweet.read", "users.read"},
- }
- }
-
- microsoftClientID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyMicrosoftClientID)
- if err != nil {
- microsoftClientID = ""
- }
- microsoftClientSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyMicrosoftClientSecret)
- if err != nil {
- microsoftClientSecret = ""
- }
- microsoftActiveDirTenantID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyMicrosoftActiveDirectoryTenantID)
- if err != nil || microsoftActiveDirTenantID == "" {
- microsoftActiveDirTenantID = microsoftCommonTenant
- }
- if microsoftClientID != "" && microsoftClientSecret != "" {
- if microsoftActiveDirTenantID == microsoftCommonTenant {
- ctx = oidc.InsecureIssuerURLContext(ctx, fmt.Sprintf("https://login.microsoftonline.com/%s/v2.0", microsoftActiveDirTenantID))
- }
- p, err := oidc.NewProvider(ctx, fmt.Sprintf("https://login.microsoftonline.com/%s/v2.0", microsoftActiveDirTenantID))
- if err != nil {
- log.Debugf(ctx, "Error while creating OIDC provider for Microsoft: %v", err)
- return err
- }
- OIDCProviders.MicrosoftOIDC = p
- OAuthProviders.MicrosoftConfig = &oauth2.Config{
- ClientID: microsoftClientID,
- ClientSecret: microsoftClientSecret,
- RedirectURL: "/oauth_callback/microsoft",
- Endpoint: microsoftOAuth2.AzureADEndpoint(microsoftActiveDirTenantID),
- Scopes: []string{oidc.ScopeOpenID, "profile", "email"},
- }
- }
-
- twitchClientID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyTwitchClientID)
- if err != nil {
- twitchClientID = ""
- }
- twitchClientSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyTwitchClientSecret)
- if err != nil {
- twitchClientSecret = ""
- }
-
- if twitchClientID != "" && twitchClientSecret != "" {
- p, err := oidc.NewProvider(ctx, "https://id.twitch.tv/oauth2")
- if err != nil {
- log.Debugf(ctx, "Error while creating OIDC provider for Twitch: %v", err)
- return err
- }
-
- OIDCProviders.TwitchOIDC = p
- OAuthProviders.TwitchConfig = &oauth2.Config{
- ClientID: twitchClientID,
- ClientSecret: twitchClientSecret,
- RedirectURL: "/oauth_callback/twitch",
- Endpoint: twitchOAuth2.Endpoint,
- Scopes: []string{oidc.ScopeOpenID},
- }
- }
-
- robloxClientID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyRobloxClientID)
- if err != nil {
- robloxClientID = ""
- }
- robloxClientSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyRobloxClientSecret)
- if err != nil {
- robloxClientSecret = ""
- }
- if robloxClientID != "" && robloxClientSecret != "" {
- OAuthProviders.RobloxConfig = &oauth2.Config{
- ClientID: robloxClientID,
- ClientSecret: robloxClientSecret,
- RedirectURL: "/oauth_callback/roblox",
- Endpoint: oauth2.Endpoint{
- AuthURL: "https://apis.roblox.com/oauth/v1/authorize",
- TokenURL: "https://apis.roblox.com/oauth/v1/token",
- },
- Scopes: []string{oidc.ScopeOpenID, "profile"},
- }
- }
- return nil
-}
diff --git a/server/resolvers/add_email_template.go b/server/resolvers/add_email_template.go
deleted file mode 100644
index 487edc25d..000000000
--- a/server/resolvers/add_email_template.go
+++ /dev/null
@@ -1,64 +0,0 @@
-package resolvers
-
-import (
- "context"
- "fmt"
- "strings"
-
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/db/models"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/refs"
- "github.com/authorizerdev/authorizer/server/token"
- "github.com/authorizerdev/authorizer/server/utils"
- "github.com/authorizerdev/authorizer/server/validators"
- log "github.com/sirupsen/logrus"
-)
-
-// AddEmailTemplateResolver resolver for add email template mutation
-func AddEmailTemplateResolver(ctx context.Context, params model.AddEmailTemplateRequest) (*model.Response, error) {
- gc, err := utils.GinContextFromContext(ctx)
- if err != nil {
- log.Debug("Failed to get GinContext: ", err)
- return nil, err
- }
-
- if !token.IsSuperAdmin(gc) {
- log.Debug("Not logged in as super admin")
- return nil, fmt.Errorf("unauthorized")
- }
-
- if !validators.IsValidEmailTemplateEventName(params.EventName) {
- log.Debug("Invalid Event Name: ", params.EventName)
- return nil, fmt.Errorf("invalid event name %s", params.EventName)
- }
-
- if strings.TrimSpace(params.Subject) == "" {
- return nil, fmt.Errorf("empty subject not allowed")
- }
-
- if strings.TrimSpace(params.Template) == "" {
- return nil, fmt.Errorf("empty template not allowed")
- }
-
- var design string
-
- if params.Design == nil || strings.TrimSpace(refs.StringValue(params.Design)) == "" {
- design = ""
- }
-
- _, err = db.Provider.AddEmailTemplate(ctx, &models.EmailTemplate{
- EventName: params.EventName,
- Template: params.Template,
- Subject: params.Subject,
- Design: design,
- })
- if err != nil {
- log.Debug("Failed to add email template: ", err)
- return nil, err
- }
-
- return &model.Response{
- Message: `Email template added successfully`,
- }, nil
-}
diff --git a/server/resolvers/admin_login.go b/server/resolvers/admin_login.go
deleted file mode 100644
index 23965bbbf..000000000
--- a/server/resolvers/admin_login.go
+++ /dev/null
@@ -1,47 +0,0 @@
-package resolvers
-
-import (
- "context"
- "fmt"
-
- log "github.com/sirupsen/logrus"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/cookie"
- "github.com/authorizerdev/authorizer/server/crypto"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/utils"
-)
-
-// AdminLoginResolver is a resolver for admin login mutation
-func AdminLoginResolver(ctx context.Context, params model.AdminLoginInput) (*model.Response, error) {
- var res *model.Response
-
- gc, err := utils.GinContextFromContext(ctx)
- if err != nil {
- log.Debug("Failed to get GinContext: ", err)
- return res, err
- }
-
- adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
- if err != nil {
- log.Debug("Error getting admin secret: ", err)
- return res, err
- }
- if params.AdminSecret != adminSecret {
- log.Debug("Admin secret is not correct")
- return res, fmt.Errorf(`invalid admin secret`)
- }
-
- hashedKey, err := crypto.EncryptPassword(adminSecret)
- if err != nil {
- return res, err
- }
- cookie.SetAdminCookie(gc, hashedKey)
-
- res = &model.Response{
- Message: "admin logged in successfully",
- }
- return res, nil
-}
diff --git a/server/resolvers/admin_logout.go b/server/resolvers/admin_logout.go
deleted file mode 100644
index 64befe02f..000000000
--- a/server/resolvers/admin_logout.go
+++ /dev/null
@@ -1,36 +0,0 @@
-package resolvers
-
-import (
- "context"
- "fmt"
-
- log "github.com/sirupsen/logrus"
-
- "github.com/authorizerdev/authorizer/server/cookie"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/token"
- "github.com/authorizerdev/authorizer/server/utils"
-)
-
-// AdminLogoutResolver is a resolver for admin logout mutation
-func AdminLogoutResolver(ctx context.Context) (*model.Response, error) {
- var res *model.Response
-
- gc, err := utils.GinContextFromContext(ctx)
- if err != nil {
- log.Debug("Failed to get GinContext: ", err)
- return res, err
- }
-
- if !token.IsSuperAdmin(gc) {
- log.Debug("Admin is not logged in")
- return res, fmt.Errorf("unauthorized")
- }
-
- cookie.DeleteAdminCookie(gc)
-
- res = &model.Response{
- Message: "admin logged out successfully",
- }
- return res, nil
-}
diff --git a/server/resolvers/admin_session.go b/server/resolvers/admin_session.go
deleted file mode 100644
index d5cb8d10c..000000000
--- a/server/resolvers/admin_session.go
+++ /dev/null
@@ -1,49 +0,0 @@
-package resolvers
-
-import (
- "context"
- "fmt"
-
- log "github.com/sirupsen/logrus"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/cookie"
- "github.com/authorizerdev/authorizer/server/crypto"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/token"
- "github.com/authorizerdev/authorizer/server/utils"
-)
-
-// AdminSessionResolver is a resolver for admin session query
-func AdminSessionResolver(ctx context.Context) (*model.Response, error) {
- var res *model.Response
-
- gc, err := utils.GinContextFromContext(ctx)
- if err != nil {
- log.Debug("Failed to get GinContext: ", err)
- return res, err
- }
-
- if !token.IsSuperAdmin(gc) {
- log.Debug("Not logged in as super admin")
- return res, fmt.Errorf("unauthorized")
- }
-
- adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
- if err != nil {
- log.Debug("Error getting admin secret: ", err)
- return res, fmt.Errorf("unauthorized")
- }
- hashedKey, err := crypto.EncryptPassword(adminSecret)
- if err != nil {
- log.Debug("Failed to encrypt key: ", err)
- return res, err
- }
- cookie.SetAdminCookie(gc, hashedKey)
-
- res = &model.Response{
- Message: "admin logged in successfully",
- }
- return res, nil
-}
diff --git a/server/resolvers/admin_signup.go b/server/resolvers/admin_signup.go
deleted file mode 100644
index c1dd5c177..000000000
--- a/server/resolvers/admin_signup.go
+++ /dev/null
@@ -1,90 +0,0 @@
-package resolvers
-
-import (
- "context"
- "fmt"
- "strings"
-
- log "github.com/sirupsen/logrus"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/cookie"
- "github.com/authorizerdev/authorizer/server/crypto"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/utils"
-)
-
-// AdminSignupResolver is a resolver for admin signup mutation
-func AdminSignupResolver(ctx context.Context, params model.AdminSignupInput) (*model.Response, error) {
- var res *model.Response
-
- gc, err := utils.GinContextFromContext(ctx)
- if err != nil {
- log.Debug("Failed to get GinContext: ", err)
- return res, err
- }
-
- if strings.TrimSpace(params.AdminSecret) == "" {
- log.Debug("Admin secret is empty")
- err = fmt.Errorf("please select secure admin secret")
- return res, err
- }
-
- if len(params.AdminSecret) < 6 {
- log.Debug("Admin secret is too short")
- err = fmt.Errorf("admin secret must be at least 6 characters")
- return res, err
- }
-
- adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
- if err != nil {
- log.Debug("Error getting admin secret: ", err)
- adminSecret = ""
- }
-
- if adminSecret != "" {
- log.Debug("Admin secret is already set")
- err = fmt.Errorf("admin sign up already completed")
- return res, err
- }
-
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyAdminSecret, params.AdminSecret)
- // consvert EnvData to JSON
- storeData, err := memorystore.Provider.GetEnvStore()
- if err != nil {
- log.Debug("Error getting env store: ", err)
- return res, err
- }
-
- env, err := db.Provider.GetEnv(ctx)
- if err != nil {
- log.Debug("Failed to get env: ", err)
- return res, err
- }
-
- envData, err := crypto.EncryptEnvData(storeData)
- if err != nil {
- log.Debug("Failed to encrypt envstore: ", err)
- return res, err
- }
-
- env.EnvData = envData
- if _, err := db.Provider.UpdateEnv(ctx, env); err != nil {
- log.Debug("Failed to update env: ", err)
- return res, err
- }
-
- hashedKey, err := crypto.EncryptPassword(params.AdminSecret)
- if err != nil {
- log.Debug("Failed to encrypt admin session key: ", err)
- return res, err
- }
- cookie.SetAdminCookie(gc, hashedKey)
-
- res = &model.Response{
- Message: "admin signed up successfully",
- }
- return res, nil
-}
diff --git a/server/resolvers/deactivate_account.go b/server/resolvers/deactivate_account.go
deleted file mode 100644
index 539575c59..000000000
--- a/server/resolvers/deactivate_account.go
+++ /dev/null
@@ -1,52 +0,0 @@
-package resolvers
-
-import (
- "context"
- "time"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/token"
- "github.com/authorizerdev/authorizer/server/utils"
- log "github.com/sirupsen/logrus"
-)
-
-// DeactivateAccountResolver is the resolver for the deactivate_account field.
-func DeactivateAccountResolver(ctx context.Context) (*model.Response, error) {
- var res *model.Response
- gc, err := utils.GinContextFromContext(ctx)
- if err != nil {
- log.Debug("Failed to get GinContext: ", err)
- return res, err
- }
- tokenData, err := token.GetUserIDFromSessionOrAccessToken(gc)
- if err != nil {
- log.Debug("Failed GetUserIDFromSessionOrAccessToken: ", err)
- return res, err
- }
- log := log.WithFields(log.Fields{
- "user_id": tokenData.UserID,
- })
- user, err := db.Provider.GetUserByID(ctx, tokenData.UserID)
- if err != nil {
- log.Debug("Failed to get user by id: ", err)
- return res, err
- }
- now := time.Now().Unix()
- user.RevokedTimestamp = &now
- user, err = db.Provider.UpdateUser(ctx, user)
- if err != nil {
- log.Debug("Failed to update user: ", err)
- return res, err
- }
- go func() {
- memorystore.Provider.DeleteAllUserSessions(user.ID)
- utils.RegisterEvent(ctx, constants.UserDeactivatedWebhookEvent, "", user)
- }()
- res = &model.Response{
- Message: `user account deactivated successfully`,
- }
- return res, nil
-}
diff --git a/server/resolvers/delete_email_template.go b/server/resolvers/delete_email_template.go
deleted file mode 100644
index 92a6172d0..000000000
--- a/server/resolvers/delete_email_template.go
+++ /dev/null
@@ -1,49 +0,0 @@
-package resolvers
-
-import (
- "context"
- "fmt"
-
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/token"
- "github.com/authorizerdev/authorizer/server/utils"
- log "github.com/sirupsen/logrus"
-)
-
-// DeleteEmailTemplateResolver resolver to delete email template and its relevant logs
-func DeleteEmailTemplateResolver(ctx context.Context, params model.DeleteEmailTemplateRequest) (*model.Response, error) {
- gc, err := utils.GinContextFromContext(ctx)
- if err != nil {
- log.Debug("Failed to get GinContext: ", err)
- return nil, err
- }
-
- if !token.IsSuperAdmin(gc) {
- log.Debug("Not logged in as super admin")
- return nil, fmt.Errorf("unauthorized")
- }
-
- if params.ID == "" {
- log.Debug("email template is required")
- return nil, fmt.Errorf("email template ID required")
- }
-
- log := log.WithField("email_template_id", params.ID)
-
- emailTemplate, err := db.Provider.GetEmailTemplateByID(ctx, params.ID)
- if err != nil {
- log.Debug("failed to get email template: ", err)
- return nil, err
- }
-
- err = db.Provider.DeleteEmailTemplate(ctx, emailTemplate)
- if err != nil {
- log.Debug("failed to delete email template: ", err)
- return nil, err
- }
-
- return &model.Response{
- Message: "Email templated deleted successfully",
- }, nil
-}
diff --git a/server/resolvers/delete_user.go b/server/resolvers/delete_user.go
deleted file mode 100644
index e6ccf62d8..000000000
--- a/server/resolvers/delete_user.go
+++ /dev/null
@@ -1,100 +0,0 @@
-package resolvers
-
-import (
- "context"
- "fmt"
-
- log "github.com/sirupsen/logrus"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/refs"
- "github.com/authorizerdev/authorizer/server/token"
- "github.com/authorizerdev/authorizer/server/utils"
-)
-
-// DeleteUserResolver is a resolver for delete user mutation
-func DeleteUserResolver(ctx context.Context, params model.DeleteUserInput) (*model.Response, error) {
- var res *model.Response
-
- gc, err := utils.GinContextFromContext(ctx)
- if err != nil {
- log.Debug("Failed to get GinContext: ", err)
- return res, err
- }
-
- if !token.IsSuperAdmin(gc) {
- log.Debug("Not logged in as super admin")
- return res, fmt.Errorf("unauthorized")
- }
-
- log := log.WithFields(log.Fields{
- "email": params.Email,
- })
-
- user, err := db.Provider.GetUserByEmail(ctx, params.Email)
- if err != nil {
- log.Debug("Failed to get user from DB: ", err)
- return res, err
- }
-
- err = db.Provider.DeleteUser(ctx, user)
- if err != nil {
- log.Debug("Failed to delete user: ", err)
- return res, err
- }
-
- res = &model.Response{
- Message: `user deleted successfully`,
- }
-
- go func() {
- // delete otp for given email
- otp, err := db.Provider.GetOTPByEmail(ctx, refs.StringValue(user.Email))
- if err != nil {
- log.Infof("No OTP found for email (%s): %v", user.Email, err)
- // continue
- } else {
- err := db.Provider.DeleteOTP(ctx, otp)
- if err != nil {
- log.Debugf("Failed to delete otp for given email (%s): %v", refs.StringValue(user.Email), err)
- // continue
- }
- }
-
- // delete otp for given phone number
- otp, err = db.Provider.GetOTPByPhoneNumber(ctx, refs.StringValue(user.PhoneNumber))
- if err != nil {
- log.Infof("No OTP found for email (%s): %v", refs.StringValue(user.Email), err)
- // continue
- } else {
- err := db.Provider.DeleteOTP(ctx, otp)
- if err != nil {
- log.Debugf("Failed to delete otp for given phone (%s): %v", refs.StringValue(user.PhoneNumber), err)
- // continue
- }
- }
-
- // delete verification requests for given email
- for _, vt := range constants.VerificationTypes {
- verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, refs.StringValue(user.Email), vt)
- if err != nil {
- log.Infof("No verification verification request found for email: %s, verification_request_type: %s. %v", refs.StringValue(user.Email), vt, err)
- // continue
- } else {
- err := db.Provider.DeleteVerificationRequest(ctx, verificationRequest)
- if err != nil {
- log.Debugf("Failed to DeleteVerificationRequest for email: %s, verification_request_type: %s. %v", refs.StringValue(user.Email), vt, err)
- // continue
- }
- }
- }
-
- memorystore.Provider.DeleteAllUserSessions(user.ID)
- utils.RegisterEvent(ctx, constants.UserDeletedWebhookEvent, "", user)
- }()
-
- return res, nil
-}
diff --git a/server/resolvers/delete_webhook.go b/server/resolvers/delete_webhook.go
deleted file mode 100644
index 917d50259..000000000
--- a/server/resolvers/delete_webhook.go
+++ /dev/null
@@ -1,49 +0,0 @@
-package resolvers
-
-import (
- "context"
- "fmt"
-
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/token"
- "github.com/authorizerdev/authorizer/server/utils"
- log "github.com/sirupsen/logrus"
-)
-
-// DeleteWebhookResolver resolver to delete webhook and its relevant logs
-func DeleteWebhookResolver(ctx context.Context, params model.WebhookRequest) (*model.Response, error) {
- gc, err := utils.GinContextFromContext(ctx)
- if err != nil {
- log.Debug("Failed to get GinContext: ", err)
- return nil, err
- }
-
- if !token.IsSuperAdmin(gc) {
- log.Debug("Not logged in as super admin")
- return nil, fmt.Errorf("unauthorized")
- }
-
- if params.ID == "" {
- log.Debug("webhookID is required")
- return nil, fmt.Errorf("webhook ID required")
- }
-
- log := log.WithField("webhook_id", params.ID)
-
- webhook, err := db.Provider.GetWebhookByID(ctx, params.ID)
- if err != nil {
- log.Debug("failed to get webhook: ", err)
- return nil, err
- }
-
- err = db.Provider.DeleteWebhook(ctx, webhook)
- if err != nil {
- log.Debug("failed to delete webhook: ", err)
- return nil, err
- }
-
- return &model.Response{
- Message: "Webhook deleted successfully",
- }, nil
-}
diff --git a/server/resolvers/email_templates.go b/server/resolvers/email_templates.go
deleted file mode 100644
index 0e1ee6639..000000000
--- a/server/resolvers/email_templates.go
+++ /dev/null
@@ -1,34 +0,0 @@
-package resolvers
-
-import (
- "context"
- "fmt"
-
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/token"
- "github.com/authorizerdev/authorizer/server/utils"
- log "github.com/sirupsen/logrus"
-)
-
-// EmailTemplatesResolver resolver for getting the list of email templates based on pagination
-func EmailTemplatesResolver(ctx context.Context, params *model.PaginatedInput) (*model.EmailTemplates, error) {
- gc, err := utils.GinContextFromContext(ctx)
- if err != nil {
- log.Debug("Failed to get GinContext: ", err)
- return nil, err
- }
-
- if !token.IsSuperAdmin(gc) {
- log.Debug("Not logged in as super admin")
- return nil, fmt.Errorf("unauthorized")
- }
-
- pagination := utils.GetPagination(params)
- emailTemplates, err := db.Provider.ListEmailTemplate(ctx, pagination)
- if err != nil {
- log.Debug("failed to get email templates: ", err)
- return nil, err
- }
- return emailTemplates, nil
-}
diff --git a/server/resolvers/enable_access.go b/server/resolvers/enable_access.go
deleted file mode 100644
index 8e245b856..000000000
--- a/server/resolvers/enable_access.go
+++ /dev/null
@@ -1,56 +0,0 @@
-package resolvers
-
-import (
- "context"
- "fmt"
-
- log "github.com/sirupsen/logrus"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/token"
- "github.com/authorizerdev/authorizer/server/utils"
-)
-
-// EnableAccessResolver is a resolver for enabling user access
-func EnableAccessResolver(ctx context.Context, params model.UpdateAccessInput) (*model.Response, error) {
- var res *model.Response
-
- gc, err := utils.GinContextFromContext(ctx)
- if err != nil {
- log.Debug("Failed to get GinContext: ", err)
- return res, err
- }
-
- if !token.IsSuperAdmin(gc) {
- log.Debug("Not logged in as super admin.")
- return res, fmt.Errorf("unauthorized")
- }
-
- log := log.WithFields(log.Fields{
- "user_id": params.UserID,
- })
-
- user, err := db.Provider.GetUserByID(ctx, params.UserID)
- if err != nil {
- log.Debug("Failed to get user from DB: ", err)
- return res, err
- }
-
- user.RevokedTimestamp = nil
-
- user, err = db.Provider.UpdateUser(ctx, user)
- if err != nil {
- log.Debug("Failed to update user: ", err)
- return res, err
- }
-
- res = &model.Response{
- Message: `user access enabled successfully`,
- }
-
- go utils.RegisterEvent(ctx, constants.UserAccessEnabledWebhookEvent, "", user)
-
- return res, nil
-}
diff --git a/server/resolvers/env.go b/server/resolvers/env.go
deleted file mode 100644
index f95e1f771..000000000
--- a/server/resolvers/env.go
+++ /dev/null
@@ -1,228 +0,0 @@
-package resolvers
-
-import (
- "context"
- "fmt"
- "strings"
-
- log "github.com/sirupsen/logrus"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/refs"
- "github.com/authorizerdev/authorizer/server/token"
- "github.com/authorizerdev/authorizer/server/utils"
-)
-
-// EnvResolver is a resolver for config query
-// This is admin only query
-func EnvResolver(ctx context.Context) (*model.Env, error) {
- res := &model.Env{}
-
- gc, err := utils.GinContextFromContext(ctx)
- if err != nil {
- log.Debug("Failed to get GinContext: ", err)
- return res, err
- }
-
- if !token.IsSuperAdmin(gc) {
- log.Debug("Not logged in as super admin.")
- return res, fmt.Errorf("unauthorized")
- }
-
- // get clone of store
- store, err := memorystore.Provider.GetEnvStore()
- if err != nil {
- log.Debug("Failed to get env store: ", err)
- return res, err
- }
-
- if val, ok := store[constants.EnvKeyAccessTokenExpiryTime]; ok {
- res.AccessTokenExpiryTime = refs.NewStringRef(val.(string))
- }
- if val, ok := store[constants.EnvKeyAdminSecret]; ok {
- res.AdminSecret = refs.NewStringRef(val.(string))
- }
- if val, ok := store[constants.EnvKeyClientID]; ok {
- res.ClientID = val.(string)
- }
- if val, ok := store[constants.EnvKeyClientSecret]; ok {
- res.ClientSecret = val.(string)
- }
- if val, ok := store[constants.EnvKeyDatabaseURL]; ok {
- res.DatabaseURL = refs.NewStringRef(val.(string))
- }
- if val, ok := store[constants.EnvKeyDatabaseName]; ok {
- res.DatabaseName = refs.NewStringRef(val.(string))
- }
- if val, ok := store[constants.EnvKeyDatabaseType]; ok {
- res.DatabaseType = refs.NewStringRef(val.(string))
- }
- if val, ok := store[constants.EnvKeyDatabaseUsername]; ok {
- res.DatabaseUsername = refs.NewStringRef(val.(string))
- }
- if val, ok := store[constants.EnvKeyDatabasePassword]; ok {
- res.DatabasePassword = refs.NewStringRef(val.(string))
- }
- if val, ok := store[constants.EnvKeyDatabaseHost]; ok {
- res.DatabaseHost = refs.NewStringRef(val.(string))
- }
- if val, ok := store[constants.EnvKeyDatabasePort]; ok {
- res.DatabasePort = refs.NewStringRef(val.(string))
- }
- if val, ok := store[constants.EnvKeyCustomAccessTokenScript]; ok {
- res.CustomAccessTokenScript = refs.NewStringRef(val.(string))
- }
- if val, ok := store[constants.EnvKeySmtpHost]; ok {
- res.SMTPHost = refs.NewStringRef(val.(string))
- }
- if val, ok := store[constants.EnvKeySmtpPort]; ok {
- res.SMTPPort = refs.NewStringRef(val.(string))
- }
- if val, ok := store[constants.EnvKeySmtpUsername]; ok {
- res.SMTPUsername = refs.NewStringRef(val.(string))
- }
- if val, ok := store[constants.EnvKeySmtpPassword]; ok {
- res.SMTPPassword = refs.NewStringRef(val.(string))
- }
- if val, ok := store[constants.EnvKeySenderEmail]; ok {
- res.SenderEmail = refs.NewStringRef(val.(string))
- }
- if val, ok := store[constants.EnvKeySenderName]; ok {
- res.SenderName = 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))
- }
- if val, ok := store[constants.EnvKeyJwtSecret]; ok {
- res.JwtSecret = refs.NewStringRef(val.(string))
- }
- if val, ok := store[constants.EnvKeyJwtRoleClaim]; ok {
- res.JwtRoleClaim = refs.NewStringRef(val.(string))
- }
- if val, ok := store[constants.EnvKeyJwtPublicKey]; ok {
- res.JwtPublicKey = refs.NewStringRef(val.(string))
- }
- if val, ok := store[constants.EnvKeyJwtPrivateKey]; ok {
- res.JwtPrivateKey = refs.NewStringRef(val.(string))
- }
- if val, ok := store[constants.EnvKeyAppURL]; ok {
- res.AppURL = refs.NewStringRef(val.(string))
- }
- if val, ok := store[constants.EnvKeyRedisURL]; ok {
- res.RedisURL = refs.NewStringRef(val.(string))
- }
- if val, ok := store[constants.EnvKeyResetPasswordURL]; ok {
- res.ResetPasswordURL = refs.NewStringRef(val.(string))
- }
- if val, ok := store[constants.EnvKeyGoogleClientID]; ok {
- res.GoogleClientID = refs.NewStringRef(val.(string))
- }
- if val, ok := store[constants.EnvKeyGoogleClientSecret]; ok {
- res.GoogleClientSecret = refs.NewStringRef(val.(string))
- }
- if val, ok := store[constants.EnvKeyFacebookClientID]; ok {
- res.FacebookClientID = refs.NewStringRef(val.(string))
- }
- if val, ok := store[constants.EnvKeyFacebookClientSecret]; ok {
- res.FacebookClientSecret = refs.NewStringRef(val.(string))
- }
- if val, ok := store[constants.EnvKeyGithubClientID]; ok {
- res.GithubClientID = refs.NewStringRef(val.(string))
- }
- if val, ok := store[constants.EnvKeyGithubClientSecret]; ok {
- res.GithubClientSecret = refs.NewStringRef(val.(string))
- }
- if val, ok := store[constants.EnvKeyLinkedInClientID]; ok {
- res.LinkedinClientID = refs.NewStringRef(val.(string))
- }
- if val, ok := store[constants.EnvKeyLinkedInClientSecret]; ok {
- res.LinkedinClientSecret = refs.NewStringRef(val.(string))
- }
- if val, ok := store[constants.EnvKeyAppleClientID]; ok {
- res.AppleClientID = refs.NewStringRef(val.(string))
- }
- if val, ok := store[constants.EnvKeyAppleClientSecret]; ok {
- res.AppleClientSecret = refs.NewStringRef(val.(string))
- }
- if val, ok := store[constants.EnvKeyDiscordClientID]; ok {
- res.DiscordClientID = refs.NewStringRef(val.(string))
- }
- if val, ok := store[constants.EnvKeyDiscordClientSecret]; ok {
- res.DiscordClientSecret = refs.NewStringRef(val.(string))
- }
- if val, ok := store[constants.EnvKeyTwitterClientID]; ok {
- res.TwitterClientID = refs.NewStringRef(val.(string))
- }
- if val, ok := store[constants.EnvKeyTwitterClientSecret]; ok {
- res.TwitterClientSecret = refs.NewStringRef(val.(string))
- }
- if val, ok := store[constants.EnvKeyMicrosoftClientID]; ok {
- res.MicrosoftClientID = refs.NewStringRef(val.(string))
- }
- if val, ok := store[constants.EnvKeyMicrosoftClientSecret]; ok {
- res.MicrosoftClientSecret = refs.NewStringRef(val.(string))
- }
- if val, ok := store[constants.EnvKeyMicrosoftActiveDirectoryTenantID]; ok {
- res.MicrosoftActiveDirectoryTenantID = refs.NewStringRef(val.(string))
- }
- if val, ok := store[constants.EnvKeyTwitchClientID]; ok {
- res.TwitchClientID = refs.NewStringRef(val.(string))
- }
- if val, ok := store[constants.EnvKeyTwitchClientSecret]; ok {
- res.TwitchClientSecret = refs.NewStringRef(val.(string))
- }
- if val, ok := store[constants.EnvKeyRobloxClientID]; ok {
- res.RobloxClientID = refs.NewStringRef(val.(string))
- }
- if val, ok := store[constants.EnvKeyRobloxClientSecret]; ok {
- res.RobloxClientSecret = refs.NewStringRef(val.(string))
- }
- if val, ok := store[constants.EnvKeyOrganizationName]; ok {
- res.OrganizationName = refs.NewStringRef(val.(string))
- }
- if val, ok := store[constants.EnvKeyOrganizationLogo]; ok {
- res.OrganizationLogo = refs.NewStringRef(val.(string))
- }
- if val, ok := store[constants.EnvKeyDefaultAuthorizeResponseType]; ok {
- res.DefaultAuthorizeResponseType = refs.NewStringRef(val.(string))
- }
- if val, ok := store[constants.EnvKeyDefaultAuthorizeResponseMode]; ok {
- res.DefaultAuthorizeResponseMode = refs.NewStringRef(val.(string))
- }
-
- // string slice vars
- res.AllowedOrigins = strings.Split(store[constants.EnvKeyAllowedOrigins].(string), ",")
- res.Roles = strings.Split(store[constants.EnvKeyRoles].(string), ",")
- res.DefaultRoles = strings.Split(store[constants.EnvKeyDefaultRoles].(string), ",")
- // since protected role is optional default split gives array with empty string
- protectedRoles := strings.Split(store[constants.EnvKeyProtectedRoles].(string), ",")
- res.ProtectedRoles = []string{}
- for _, role := range protectedRoles {
- if strings.Trim(role, " ") != "" {
- res.ProtectedRoles = append(res.ProtectedRoles, strings.Trim(role, " "))
- }
- }
-
- // bool vars
- res.DisableEmailVerification = store[constants.EnvKeyDisableEmailVerification].(bool)
- res.DisableBasicAuthentication = store[constants.EnvKeyDisableBasicAuthentication].(bool)
- res.DisableMobileBasicAuthentication = store[constants.EnvKeyDisableMobileBasicAuthentication].(bool)
- res.DisableMagicLinkLogin = store[constants.EnvKeyDisableMagicLinkLogin].(bool)
- res.DisableLoginPage = store[constants.EnvKeyDisableLoginPage].(bool)
- res.DisableSignUp = store[constants.EnvKeyDisableSignUp].(bool)
- 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)
- res.DisablePlayground = store[constants.EnvKeyDisablePlayGround].(bool)
- res.DisableMailOtpLogin = store[constants.EnvKeyDisableMailOTPLogin].(bool)
- res.DisableTotpLogin = store[constants.EnvKeyDisableTOTPLogin].(bool)
-
- return res, nil
-}
diff --git a/server/resolvers/forgot_password.go b/server/resolvers/forgot_password.go
deleted file mode 100644
index 624955e7b..000000000
--- a/server/resolvers/forgot_password.go
+++ /dev/null
@@ -1,169 +0,0 @@
-package resolvers
-
-import (
- "context"
- "fmt"
- "strings"
- "time"
-
- "github.com/google/uuid"
- log "github.com/sirupsen/logrus"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/cookie"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/db/models"
- mailService "github.com/authorizerdev/authorizer/server/email"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/parsers"
- "github.com/authorizerdev/authorizer/server/refs"
- "github.com/authorizerdev/authorizer/server/smsproviders"
- "github.com/authorizerdev/authorizer/server/token"
- "github.com/authorizerdev/authorizer/server/utils"
-)
-
-// ForgotPasswordResolver is a resolver for forgot password mutation
-func ForgotPasswordResolver(ctx context.Context, params model.ForgotPasswordInput) (*model.ForgotPasswordResponse, error) {
- gc, err := utils.GinContextFromContext(ctx)
- if err != nil {
- log.Debug("Failed to get GinContext: ", err)
- return nil, err
- }
-
- isBasicAuthDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableBasicAuthentication)
- if err != nil {
- log.Debug("Error getting basic auth disabled: ", err)
- isBasicAuthDisabled = true
- }
- isEmailVerificationDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableEmailVerification)
- if err != nil {
- log.Debug("Error getting email verification disabled: ", err)
- isEmailVerificationDisabled = true
- }
-
- isMobileBasicAuthDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableMobileBasicAuthentication)
- if err != nil {
- log.Debug("Error getting mobile basic auth disabled: ", err)
- isMobileBasicAuthDisabled = true
- }
- isMobileVerificationDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisablePhoneVerification)
- if err != nil {
- log.Debug("Error getting mobile verification disabled: ", err)
- isMobileVerificationDisabled = true
- }
-
- email := refs.StringValue(params.Email)
- phoneNumber := refs.StringValue(params.PhoneNumber)
- if email == "" && phoneNumber == "" {
- log.Debug("Email or phone number is required")
- return nil, fmt.Errorf(`email or phone number is required`)
- }
- log := log.WithFields(log.Fields{
- "email": refs.StringValue(params.Email),
- "phone_number": refs.StringValue(params.PhoneNumber),
- })
- isEmailLogin := email != ""
- isMobileLogin := phoneNumber != ""
- if isBasicAuthDisabled && isEmailLogin && !isEmailVerificationDisabled {
- log.Debug("Basic authentication is disabled.")
- return nil, fmt.Errorf(`basic authentication is disabled for this instance`)
- }
- if isMobileBasicAuthDisabled && isMobileLogin && !isMobileVerificationDisabled {
- log.Debug("Mobile basic authentication is disabled.")
- return nil, fmt.Errorf(`mobile basic authentication is disabled for this instance`)
- }
- var user *models.User
- if isEmailLogin {
- user, err = db.Provider.GetUserByEmail(ctx, email)
- } else {
- user, err = db.Provider.GetUserByPhoneNumber(ctx, phoneNumber)
- }
- if err != nil {
- log.Debug("Failed to get user: ", err)
- return nil, fmt.Errorf(`bad user credentials`)
- }
- hostname := parsers.GetHost(gc)
- _, nonceHash, err := utils.GenerateNonce()
- if err != nil {
- log.Debug("Failed to generate nonce: ", err)
- return nil, err
- }
- if user.RevokedTimestamp != nil {
- log.Debug("User access is revoked")
- return nil, fmt.Errorf(`user access has been revoked`)
- }
- if isEmailLogin {
- redirectURI := ""
- // give higher preference to params redirect uri
- if strings.TrimSpace(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(email, constants.VerificationTypeForgotPassword, hostname, nonceHash, redirectURI)
- if err != nil {
- log.Debug("Failed to create verification token", err)
- return nil, err
- }
- _, err = db.Provider.AddVerificationRequest(ctx, &models.VerificationRequest{
- Token: verificationToken,
- Identifier: constants.VerificationTypeForgotPassword,
- ExpiresAt: time.Now().Add(time.Minute * 30).Unix(),
- Email: email,
- Nonce: nonceHash,
- RedirectURI: redirectURI,
- })
- if err != nil {
- log.Debug("Failed to add verification request", err)
- return nil, err
- }
- // execute it as go routine so that we can reduce the api latency
- go mailService.SendEmail([]string{email}, constants.VerificationTypeForgotPassword, map[string]interface{}{
- "user": user.ToMap(),
- "organization": utils.GetOrganization(),
- "verification_url": utils.GetForgotPasswordURL(verificationToken, redirectURI),
- })
- return &model.ForgotPasswordResponse{
- Message: `Please check your inbox! We have sent a password reset link.`,
- }, nil
- }
- if isMobileLogin {
- expiresAt := time.Now().Add(1 * time.Minute).Unix()
- otp := utils.GenerateOTP()
- otpData, err := db.Provider.UpsertOTP(ctx, &models.OTP{
- Email: refs.StringValue(user.Email),
- PhoneNumber: refs.StringValue(user.PhoneNumber),
- Otp: otp,
- ExpiresAt: expiresAt,
- })
- if err != nil {
- log.Debug("Failed to add otp: ", err)
- return nil, err
- }
- mfaSession := uuid.NewString()
- err = memorystore.Provider.SetMfaSession(user.ID, mfaSession, expiresAt)
- if err != nil {
- log.Debug("Failed to add mfasession: ", err)
- return nil, err
- }
- cookie.SetMfaSession(gc, mfaSession)
- smsBody := strings.Builder{}
- smsBody.WriteString("Your verification code is: ")
- smsBody.WriteString(otpData.Otp)
- if err := smsproviders.SendSMS(phoneNumber, smsBody.String()); err != nil {
- log.Debug("Failed to send sms: ", err)
- // continue
- }
- return &model.ForgotPasswordResponse{
- Message: "Please enter the OTP sent to your phone number and change your password.",
- ShouldShowMobileOtpScreen: refs.NewBoolRef(true),
- }, nil
- }
- return nil, fmt.Errorf(`email or phone number verification needs to be enabled`)
-}
diff --git a/server/resolvers/generate_jwt_keys.go b/server/resolvers/generate_jwt_keys.go
deleted file mode 100644
index 323e006e8..000000000
--- a/server/resolvers/generate_jwt_keys.go
+++ /dev/null
@@ -1,71 +0,0 @@
-package resolvers
-
-import (
- "context"
- "fmt"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/crypto"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/token"
- "github.com/authorizerdev/authorizer/server/utils"
- log "github.com/sirupsen/logrus"
-)
-
-// GenerateJWTKeysResolver mutation to generate new jwt keys
-func GenerateJWTKeysResolver(ctx context.Context, params model.GenerateJWTKeysInput) (*model.GenerateJWTKeysResponse, error) {
- gc, err := utils.GinContextFromContext(ctx)
- if err != nil {
- log.Debug("Failed to get GinContext: ", err)
- return nil, err
- }
-
- if !token.IsSuperAdmin(gc) {
- log.Debug("Not logged in as super admin")
- return nil, fmt.Errorf("unauthorized")
- }
-
- clientID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyClientID)
- if err != nil {
- log.Debug("Error getting client id: ", err)
- return nil, err
- }
- if crypto.IsHMACA(params.Type) {
- secret, _, err := crypto.NewHMACKey(params.Type, clientID)
- if err != nil {
- log.Debug("Failed to generate new HMAC key: ", err)
- return nil, err
- }
- return &model.GenerateJWTKeysResponse{
- Secret: &secret,
- }, nil
- }
-
- if crypto.IsRSA(params.Type) {
- _, privateKey, publicKey, _, err := crypto.NewRSAKey(params.Type, clientID)
- if err != nil {
- log.Debug("Failed to generate new RSA key: ", err)
- return nil, err
- }
- return &model.GenerateJWTKeysResponse{
- PrivateKey: &privateKey,
- PublicKey: &publicKey,
- }, nil
- }
-
- if crypto.IsECDSA(params.Type) {
- _, privateKey, publicKey, _, err := crypto.NewECDSAKey(params.Type, clientID)
- if err != nil {
- log.Debug("Failed to generate new ECDSA key: ", err)
- return nil, err
- }
- return &model.GenerateJWTKeysResponse{
- PrivateKey: &privateKey,
- PublicKey: &publicKey,
- }, nil
- }
-
- log.Debug("Invalid algorithm: ", params.Type)
- return nil, fmt.Errorf("invalid algorithm")
-}
diff --git a/server/resolvers/invite_members.go b/server/resolvers/invite_members.go
deleted file mode 100644
index 86aac44d9..000000000
--- a/server/resolvers/invite_members.go
+++ /dev/null
@@ -1,202 +0,0 @@
-package resolvers
-
-import (
- "context"
- "errors"
- "fmt"
- "strings"
- "time"
-
- log "github.com/sirupsen/logrus"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/db/models"
- emailservice "github.com/authorizerdev/authorizer/server/email"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/parsers"
- "github.com/authorizerdev/authorizer/server/refs"
- "github.com/authorizerdev/authorizer/server/token"
- "github.com/authorizerdev/authorizer/server/utils"
- "github.com/authorizerdev/authorizer/server/validators"
-)
-
-// InviteMembersResolver resolver to invite members
-func InviteMembersResolver(ctx context.Context, params model.InviteMemberInput) (*model.InviteMembersResponse, error) {
- gc, err := utils.GinContextFromContext(ctx)
- if err != nil {
- log.Debug("Failed to get GinContext: ", err)
- return nil, err
- }
-
- if !token.IsSuperAdmin(gc) {
- log.Debug("Not logged in as super admin.")
- return nil, errors.New("unauthorized")
- }
-
- // this feature is only allowed if email server is configured
- EnvKeyIsEmailServiceEnabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyIsEmailServiceEnabled)
- if err != nil {
- log.Debug("Error getting email verification disabled: ", err)
- EnvKeyIsEmailServiceEnabled = false
- }
-
- if !EnvKeyIsEmailServiceEnabled {
- log.Debug("Email server is not configured")
- return nil, errors.New("email sending is disabled")
- }
-
- isBasicAuthDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableBasicAuthentication)
- if err != nil {
- log.Debug("Failed to get is basic auth disabled")
- return nil, err
- }
- isMagicLinkLoginDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableMagicLinkLogin)
- if err != nil {
- log.Debug("Failed to get is magic link login disabled")
- return nil, err
- }
- if isBasicAuthDisabled && isMagicLinkLoginDisabled {
- log.Debug("Basic authentication and Magic link login is disabled.")
- return nil, errors.New("either basic authentication or magic link login is required")
- }
-
- // filter valid emails
- emails := []string{}
- for _, email := range params.Emails {
- if validators.IsValidEmail(email) {
- emails = append(emails, email)
- }
- }
-
- if len(emails) == 0 {
- log.Debug("No valid email addresses")
- return nil, errors.New("no valid emails found")
- }
-
- // TODO: optimise to use like query instead of looping through emails and getting user individually
- // for each emails check if emails exists in db
- newEmails := []string{}
- for _, email := range emails {
- _, err := db.Provider.GetUserByEmail(ctx, email)
- if err != nil {
- log.Debugf("User with %s email not found, so inviting user", email)
- newEmails = append(newEmails, email)
- } else {
- log.Debugf("User with %s email already exists, so not inviting user", email)
- }
- }
-
- if len(newEmails) == 0 {
- log.Debug("No new emails found.")
- return nil, errors.New("all emails already exist")
- }
-
- // invite new emails
- for _, email := range newEmails {
-
- defaultRolesString, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyDefaultRoles)
- defaultRoles := []string{}
- if err != nil {
- log.Debug("Error getting default roles: ", err)
- defaultRolesString = ""
- } else {
- defaultRoles = strings.Split(defaultRolesString, ",")
- }
-
- user := &models.User{
- Email: refs.NewStringRef(email),
- Roles: strings.Join(defaultRoles, ","),
- }
- hostname := parsers.GetHost(gc)
- verifyEmailURL := hostname + "/verify_email"
- appURL := parsers.GetAppURL(gc)
-
- redirectURL := appURL
- if params.RedirectURI != nil {
- redirectURL = *params.RedirectURI
- }
-
- _, nonceHash, err := utils.GenerateNonce()
- if err != nil {
- return nil, err
- }
-
- verificationToken, err := token.CreateVerificationToken(email, constants.VerificationTypeInviteMember, hostname, nonceHash, redirectURL)
- if err != nil {
- log.Debug("Failed to create verification token: ", err)
- }
-
- verificationRequest := &models.VerificationRequest{
- Token: verificationToken,
- ExpiresAt: time.Now().Add(time.Minute * 30).Unix(),
- Email: email,
- Nonce: nonceHash,
- RedirectURI: redirectURL,
- }
-
- // use magic link login if that option is on
- if !isMagicLinkLoginDisabled {
- user.SignupMethods = constants.AuthRecipeMethodMagicLinkLogin
- verificationRequest.Identifier = constants.VerificationTypeMagicLinkLogin
- } else {
- // use basic authentication if that option is on
- user.SignupMethods = constants.AuthRecipeMethodBasicAuth
- verificationRequest.Identifier = constants.VerificationTypeInviteMember
-
- isMFAEnforced, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyEnforceMultiFactorAuthentication)
- if err != nil {
- log.Debug("MFA service not enabled: ", err)
- isMFAEnforced = false
- }
-
- if isMFAEnforced {
- user.IsMultiFactorAuthEnabled = refs.NewBoolRef(true)
- }
- verifyEmailURL = appURL + "/setup-password"
-
- }
-
- user, err = db.Provider.AddUser(ctx, user)
- if err != nil {
- log.Debugf("Error adding user: %s, err: %v", email, err)
- return nil, err
- }
-
- _, err = db.Provider.AddVerificationRequest(ctx, verificationRequest)
- if err != nil {
- log.Debugf("Error adding verification request: %s, err: %v", email, err)
- return nil, err
- }
-
- // exec it as go routine so that we can reduce the api latency
- go emailservice.SendEmail([]string{refs.StringValue(user.Email)}, constants.VerificationTypeInviteMember, map[string]interface{}{
- "user": user.ToMap(),
- "organization": utils.GetOrganization(),
- "verification_url": utils.GetInviteVerificationURL(verifyEmailURL, verificationToken, redirectURL),
- })
- }
-
- InvitedUsers := []*model.User{}
-
- for _, email := range newEmails {
- user, err := db.Provider.GetUserByEmail(ctx, email)
-
- if err != nil {
- log.Debugf("err: %s", err.Error())
- return nil, err
- }
-
- InvitedUsers = append(InvitedUsers, &model.User{
- Email: user.Email,
- ID: user.ID,
- })
-
- }
-
- return &model.InviteMembersResponse{
- Message: fmt.Sprintf("%d user(s) invited successfully.", len(newEmails)),
- Users: InvitedUsers,
- }, nil
-}
diff --git a/server/resolvers/login.go b/server/resolvers/login.go
deleted file mode 100644
index 159c18e26..000000000
--- a/server/resolvers/login.go
+++ /dev/null
@@ -1,423 +0,0 @@
-package resolvers
-
-import (
- "context"
- "fmt"
- "strings"
- "time"
-
- "github.com/google/uuid"
- "golang.org/x/crypto/bcrypt"
-
- log "github.com/sirupsen/logrus"
-
- "github.com/authorizerdev/authorizer/server/authenticators"
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/cookie"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/db/models"
- mailService "github.com/authorizerdev/authorizer/server/email"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/refs"
- "github.com/authorizerdev/authorizer/server/smsproviders"
- "github.com/authorizerdev/authorizer/server/token"
- "github.com/authorizerdev/authorizer/server/utils"
- "github.com/authorizerdev/authorizer/server/validators"
-)
-
-// LoginResolver is a resolver for login mutation
-// User can login with email or phone number, but not both
-func LoginResolver(ctx context.Context, params model.LoginInput) (*model.AuthResponse, error) {
- var res *model.AuthResponse
-
- gc, err := utils.GinContextFromContext(ctx)
- if err != nil {
- log.Debug("Failed to get GinContext: ", err)
- return res, err
- }
-
- isBasicAuthDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableBasicAuthentication)
- if err != nil {
- log.Debug("Error getting basic auth disabled: ", err)
- isBasicAuthDisabled = true
- }
-
- isMobileBasicAuthDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableMobileBasicAuthentication)
- if err != nil {
- log.Debug("Error getting mobile basic auth disabled: ", err)
- isMobileBasicAuthDisabled = true
- }
-
- email := refs.StringValue(params.Email)
- phoneNumber := refs.StringValue(params.PhoneNumber)
- if email == "" && phoneNumber == "" {
- log.Debug("Email or phone number is required")
- return res, fmt.Errorf(`email or phone number is required`)
- }
- log := log.WithFields(log.Fields{
- "email": refs.StringValue(params.Email),
- "phone_number": refs.StringValue(params.PhoneNumber),
- })
- isEmailLogin := email != ""
- isMobileLogin := phoneNumber != ""
- if isBasicAuthDisabled {
- log.Debug("Basic authentication is disabled.")
- return res, fmt.Errorf(`basic authentication is disabled for this instance`)
- }
- if isMobileBasicAuthDisabled && isMobileLogin {
- log.Debug("Mobile basic authentication is disabled.")
- return res, fmt.Errorf(`mobile basic authentication is disabled for this instance`)
- }
- var user *models.User
- if isEmailLogin {
- user, err = db.Provider.GetUserByEmail(ctx, email)
- } else {
- user, err = db.Provider.GetUserByPhoneNumber(ctx, phoneNumber)
- }
- if err != nil {
- log.Debug("Failed to get user: ", err)
- return res, fmt.Errorf(`user not found`)
- }
- if user.RevokedTimestamp != nil {
- log.Debug("User access is revoked")
- return res, fmt.Errorf(`user access has been revoked`)
- }
- isEmailServiceEnabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyIsEmailServiceEnabled)
- if err != nil || !isEmailServiceEnabled {
- log.Debug("Email service not enabled: ", err)
- }
- isSMSServiceEnabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyIsSMSServiceEnabled)
- if err != nil || !isSMSServiceEnabled {
- log.Debug("SMS service not enabled: ", err)
- }
- // If multi factor authentication is enabled and we need to generate OTP for mail / sms based MFA
- generateOTP := func(expiresAt int64) (*models.OTP, error) {
- otp := utils.GenerateOTP()
- otpData, err := db.Provider.UpsertOTP(ctx, &models.OTP{
- Email: refs.StringValue(user.Email),
- PhoneNumber: refs.StringValue(user.PhoneNumber),
- Otp: otp,
- ExpiresAt: expiresAt,
- })
- if err != nil {
- log.Debug("Failed to add otp: ", err)
- return nil, err
- }
- return otpData, nil
- }
- setOTPMFaSession := func(expiresAt int64) error {
- mfaSession := uuid.NewString()
- err = memorystore.Provider.SetMfaSession(user.ID, mfaSession, expiresAt)
- if err != nil {
- log.Debug("Failed to add mfasession: ", err)
- return err
- }
- cookie.SetMfaSession(gc, mfaSession)
- return nil
- }
- if isEmailLogin {
- if !strings.Contains(user.SignupMethods, constants.AuthRecipeMethodBasicAuth) {
- log.Debug("User signup method is not basic auth")
- return res, fmt.Errorf(`user has not signed up email & password`)
- }
-
- if user.EmailVerifiedAt == nil {
- // Check if email service is enabled
- // Send email verification via otp
- if !isEmailServiceEnabled {
- log.Debug("User email is not verified and email service is not enabled")
- return res, fmt.Errorf(`email not verified`)
- } else {
- if vreq, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeBasicAuthSignup); err == nil && vreq != nil {
- // if verification request exists and not expired then return
- // if verification request exists and expired then delete it and proceed
- if vreq.ExpiresAt <= time.Now().Unix() {
- if err := db.Provider.DeleteVerificationRequest(ctx, vreq); err != nil {
- log.Debug("Failed to delete verification request: ", err)
- // continue with the flow
- }
- } else {
- log.Debug("Verification request exists. Please verify email")
- return res, fmt.Errorf(`email verification pending`)
- }
- }
- expiresAt := time.Now().Add(1 * time.Minute).Unix()
- otpData, err := generateOTP(expiresAt)
- if err != nil {
- log.Debug("Failed to generate otp: ", err)
- return nil, err
- }
- if err := setOTPMFaSession(expiresAt); err != nil {
- log.Debug("Failed to set mfa session: ", err)
- return nil, err
- }
- go func() {
- // exec it as go routine so that we can reduce the api latency
- if err := mailService.SendEmail([]string{email}, constants.VerificationTypeOTP, map[string]interface{}{
- "user": user.ToMap(),
- "organization": utils.GetOrganization(),
- "otp": otpData.Otp,
- }); err != nil {
- log.Debug("Failed to send otp email: ", err)
- }
- utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, constants.AuthRecipeMethodBasicAuth, user)
- }()
- return &model.AuthResponse{
- Message: "Please check email inbox for the OTP",
- ShouldShowEmailOtpScreen: refs.NewBoolRef(isEmailLogin),
- }, nil
- }
- }
- } else {
- if !strings.Contains(user.SignupMethods, constants.AuthRecipeMethodMobileBasicAuth) {
- log.Debug("User signup method is not mobile basic auth")
- return res, fmt.Errorf(`user has not signed up with phone number & password`)
- }
-
- if user.PhoneNumberVerifiedAt == nil {
- if !isSMSServiceEnabled {
- log.Debug("User phone number is not verified")
- return res, fmt.Errorf(`phone number is not verified and sms service is not enabled`)
- } else {
- expiresAt := time.Now().Add(1 * time.Minute).Unix()
- otpData, err := generateOTP(expiresAt)
- if err != nil {
- log.Debug("Failed to generate otp: ", err)
- return nil, err
- }
- if err := setOTPMFaSession(expiresAt); err != nil {
- log.Debug("Failed to set mfa session: ", err)
- return nil, err
- }
- go func() {
- smsBody := strings.Builder{}
- smsBody.WriteString("Your verification code is: ")
- smsBody.WriteString(otpData.Otp)
- utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, constants.AuthRecipeMethodMobileBasicAuth, user)
- if err := smsproviders.SendSMS(phoneNumber, smsBody.String()); err != nil {
- log.Debug("Failed to send sms: ", err)
- }
- }()
- return &model.AuthResponse{
- Message: "Please check text message for the OTP",
- ShouldShowMobileOtpScreen: refs.NewBoolRef(isMobileLogin),
- }, nil
- }
- }
- }
- err = bcrypt.CompareHashAndPassword([]byte(*user.Password), []byte(params.Password))
- if err != nil {
- log.Debug("Failed to compare password: ", err)
- return res, fmt.Errorf(`bad user credentials`)
- }
- defaultRolesString, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyDefaultRoles)
- roles := []string{}
- if err != nil {
- log.Debug("Error getting default roles: ", err)
- defaultRolesString = ""
- } else {
- roles = strings.Split(defaultRolesString, ",")
- }
- currentRoles := strings.Split(user.Roles, ",")
- if len(params.Roles) > 0 {
- if !validators.IsValidRoles(params.Roles, currentRoles) {
- log.Debug("Invalid roles: ", params.Roles)
- return res, fmt.Errorf(`invalid roles`)
- }
- roles = params.Roles
- }
- scope := []string{"openid", "email", "profile"}
- if params.Scope != nil && len(scope) > 0 {
- scope = params.Scope
- }
-
- isMFADisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableMultiFactorAuthentication)
- if err != nil || !isMFADisabled {
- log.Debug("MFA service not enabled: ", err)
- }
-
- isTOTPLoginDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableTOTPLogin)
- if err != nil || !isTOTPLoginDisabled {
- log.Debug("totp service not enabled: ", err)
- }
-
- isMailOTPDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableMailOTPLogin)
- if err != nil || !isMailOTPDisabled {
- log.Debug("mail OTP service not enabled: ", err)
- }
-
- isSMSOTPDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisablePhoneVerification)
- if err != nil || !isSMSOTPDisabled {
- log.Debug("sms OTP service not enabled: ", err)
- }
-
- // If multi factor authentication is enabled and is email based login and email otp is enabled
- if refs.BoolValue(user.IsMultiFactorAuthEnabled) && !isMFADisabled && !isMailOTPDisabled && isEmailServiceEnabled && isEmailLogin {
- expiresAt := time.Now().Add(1 * time.Minute).Unix()
- otpData, err := generateOTP(expiresAt)
- if err != nil {
- log.Debug("Failed to generate otp: ", err)
- return nil, err
- }
- if err := setOTPMFaSession(expiresAt); err != nil {
- log.Debug("Failed to set mfa session: ", err)
- return nil, err
- }
- go func() {
- // exec it as go routine so that we can reduce the api latency
- if err := mailService.SendEmail([]string{email}, constants.VerificationTypeOTP, map[string]interface{}{
- "user": user.ToMap(),
- "organization": utils.GetOrganization(),
- "otp": otpData.Otp,
- }); err != nil {
- log.Debug("Failed to send otp email: ", err)
- }
- utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, constants.AuthRecipeMethodBasicAuth, user)
- }()
- return &model.AuthResponse{
- Message: "Please check email inbox for the OTP",
- ShouldShowEmailOtpScreen: refs.NewBoolRef(isMobileLogin),
- }, nil
- }
- // If multi factor authentication is enabled and is sms based login and sms otp is enabled
- if refs.BoolValue(user.IsMultiFactorAuthEnabled) && !isMFADisabled && !isSMSOTPDisabled && isSMSServiceEnabled && isMobileLogin {
- expiresAt := time.Now().Add(1 * time.Minute).Unix()
- otpData, err := generateOTP(expiresAt)
- if err != nil {
- log.Debug("Failed to generate otp: ", err)
- return nil, err
- }
- if err := setOTPMFaSession(expiresAt); err != nil {
- log.Debug("Failed to set mfa session: ", err)
- return nil, err
- }
- go func() {
- smsBody := strings.Builder{}
- smsBody.WriteString("Your verification code is: ")
- smsBody.WriteString(otpData.Otp)
- utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, constants.AuthRecipeMethodMobileBasicAuth, user)
- if err := smsproviders.SendSMS(phoneNumber, smsBody.String()); err != nil {
- log.Debug("Failed to send sms: ", err)
- }
- }()
- return &model.AuthResponse{
- Message: "Please check text message for the OTP",
- ShouldShowMobileOtpScreen: refs.NewBoolRef(isMobileLogin),
- }, nil
- }
- // If mfa enabled and also totp enabled
- if refs.BoolValue(user.IsMultiFactorAuthEnabled) && !isMFADisabled && !isTOTPLoginDisabled {
- expiresAt := time.Now().Add(3 * time.Minute).Unix()
- if err := setOTPMFaSession(expiresAt); err != nil {
- log.Debug("Failed to set mfa session: ", err)
- return nil, err
- }
- authenticator, err := db.Provider.GetAuthenticatorDetailsByUserId(ctx, user.ID, constants.EnvKeyTOTPAuthenticator)
- if err != nil || authenticator == nil || authenticator.VerifiedAt == nil {
- // generate totp
- // Generate a base64 URL and initiate the registration for TOTP
- authConfig, err := authenticators.Provider.Generate(ctx, user.ID)
- if err != nil {
- log.Debug("error while generating base64 url: ", err)
- return nil, err
- }
- recoveryCodes := []*string{}
- for _, code := range authConfig.RecoveryCodes {
- recoveryCodes = append(recoveryCodes, refs.NewStringRef(code))
- }
- // when user is first time registering for totp
- res = &model.AuthResponse{
- Message: `Proceed to totp verification screen`,
- ShouldShowTotpScreen: refs.NewBoolRef(true),
- AuthenticatorScannerImage: refs.NewStringRef(authConfig.ScannerImage),
- AuthenticatorSecret: refs.NewStringRef(authConfig.Secret),
- AuthenticatorRecoveryCodes: recoveryCodes,
- }
- return res, nil
- } else {
- //when user is already register for totp
- res = &model.AuthResponse{
- Message: `Proceed to totp screen`,
- ShouldShowTotpScreen: refs.NewBoolRef(true),
- }
- return res, nil
- }
- }
-
- code := ""
- codeChallenge := ""
- nonce := ""
- if params.State != nil {
- // Get state from store
- authorizeState, _ := memorystore.Provider.GetState(refs.StringValue(params.State))
- if authorizeState != "" {
- authorizeStateSplit := strings.Split(authorizeState, "@@")
- if len(authorizeStateSplit) > 1 {
- code = authorizeStateSplit[0]
- codeChallenge = authorizeStateSplit[1]
- } else {
- nonce = authorizeState
- }
- go memorystore.Provider.RemoveState(refs.StringValue(params.State))
- }
- }
-
- if nonce == "" {
- nonce = uuid.New().String()
- }
- authToken, err := token.CreateAuthToken(gc, user, roles, scope, constants.AuthRecipeMethodBasicAuth, nonce, code)
- if err != nil {
- log.Debug("Failed to create auth token", err)
- return res, err
- }
-
- // TODO add to other login options as well
- // Code challenge could be optional if PKCE flow is not used
- if code != "" {
- if err := memorystore.Provider.SetState(code, codeChallenge+"@@"+authToken.FingerPrintHash); err != nil {
- log.Debug("SetState failed: ", err)
- return res, err
- }
- }
-
- expiresIn := authToken.AccessToken.ExpiresAt - time.Now().Unix()
- if expiresIn <= 0 {
- expiresIn = 1
- }
-
- res = &model.AuthResponse{
- Message: `Logged in successfully`,
- AccessToken: &authToken.AccessToken.Token,
- IDToken: &authToken.IDToken.Token,
- ExpiresIn: &expiresIn,
- User: user.AsAPIUser(),
- }
-
- cookie.SetSession(gc, authToken.FingerPrintHash)
- sessionStoreKey := constants.AuthRecipeMethodBasicAuth + ":" + user.ID
- memorystore.Provider.SetUserSession(sessionStoreKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash, authToken.SessionTokenExpiresAt)
- memorystore.Provider.SetUserSession(sessionStoreKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token, authToken.AccessToken.ExpiresAt)
-
- if authToken.RefreshToken != nil {
- res.RefreshToken = &authToken.RefreshToken.Token
- memorystore.Provider.SetUserSession(sessionStoreKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token, authToken.RefreshToken.ExpiresAt)
- }
-
- go func() {
- // Register event
- if isEmailLogin {
- utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, constants.AuthRecipeMethodBasicAuth, user)
- } else {
- utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, constants.AuthRecipeMethodMobileBasicAuth, user)
- }
- // Record session
- db.Provider.AddSession(ctx, &models.Session{
- UserID: user.ID,
- UserAgent: utils.GetUserAgent(gc.Request),
- IP: utils.GetIP(gc.Request),
- })
- }()
-
- return res, nil
-}
diff --git a/server/resolvers/logout.go b/server/resolvers/logout.go
deleted file mode 100644
index 0988e1696..000000000
--- a/server/resolvers/logout.go
+++ /dev/null
@@ -1,42 +0,0 @@
-package resolvers
-
-import (
- "context"
-
- log "github.com/sirupsen/logrus"
-
- "github.com/authorizerdev/authorizer/server/cookie"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/token"
- "github.com/authorizerdev/authorizer/server/utils"
-)
-
-// LogoutResolver is a resolver for logout mutation
-func LogoutResolver(ctx context.Context) (*model.Response, error) {
- gc, err := utils.GinContextFromContext(ctx)
- if err != nil {
- log.Debug("Failed to get GinContext: ", err)
- return nil, err
- }
-
- tokenData, err := token.GetUserIDFromSessionOrAccessToken(gc)
- if err != nil {
- log.Debug("Failed GetUserIDFromSessionOrAccessToken: ", err)
- return nil, err
- }
-
- sessionKey := tokenData.UserID
- if tokenData.LoginMethod != "" {
- sessionKey = tokenData.LoginMethod + ":" + tokenData.UserID
- }
-
- memorystore.Provider.DeleteUserSession(sessionKey, tokenData.Nonce)
- cookie.DeleteSession(gc)
-
- res := &model.Response{
- Message: "Logged out successfully",
- }
-
- return res, nil
-}
diff --git a/server/resolvers/magic_link_login.go b/server/resolvers/magic_link_login.go
deleted file mode 100644
index 4edacdf98..000000000
--- a/server/resolvers/magic_link_login.go
+++ /dev/null
@@ -1,236 +0,0 @@
-package resolvers
-
-import (
- "context"
- "fmt"
- "strings"
- "time"
-
- log "github.com/sirupsen/logrus"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/db/models"
- "github.com/authorizerdev/authorizer/server/email"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/parsers"
- "github.com/authorizerdev/authorizer/server/refs"
- "github.com/authorizerdev/authorizer/server/token"
- "github.com/authorizerdev/authorizer/server/utils"
- "github.com/authorizerdev/authorizer/server/validators"
-)
-
-// MagicLinkLoginResolver is a resolver for magic link login mutation
-func MagicLinkLoginResolver(ctx context.Context, params model.MagicLinkLoginInput) (*model.Response, error) {
- var res *model.Response
-
- gc, err := utils.GinContextFromContext(ctx)
- if err != nil {
- log.Debug("Failed to get GinContext: ", err)
- return res, err
- }
-
- isMagicLinkLoginDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableMagicLinkLogin)
- if err != nil {
- log.Debug("Error getting magic link login disabled: ", err)
- isMagicLinkLoginDisabled = true
- }
-
- if isMagicLinkLoginDisabled {
- log.Debug("Magic link login is disabled.")
- return res, fmt.Errorf(`magic link login is disabled for this instance`)
- }
-
- params.Email = strings.ToLower(params.Email)
-
- if !validators.IsValidEmail(params.Email) {
- log.Debug("Invalid email")
- return res, fmt.Errorf(`invalid email address`)
- }
-
- log := log.WithFields(log.Fields{
- "email": params.Email,
- })
-
- inputRoles := []string{}
-
- user := &models.User{
- Email: refs.NewStringRef(params.Email),
- }
-
- // find user with email
- existingUser, err := db.Provider.GetUserByEmail(ctx, params.Email)
- if err != nil {
- isSignupDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableSignUp)
- if err != nil {
- log.Debug("Error getting signup disabled: ", err)
- }
- if isSignupDisabled {
- log.Debug("Signup is disabled.")
- return res, fmt.Errorf(`signup is disabled for this instance`)
- }
-
- user.SignupMethods = constants.AuthRecipeMethodMagicLinkLogin
- // define roles for new user
- if len(params.Roles) > 0 {
- // check if roles exists
- rolesString, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyRoles)
- roles := []string{}
- if err != nil {
- log.Debug("Error getting roles: ", err)
- return res, err
- } else {
- roles = strings.Split(rolesString, ",")
- }
- if !validators.IsValidRoles(params.Roles, roles) {
- log.Debug("Invalid roles: ", params.Roles)
- return res, fmt.Errorf(`invalid roles`)
- } else {
- inputRoles = params.Roles
- }
- } else {
- inputRolesString, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyDefaultRoles)
- if err != nil {
- log.Debug("Error getting default roles: ", err)
- return res, fmt.Errorf(`invalid roles`)
- } else {
- inputRoles = strings.Split(inputRolesString, ",")
- }
- }
-
- user.Roles = strings.Join(inputRoles, ",")
- user, _ = db.Provider.AddUser(ctx, user)
- go utils.RegisterEvent(ctx, constants.UserCreatedWebhookEvent, constants.AuthRecipeMethodMagicLinkLogin, user)
- } else {
- user = existingUser
- // There multiple scenarios with roles here in magic link login
- // 1. user has access to protected roles + roles and trying to login
- // 2. user has not signed up for one of the available role but trying to signup.
- // Need to modify roles in this case
-
- if user.RevokedTimestamp != nil {
- log.Debug("User access is revoked at: ", user.RevokedTimestamp)
- return res, fmt.Errorf(`user access has been revoked`)
- }
-
- // find the unassigned roles
- if len(params.Roles) <= 0 {
- inputRolesString, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyDefaultRoles)
- if err != nil {
- log.Debug("Error getting default roles: ", err)
- return res, fmt.Errorf(`invalid default roles`)
- } else {
- inputRoles = strings.Split(inputRolesString, ",")
- }
- }
- existingRoles := strings.Split(existingUser.Roles, ",")
- unasignedRoles := []string{}
- for _, ir := range inputRoles {
- if !utils.StringSliceContains(existingRoles, ir) {
- unasignedRoles = append(unasignedRoles, ir)
- }
- }
-
- if len(unasignedRoles) > 0 {
- // check if it contains protected unassigned role
- hasProtectedRole := false
- protectedRolesString, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyProtectedRoles)
- protectedRoles := []string{}
- if err != nil {
- log.Debug("Error getting protected roles: ", err)
- return res, err
- } else {
- protectedRoles = strings.Split(protectedRolesString, ",")
- }
- for _, ur := range unasignedRoles {
- if utils.StringSliceContains(protectedRoles, ur) {
- hasProtectedRole = true
- }
- }
-
- if hasProtectedRole {
- log.Debug("User is not assigned one of the protected roles", unasignedRoles)
- return res, fmt.Errorf(`invalid roles`)
- } else {
- user.Roles = existingUser.Roles + "," + strings.Join(unasignedRoles, ",")
- }
- } else {
- user.Roles = existingUser.Roles
- }
-
- signupMethod := existingUser.SignupMethods
- if !strings.Contains(signupMethod, constants.AuthRecipeMethodMagicLinkLogin) {
- signupMethod = signupMethod + "," + constants.AuthRecipeMethodMagicLinkLogin
- }
-
- user.SignupMethods = signupMethod
- user, _ = db.Provider.UpdateUser(ctx, user)
- if err != nil {
- log.Debug("Failed to update user: ", err)
- }
- }
-
- hostname := parsers.GetHost(gc)
- isEmailVerificationDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableEmailVerification)
- if err != nil {
- log.Debug("Error getting email verification disabled: ", err)
- isEmailVerificationDisabled = true
- }
- if !isEmailVerificationDisabled {
- // insert verification request
- _, nonceHash, err := utils.GenerateNonce()
- if err != nil {
- log.Debug("Failed to generate nonce: ", err)
- return res, err
- }
- redirectURLParams := "&roles=" + strings.Join(inputRoles, ",")
- if params.State != nil {
- redirectURLParams = redirectURLParams + "&state=" + refs.StringValue(params.State)
- }
- if params.Scope != nil && len(params.Scope) > 0 {
- redirectURLParams = redirectURLParams + "&scope=" + strings.Join(params.Scope, " ")
- }
- redirectURL := parsers.GetAppURL(gc)
- if params.RedirectURI != nil {
- redirectURL = *params.RedirectURI
- }
-
- if strings.Contains(redirectURL, "?") {
- redirectURL = redirectURL + "&" + redirectURLParams
- } else {
- redirectURL = redirectURL + "?" + strings.TrimPrefix(redirectURLParams, "&")
- }
-
- verificationType := constants.VerificationTypeMagicLinkLogin
- verificationToken, err := token.CreateVerificationToken(params.Email, verificationType, hostname, nonceHash, redirectURL)
- if err != nil {
- log.Debug("Failed to create verification token: ", err)
- }
- _, err = db.Provider.AddVerificationRequest(ctx, &models.VerificationRequest{
- Token: verificationToken,
- Identifier: verificationType,
- ExpiresAt: time.Now().Add(time.Minute * 30).Unix(),
- Email: params.Email,
- Nonce: nonceHash,
- RedirectURI: redirectURL,
- })
- if err != nil {
- log.Debug("Failed to add verification request in db: ", err)
- return res, err
- }
-
- // exec it as go routine so that we can reduce the api latency
- go email.SendEmail([]string{params.Email}, constants.VerificationTypeMagicLinkLogin, map[string]interface{}{
- "user": user.ToMap(),
- "organization": utils.GetOrganization(),
- "verification_url": utils.GetEmailVerificationURL(verificationToken, hostname, redirectURL),
- })
- }
-
- res = &model.Response{
- Message: `Magic Link has been sent to your email. Please check your inbox!`,
- }
-
- return res, nil
-}
diff --git a/server/resolvers/meta.go b/server/resolvers/meta.go
deleted file mode 100644
index 9fb14c8b2..000000000
--- a/server/resolvers/meta.go
+++ /dev/null
@@ -1,196 +0,0 @@
-package resolvers
-
-import (
- "context"
-
- log "github.com/sirupsen/logrus"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
-)
-
-// MetaResolver is a resolver for meta query
-func MetaResolver(ctx context.Context) (*model.Meta, error) {
- clientID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyClientID)
- if err != nil {
- return nil, err
- }
-
- googleClientID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyGoogleClientID)
- if err != nil {
- log.Debug("Failed to get Google Client ID from environment variable", err)
- googleClientID = ""
- }
-
- googleClientSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyGoogleClientSecret)
- if err != nil {
- log.Debug("Failed to get Google Client Secret from environment variable", err)
- googleClientSecret = ""
- }
-
- facebookClientID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyFacebookClientID)
- if err != nil {
- log.Debug("Failed to get Facebook Client ID from environment variable", err)
- facebookClientID = ""
- }
-
- facebookClientSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyFacebookClientSecret)
- if err != nil {
- log.Debug("Failed to get Facebook Client Secret from environment variable", err)
- facebookClientSecret = ""
- }
-
- linkedClientID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyLinkedInClientID)
- if err != nil {
- log.Debug("Failed to get LinkedIn Client ID from environment variable", err)
- linkedClientID = ""
- }
-
- linkedInClientSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyLinkedInClientSecret)
- if err != nil {
- log.Debug("Failed to get LinkedIn Client Secret from environment variable", err)
- linkedInClientSecret = ""
- }
-
- appleClientID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAppleClientID)
- if err != nil {
- log.Debug("Failed to get Apple Client ID from environment variable", err)
- appleClientID = ""
- }
-
- appleClientSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAppleClientSecret)
- if err != nil {
- log.Debug("Failed to get Apple Client Secret from environment variable", err)
- appleClientSecret = ""
- }
-
- githubClientID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyGithubClientID)
- if err != nil {
- log.Debug("Failed to get Github Client ID from environment variable", err)
- githubClientID = ""
- }
-
- githubClientSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyGithubClientSecret)
- if err != nil {
- log.Debug("Failed to get Github Client Secret from environment variable", err)
- githubClientSecret = ""
- }
-
- twitterClientID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyTwitterClientID)
- if err != nil {
- log.Debug("Failed to get Twitter Client ID from environment variable", err)
- twitterClientID = ""
- }
-
- twitterClientSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyTwitterClientSecret)
- if err != nil {
- log.Debug("Failed to get Twitter Client Secret from environment variable", err)
- twitterClientSecret = ""
- }
-
- microsoftClientID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyMicrosoftClientID)
- if err != nil {
- log.Debug("Failed to get Microsoft Client ID from environment variable", err)
- microsoftClientID = ""
- }
-
- microsoftClientSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyMicrosoftClientSecret)
- if err != nil {
- log.Debug("Failed to get Microsoft Client Secret from environment variable", err)
- microsoftClientSecret = ""
- }
-
- twitchClientID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyTwitchClientID)
- if err != nil {
- log.Debug("Failed to get Twitch Client ID from environment variable", err)
- microsoftClientID = ""
- }
-
- twitchClientSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyTwitchClientSecret)
- if err != nil {
- log.Debug("Failed to get Twitch Client Secret from environment variable", err)
- microsoftClientSecret = ""
- }
-
- robloxClientID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyRobloxClientID)
- if err != nil {
- log.Debug("Failed to get Roblox Client ID from environment variable", err)
- microsoftClientID = ""
- }
-
- robloxClientSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyRobloxClientSecret)
- if err != nil {
- log.Debug("Failed to get Roblox Client Secret from environment variable", err)
- microsoftClientSecret = ""
- }
-
- isBasicAuthDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableBasicAuthentication)
- if err != nil {
- log.Debug("Failed to get Disable Basic Authentication from environment variable", err)
- isBasicAuthDisabled = true
- }
- isMobileBasicAuthDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableMobileBasicAuthentication)
- if err != nil {
- log.Debug("Failed to get Disable Basic Authentication from environment variable", err)
- isMobileBasicAuthDisabled = true
- }
- isMobileVerificationDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisablePhoneVerification)
- if err != nil {
- log.Debug("Failed to get Disable Basic Authentication from environment variable", err)
- isMobileVerificationDisabled = true
- }
-
- isEmailVerificationDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableEmailVerification)
- if err != nil {
- log.Debug("Failed to get Disable Email Verification from environment variable", err)
- isEmailVerificationDisabled = true
- }
-
- isMagicLinkLoginDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableMagicLinkLogin)
- if err != nil {
- log.Debug("Failed to get Disable Magic Link Login from environment variable", err)
- isMagicLinkLoginDisabled = true
- }
-
- isSignUpDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableSignUp)
- if err != nil {
- log.Debug("Failed to get Disable Signup from environment variable", err)
- isSignUpDisabled = true
- }
-
- isStrongPasswordDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableStrongPassword)
- if err != nil {
- log.Debug("Failed to get Disable Signup from environment variable", err)
- isSignUpDisabled = true
- }
-
- isMultiFactorAuthenticationEnabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableMultiFactorAuthentication)
- if err != nil {
- log.Debug("Failed to get Disable Multi Factor Authentication from environment variable", err)
- isSignUpDisabled = true
- }
-
- metaInfo := model.Meta{
- Version: constants.VERSION,
- ClientID: clientID,
- IsGoogleLoginEnabled: googleClientID != "" && googleClientSecret != "",
- IsGithubLoginEnabled: githubClientID != "" && githubClientSecret != "",
- IsFacebookLoginEnabled: facebookClientID != "" && facebookClientSecret != "",
- IsLinkedinLoginEnabled: linkedClientID != "" && linkedInClientSecret != "",
- IsAppleLoginEnabled: appleClientID != "" && appleClientSecret != "",
- IsTwitterLoginEnabled: twitterClientID != "" && twitterClientSecret != "",
- IsMicrosoftLoginEnabled: microsoftClientID != "" && microsoftClientSecret != "",
- IsBasicAuthenticationEnabled: !isBasicAuthDisabled,
- IsEmailVerificationEnabled: !isEmailVerificationDisabled,
- IsMagicLinkLoginEnabled: !isMagicLinkLoginDisabled,
- IsSignUpEnabled: !isSignUpDisabled,
- IsStrongPasswordEnabled: !isStrongPasswordDisabled,
- IsMultiFactorAuthEnabled: !isMultiFactorAuthenticationEnabled,
- IsMobileBasicAuthenticationEnabled: !isMobileBasicAuthDisabled,
- IsPhoneVerificationEnabled: !isMobileVerificationDisabled,
- IsTwitchLoginEnabled: twitchClientID != "" && twitchClientSecret != "",
- IsRobloxLoginEnabled: robloxClientID != "" && robloxClientSecret != "",
- }
- return &metaInfo, nil
-}
diff --git a/server/resolvers/mobile_login.go b/server/resolvers/mobile_login.go
deleted file mode 100644
index c3ab9348f..000000000
--- a/server/resolvers/mobile_login.go
+++ /dev/null
@@ -1,229 +0,0 @@
-package resolvers
-
-import (
- "context"
- "fmt"
- "strings"
- "time"
-
- "github.com/google/uuid"
- log "github.com/sirupsen/logrus"
- "golang.org/x/crypto/bcrypt"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/cookie"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/db/models"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/refs"
- "github.com/authorizerdev/authorizer/server/smsproviders"
- "github.com/authorizerdev/authorizer/server/token"
- "github.com/authorizerdev/authorizer/server/utils"
- "github.com/authorizerdev/authorizer/server/validators"
-)
-
-// MobileLoginResolver is a resolver for mobile login mutation
-func MobileLoginResolver(ctx context.Context, params model.MobileLoginInput) (*model.AuthResponse, error) {
- var res *model.AuthResponse
-
- gc, err := utils.GinContextFromContext(ctx)
- if err != nil {
- log.Debug("Failed to get GinContext: ", err)
- return res, err
- }
-
- isBasicAuthDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableMobileBasicAuthentication)
- if err != nil {
- log.Debug("Error getting mobile basic auth disabled: ", err)
- isBasicAuthDisabled = true
- }
-
- if isBasicAuthDisabled {
- log.Debug("Basic authentication is disabled.")
- return res, fmt.Errorf(`phone number based basic authentication is disabled for this instance`)
- }
-
- log := log.WithFields(log.Fields{
- "phone_number": params.PhoneNumber,
- })
-
- user, err := db.Provider.GetUserByPhoneNumber(ctx, params.PhoneNumber)
- if err != nil {
- log.Debug("Failed to get user by phone number: ", err)
- return res, fmt.Errorf(`bad user credentials`)
- }
-
- if user.RevokedTimestamp != nil {
- log.Debug("User access is revoked")
- return res, fmt.Errorf(`user access has been revoked`)
- }
-
- if !strings.Contains(user.SignupMethods, constants.AuthRecipeMethodMobileBasicAuth) {
- log.Debug("User signup method is not mobile basic auth")
- return res, fmt.Errorf(`user has not signed up with phone number & password`)
- }
-
- if user.PhoneNumberVerifiedAt == nil {
- log.Debug("User phone number is not verified")
- return res, fmt.Errorf(`phone number is not verified`)
- }
-
- err = bcrypt.CompareHashAndPassword([]byte(*user.Password), []byte(params.Password))
-
- if err != nil {
- log.Debug("Failed to compare password: ", err)
- return res, fmt.Errorf(`bad user credentials`)
- }
-
- defaultRolesString, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyDefaultRoles)
- roles := []string{}
- if err != nil {
- log.Debug("Error getting default roles: ", err)
- defaultRolesString = ""
- } else {
- roles = strings.Split(defaultRolesString, ",")
- }
-
- currentRoles := strings.Split(user.Roles, ",")
- if len(params.Roles) > 0 {
- if !validators.IsValidRoles(params.Roles, currentRoles) {
- log.Debug("Invalid roles: ", params.Roles)
- return res, fmt.Errorf(`invalid roles`)
- }
-
- roles = params.Roles
- }
-
- disablePhoneVerification, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisablePhoneVerification)
- if err != nil {
- log.Debug("Error getting disable phone verification: ", err)
- }
- if disablePhoneVerification {
- now := time.Now().Unix()
- user.PhoneNumberVerifiedAt = &now
- }
- isSMSServiceEnabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyIsSMSServiceEnabled)
- if err != nil || !isSMSServiceEnabled {
- log.Debug("SMS service not enabled: ", err)
- }
- if disablePhoneVerification {
- now := time.Now().Unix()
- user.PhoneNumberVerifiedAt = &now
- }
- isMFADisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableMultiFactorAuthentication)
- if err != nil || !isMFADisabled {
- log.Debug("MFA service not enabled: ", err)
- }
- if !disablePhoneVerification && isSMSServiceEnabled && !isMFADisabled {
- duration, _ := time.ParseDuration("10m")
- smsCode := utils.GenerateOTP()
-
- smsBody := strings.Builder{}
- smsBody.WriteString("Your verification code is: ")
- smsBody.WriteString(smsCode)
- expires := time.Now().Add(duration).Unix()
- _, err := db.Provider.UpsertOTP(ctx, &models.OTP{
- PhoneNumber: params.PhoneNumber,
- Otp: smsCode,
- ExpiresAt: expires,
- })
- if err != nil {
- log.Debug("error while upserting OTP: ", err.Error())
- return nil, err
- }
-
- mfaSession := uuid.NewString()
- err = memorystore.Provider.SetMfaSession(user.ID, mfaSession, expires)
- if err != nil {
- log.Debug("Failed to add mfasession: ", err)
- return nil, err
- }
- cookie.SetMfaSession(gc, mfaSession)
-
- go func() {
- utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, constants.AuthRecipeMethodMobileBasicAuth, user)
- smsproviders.SendSMS(params.PhoneNumber, smsBody.String())
- }()
- return &model.AuthResponse{
- Message: "Please check the OTP",
- ShouldShowMobileOtpScreen: refs.NewBoolRef(true),
- }, nil
- }
-
- scope := []string{"openid", "email", "profile"}
- if params.Scope != nil && len(scope) > 0 {
- scope = params.Scope
- }
-
- code := ""
- codeChallenge := ""
- nonce := ""
- if params.State != nil {
- // Get state from store
- authorizeState, _ := memorystore.Provider.GetState(refs.StringValue(params.State))
- if authorizeState != "" {
- authorizeStateSplit := strings.Split(authorizeState, "@@")
- if len(authorizeStateSplit) > 1 {
- code = authorizeStateSplit[0]
- codeChallenge = authorizeStateSplit[1]
- } else {
- nonce = authorizeState
- }
- go memorystore.Provider.RemoveState(refs.StringValue(params.State))
- }
- }
-
- if nonce == "" {
- nonce = uuid.New().String()
- }
-
- authToken, err := token.CreateAuthToken(gc, user, roles, scope, constants.AuthRecipeMethodMobileBasicAuth, nonce, code)
- if err != nil {
- log.Debug("Failed to create auth token", err)
- return res, err
- }
-
- // TODO add to other login options as well
- // Code challenge could be optional if PKCE flow is not used
- if code != "" {
- if err := memorystore.Provider.SetState(code, codeChallenge+"@@"+authToken.FingerPrintHash); err != nil {
- log.Debug("SetState failed: ", err)
- return res, err
- }
- }
-
- expiresIn := authToken.AccessToken.ExpiresAt - time.Now().Unix()
- if expiresIn <= 0 {
- expiresIn = 1
- }
-
- res = &model.AuthResponse{
- Message: `Logged in successfully`,
- AccessToken: &authToken.AccessToken.Token,
- IDToken: &authToken.IDToken.Token,
- ExpiresIn: &expiresIn,
- User: user.AsAPIUser(),
- }
-
- cookie.SetSession(gc, authToken.FingerPrintHash)
- sessionStoreKey := constants.AuthRecipeMethodMobileBasicAuth + ":" + user.ID
- memorystore.Provider.SetUserSession(sessionStoreKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash, authToken.SessionTokenExpiresAt)
- memorystore.Provider.SetUserSession(sessionStoreKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token, authToken.AccessToken.ExpiresAt)
-
- if authToken.RefreshToken != nil {
- res.RefreshToken = &authToken.RefreshToken.Token
- memorystore.Provider.SetUserSession(sessionStoreKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token, authToken.RefreshToken.ExpiresAt)
- }
-
- go func() {
- utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, constants.AuthRecipeMethodMobileBasicAuth, user)
- db.Provider.AddSession(ctx, &models.Session{
- UserID: user.ID,
- UserAgent: utils.GetUserAgent(gc.Request),
- IP: utils.GetIP(gc.Request),
- })
- }()
-
- return res, nil
-}
diff --git a/server/resolvers/mobile_signup.go b/server/resolvers/mobile_signup.go
deleted file mode 100644
index 45594cacd..000000000
--- a/server/resolvers/mobile_signup.go
+++ /dev/null
@@ -1,312 +0,0 @@
-package resolvers
-
-import (
- "context"
- "fmt"
- "strings"
- "time"
-
- "github.com/google/uuid"
- log "github.com/sirupsen/logrus"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/cookie"
- "github.com/authorizerdev/authorizer/server/crypto"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/db/models"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/refs"
- "github.com/authorizerdev/authorizer/server/smsproviders"
- "github.com/authorizerdev/authorizer/server/token"
- "github.com/authorizerdev/authorizer/server/utils"
- "github.com/authorizerdev/authorizer/server/validators"
-)
-
-// MobileSignupResolver is a resolver for mobile_basic_auth_signup mutation
-func MobileSignupResolver(ctx context.Context, params *model.MobileSignUpInput) (*model.AuthResponse, error) {
- var res *model.AuthResponse
-
- gc, err := utils.GinContextFromContext(ctx)
- if err != nil {
- log.Debug("Failed to get GinContext: ", err)
- return res, err
- }
-
- isSignupDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableSignUp)
- if err != nil {
- log.Debug("Error getting signup disabled: ", err)
- isSignupDisabled = true
- }
- if isSignupDisabled {
- log.Debug("Signup is disabled")
- return res, fmt.Errorf(`signup is disabled for this instance`)
- }
-
- isBasicAuthDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableMobileBasicAuthentication)
- if err != nil {
- log.Debug("Error getting basic auth disabled: ", err)
- isBasicAuthDisabled = true
- }
-
- if isBasicAuthDisabled {
- log.Debug("Mobile based Basic authentication is disabled")
- return res, fmt.Errorf(`phone number based basic authentication is disabled for this instance`)
- }
-
- if params.ConfirmPassword != params.Password {
- log.Debug("Passwords do not match")
- return res, fmt.Errorf(`password and confirm password does not match`)
- }
-
- if err := validators.IsValidPassword(params.Password); err != nil {
- log.Debug("Invalid password")
- return res, err
- }
-
- mobile := strings.TrimSpace(params.PhoneNumber)
- if mobile == "" || len(mobile) < 10 {
- log.Debug("Invalid phone number")
- return res, fmt.Errorf("invalid phone number")
- }
-
- emailInput := strings.ToLower(strings.TrimSpace(refs.StringValue(params.Email)))
-
- // if email is null set random dummy email for db constraint
-
- if emailInput != "" && !validators.IsValidEmail(emailInput) {
- log.Debug("Invalid email: ", emailInput)
- return res, fmt.Errorf(`invalid email address`)
- }
-
- if emailInput == "" {
- emailInput = mobile + "@authorizer.dev"
- }
-
- log := log.WithFields(log.Fields{
- "email": emailInput,
- "phone_number": mobile,
- })
- // find user with email
- existingUser, err := db.Provider.GetUserByPhoneNumber(ctx, mobile)
- if err != nil {
- log.Debug("Failed to get user by email: ", err)
- }
- if existingUser != nil {
- if existingUser.PhoneNumberVerifiedAt != nil {
- // email is verified
- log.Debug("Phone number is already verified and signed up.")
- return res, fmt.Errorf(`%s has already signed up`, mobile)
- } else if existingUser.ID != "" && existingUser.PhoneNumberVerifiedAt == nil {
- log.Debug("Phone number is already signed up. Verification pending...")
- return res, fmt.Errorf("%s has already signed up. please complete the phone number verification process or reset the password", mobile)
- }
- }
-
- inputRoles := []string{}
- if len(params.Roles) > 0 {
- // check if roles exists
- rolesString, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyRoles)
- roles := []string{}
- if err != nil {
- log.Debug("Error getting roles: ", err)
- return res, err
- } else {
- roles = strings.Split(rolesString, ",")
- }
- if !validators.IsValidRoles(params.Roles, roles) {
- log.Debug("Invalid roles: ", params.Roles)
- return res, fmt.Errorf(`invalid roles`)
- } else {
- inputRoles = params.Roles
- }
- } else {
- inputRolesString, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyDefaultRoles)
- if err != nil {
- log.Debug("Error getting default roles: ", err)
- return res, err
- } else {
- inputRoles = strings.Split(inputRolesString, ",")
- }
- }
-
- user := &models.User{
- Email: &emailInput,
- PhoneNumber: &mobile,
- }
-
- user.Roles = strings.Join(inputRoles, ",")
-
- password, _ := crypto.EncryptPassword(params.Password)
- user.Password = &password
-
- if params.GivenName != nil {
- user.GivenName = params.GivenName
- }
-
- if params.FamilyName != nil {
- user.FamilyName = params.FamilyName
- }
-
- if params.MiddleName != nil {
- user.MiddleName = params.MiddleName
- }
-
- if params.Nickname != nil {
- user.Nickname = params.Nickname
- }
-
- if params.Gender != nil {
- user.Gender = params.Gender
- }
-
- if params.Birthdate != nil {
- user.Birthdate = params.Birthdate
- }
-
- if params.Picture != nil {
- user.Picture = params.Picture
- }
-
- if params.IsMultiFactorAuthEnabled != nil {
- user.IsMultiFactorAuthEnabled = params.IsMultiFactorAuthEnabled
- }
-
- isMFAEnforced, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyEnforceMultiFactorAuthentication)
- if err != nil {
- log.Debug("MFA service not enabled: ", err)
- isMFAEnforced = false
- }
-
- if isMFAEnforced {
- user.IsMultiFactorAuthEnabled = refs.NewBoolRef(true)
- }
-
- disablePhoneVerification, _ := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisablePhoneVerification)
- if disablePhoneVerification {
- now := time.Now().Unix()
- user.PhoneNumberVerifiedAt = &now
- }
- isSMSServiceEnabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyIsSMSServiceEnabled)
- if err != nil || !isSMSServiceEnabled {
- log.Debug("SMS service not enabled: ", err)
- }
-
- user.SignupMethods = constants.AuthRecipeMethodMobileBasicAuth
- user, err = db.Provider.AddUser(ctx, user)
-
- if err != nil {
- log.Debug("Failed to add user: ", err)
- return res, err
- }
- if !disablePhoneVerification && isSMSServiceEnabled {
- duration, _ := time.ParseDuration("10m")
- smsCode := utils.GenerateOTP()
-
- smsBody := strings.Builder{}
- smsBody.WriteString("Your verification code is: ")
- smsBody.WriteString(smsCode)
-
- // TODO: For those who enabled the webhook to call their sms vendor separately - sending the otp to their api
- if err != nil {
- log.Debug("error while upserting user: ", err.Error())
- return nil, err
- }
- _, err = db.Provider.UpsertOTP(ctx, &models.OTP{
- PhoneNumber: mobile,
- Otp: smsCode,
- ExpiresAt: time.Now().Add(duration).Unix(),
- })
- if err != nil {
- log.Debug("error while upserting OTP: ", err.Error())
- return nil, err
- }
- go func() {
- smsproviders.SendSMS(mobile, smsBody.String())
- utils.RegisterEvent(ctx, constants.UserCreatedWebhookEvent, constants.AuthRecipeMethodBasicAuth, user)
- }()
- return &model.AuthResponse{
- Message: "Please check the OTP in your inbox",
- ShouldShowMobileOtpScreen: refs.NewBoolRef(true),
- }, nil
- }
-
- roles := strings.Split(user.Roles, ",")
- userToReturn := user.AsAPIUser()
-
- scope := []string{"openid", "email", "profile"}
- if params.Scope != nil && len(scope) > 0 {
- scope = params.Scope
- }
-
- code := ""
- codeChallenge := ""
- nonce := ""
- if params.State != nil {
- // Get state from store
- authorizeState, _ := memorystore.Provider.GetState(refs.StringValue(params.State))
- if authorizeState != "" {
- authorizeStateSplit := strings.Split(authorizeState, "@@")
- if len(authorizeStateSplit) > 1 {
- code = authorizeStateSplit[0]
- codeChallenge = authorizeStateSplit[1]
- } else {
- nonce = authorizeState
- }
- go memorystore.Provider.RemoveState(refs.StringValue(params.State))
- }
- }
-
- if nonce == "" {
- nonce = uuid.New().String()
- }
-
- authToken, err := token.CreateAuthToken(gc, user, roles, scope, constants.AuthRecipeMethodMobileBasicAuth, nonce, code)
- if err != nil {
- log.Debug("Failed to create auth token: ", err)
- return res, err
- }
-
- // Code challenge could be optional if PKCE flow is not used
- if code != "" {
- if err := memorystore.Provider.SetState(code, codeChallenge+"@@"+authToken.FingerPrintHash); err != nil {
- log.Debug("SetState failed: ", err)
- return res, err
- }
- }
-
- expiresIn := authToken.AccessToken.ExpiresAt - time.Now().Unix()
- if expiresIn <= 0 {
- expiresIn = 1
- }
-
- res = &model.AuthResponse{
- Message: `Signed up successfully.`,
- AccessToken: &authToken.AccessToken.Token,
- ExpiresIn: &expiresIn,
- User: userToReturn,
- }
-
- sessionKey := constants.AuthRecipeMethodMobileBasicAuth + ":" + user.ID
- cookie.SetSession(gc, authToken.FingerPrintHash)
- memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash, authToken.SessionTokenExpiresAt)
- memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token, authToken.AccessToken.ExpiresAt)
-
- if authToken.RefreshToken != nil {
- res.RefreshToken = &authToken.RefreshToken.Token
- memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token, authToken.RefreshToken.ExpiresAt)
- }
-
- go func() {
- utils.RegisterEvent(ctx, constants.UserSignUpWebhookEvent, constants.AuthRecipeMethodMobileBasicAuth, user)
- // User is also logged in with signup
- utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, constants.AuthRecipeMethodMobileBasicAuth, user)
- db.Provider.AddSession(ctx, &models.Session{
- UserID: user.ID,
- UserAgent: utils.GetUserAgent(gc.Request),
- IP: utils.GetIP(gc.Request),
- })
- }()
-
- return res, nil
-}
diff --git a/server/resolvers/profile.go b/server/resolvers/profile.go
deleted file mode 100644
index df7092ce8..000000000
--- a/server/resolvers/profile.go
+++ /dev/null
@@ -1,38 +0,0 @@
-package resolvers
-
-import (
- "context"
-
- log "github.com/sirupsen/logrus"
-
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/token"
- "github.com/authorizerdev/authorizer/server/utils"
-)
-
-// ProfileResolver is a resolver for profile query
-func ProfileResolver(ctx context.Context) (*model.User, error) {
- var res *model.User
-
- gc, err := utils.GinContextFromContext(ctx)
- if err != nil {
- log.Debug("Failed to get GinContext: ", err)
- return res, err
- }
- tokenData, err := token.GetUserIDFromSessionOrAccessToken(gc)
- if err != nil {
- log.Debug("Failed GetUserIDFromSessionOrAccessToken: ", err)
- return res, err
- }
- log := log.WithFields(log.Fields{
- "user_id": tokenData.UserID,
- })
- user, err := db.Provider.GetUserByID(ctx, tokenData.UserID)
- if err != nil {
- log.Debug("Failed to get user: ", err)
- return res, err
- }
-
- return user.AsAPIUser(), nil
-}
diff --git a/server/resolvers/resend_otp.go b/server/resolvers/resend_otp.go
deleted file mode 100644
index 8b9ac842a..000000000
--- a/server/resolvers/resend_otp.go
+++ /dev/null
@@ -1,162 +0,0 @@
-package resolvers
-
-import (
- "context"
- "errors"
- "fmt"
- "strings"
- "time"
-
- "github.com/google/uuid"
- log "github.com/sirupsen/logrus"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/cookie"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/db/models"
- mailService "github.com/authorizerdev/authorizer/server/email"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/refs"
- "github.com/authorizerdev/authorizer/server/smsproviders"
- "github.com/authorizerdev/authorizer/server/utils"
-)
-
-// ResendOTPResolver is a resolver for resend otp mutation
-func ResendOTPResolver(ctx context.Context, params model.ResendOTPRequest) (*model.Response, error) {
- email := strings.ToLower(strings.Trim(refs.StringValue(params.Email), " "))
- phoneNumber := strings.Trim(refs.StringValue(params.PhoneNumber), " ")
- log := log.WithFields(log.Fields{
- "email": email,
- "phone_number": phoneNumber,
- })
- if email == "" && phoneNumber == "" {
- log.Debug("Email or phone number is required")
- return nil, errors.New("email or phone number is required")
- }
- gc, err := utils.GinContextFromContext(ctx)
- if err != nil {
- log.Debug("Failed to get GinContext: ", err)
- return nil, err
- }
- var user *models.User
- var isEmailServiceEnabled, isSMSServiceEnabled bool
- if email != "" {
- isEmailServiceEnabled, err = memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyIsEmailServiceEnabled)
- if err != nil || !isEmailServiceEnabled {
- log.Debug("Email service not enabled: ", err)
- return nil, errors.New("email service not enabled")
- }
- user, err = db.Provider.GetUserByEmail(ctx, email)
- if err != nil {
- log.Debug("Failed to get user by email: ", err)
- return nil, fmt.Errorf(`user with this email/phone not found`)
- }
- } else {
- isSMSServiceEnabled, err = memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyIsEmailServiceEnabled)
- if err != nil || !isSMSServiceEnabled {
- log.Debug("Email service not enabled: ", err)
- return nil, errors.New("email service not enabled")
- }
- user, err = db.Provider.GetUserByPhoneNumber(ctx, phoneNumber)
- if err != nil {
- log.Debug("Failed to get user by phone: ", err)
- return nil, fmt.Errorf(`user with this email/phone not found`)
- }
- }
- if user.RevokedTimestamp != nil {
- log.Debug("User access is revoked")
- return nil, fmt.Errorf(`user access has been revoked`)
- }
-
- if !refs.BoolValue(user.IsMultiFactorAuthEnabled) && user.EmailVerifiedAt != nil && user.PhoneNumberVerifiedAt != nil {
- log.Debug("User multi factor authentication is not enabled")
- return nil, fmt.Errorf(`multi factor authentication not enabled`)
- }
-
- isMFADisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableMultiFactorAuthentication)
- if err != nil || isMFADisabled {
- log.Debug("MFA service not enabled: ", err)
- return nil, errors.New("multi factor authentication is disabled for this instance")
- }
-
- // get otp by email or phone number
- var otpData *models.OTP
- if email != "" {
- otpData, err = db.Provider.GetOTPByEmail(ctx, refs.StringValue(params.Email))
- } else {
- otpData, err = db.Provider.GetOTPByPhoneNumber(ctx, refs.StringValue(params.PhoneNumber))
- }
- if err != nil {
- log.Debug("Failed to get otp for given email: ", err)
- return nil, err
- }
- if otpData == nil {
- log.Debug("No otp found for given email: ", params.Email)
- return &model.Response{
- Message: "Failed to get for given email",
- }, errors.New("failed to get otp for given email")
- }
- // If multi factor authentication is enabled and we need to generate OTP for mail / sms based MFA
- generateOTP := func(expiresAt int64) (*models.OTP, error) {
- otp := utils.GenerateOTP()
- otpData, err := db.Provider.UpsertOTP(ctx, &models.OTP{
- Email: refs.StringValue(user.Email),
- PhoneNumber: refs.StringValue(user.PhoneNumber),
- Otp: otp,
- ExpiresAt: expiresAt,
- })
- if err != nil {
- log.Debug("Failed to add otp: ", err)
- return nil, err
- }
- return otpData, nil
- }
- setOTPMFaSession := func(expiresAt int64) error {
- mfaSession := uuid.NewString()
- err = memorystore.Provider.SetMfaSession(user.ID, mfaSession, expiresAt)
- if err != nil {
- log.Debug("Failed to add mfasession: ", err)
- return err
- }
- cookie.SetMfaSession(gc, mfaSession)
- return nil
- }
- expiresAt := time.Now().Add(1 * time.Minute).Unix()
- otpData, err = generateOTP(expiresAt)
- if err != nil {
- log.Debug("Failed to generate otp: ", err)
- return nil, err
- }
- if err := setOTPMFaSession(expiresAt); err != nil {
- log.Debug("Failed to set mfa session: ", err)
- return nil, err
- }
- if email != "" {
- go func() {
- // exec it as go routine so that we can reduce the api latency
- if err := mailService.SendEmail([]string{email}, constants.VerificationTypeOTP, map[string]interface{}{
- "user": user.ToMap(),
- "organization": utils.GetOrganization(),
- "otp": otpData.Otp,
- }); err != nil {
- log.Debug("Failed to send otp email: ", err)
- }
- utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, constants.AuthRecipeMethodBasicAuth, user)
- }()
- } else {
- go func() {
- smsBody := strings.Builder{}
- smsBody.WriteString("Your verification code is: ")
- smsBody.WriteString(otpData.Otp)
- utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, constants.AuthRecipeMethodMobileBasicAuth, user)
- if err := smsproviders.SendSMS(phoneNumber, smsBody.String()); err != nil {
- log.Debug("Failed to send sms: ", err)
- }
- }()
- }
- log.Info("OTP has been resent")
- return &model.Response{
- Message: `OTP has been sent. Please check your inbox`,
- }, nil
-}
diff --git a/server/resolvers/resend_verify_email.go b/server/resolvers/resend_verify_email.go
deleted file mode 100644
index b5a789f56..000000000
--- a/server/resolvers/resend_verify_email.go
+++ /dev/null
@@ -1,94 +0,0 @@
-package resolvers
-
-import (
- "context"
- "fmt"
- "strings"
- "time"
-
- log "github.com/sirupsen/logrus"
-
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/db/models"
- "github.com/authorizerdev/authorizer/server/email"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/parsers"
- "github.com/authorizerdev/authorizer/server/token"
- "github.com/authorizerdev/authorizer/server/utils"
- "github.com/authorizerdev/authorizer/server/validators"
-)
-
-// ResendVerifyEmailResolver is a resolver for resend verify email mutation
-func ResendVerifyEmailResolver(ctx context.Context, params model.ResendVerifyEmailInput) (*model.Response, error) {
- var res *model.Response
-
- gc, err := utils.GinContextFromContext(ctx)
- if err != nil {
- log.Debug("Failed to get GinContext: ", err)
- return res, err
- }
- params.Email = strings.ToLower(params.Email)
-
- if !validators.IsValidEmail(params.Email) {
- log.Debug("Invalid email: ", params.Email)
- return res, fmt.Errorf("invalid email")
- }
-
- if !validators.IsValidVerificationIdentifier(params.Identifier) {
- log.Debug("Invalid verification identifier: ", params.Identifier)
- return res, fmt.Errorf("invalid identifier")
- }
-
- user, err := db.Provider.GetUserByEmail(ctx, params.Email)
- if err != nil {
- return res, fmt.Errorf("invalid user")
- }
-
- verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, params.Email, params.Identifier)
- if err != nil {
- log.Debug("Failed to get verification request: ", err)
- return res, fmt.Errorf(`verification request not found`)
- }
-
- // delete current verification and create new one
- err = db.Provider.DeleteVerificationRequest(ctx, verificationRequest)
- if err != nil {
- log.Debug("Failed to delete verification request: ", err)
- }
-
- hostname := parsers.GetHost(gc)
- _, nonceHash, err := utils.GenerateNonce()
- if err != nil {
- log.Debug("Failed to generate nonce: ", err)
- return res, err
- }
-
- verificationToken, err := token.CreateVerificationToken(params.Email, params.Identifier, hostname, nonceHash, verificationRequest.RedirectURI)
- if err != nil {
- log.Debug("Failed to create verification token: ", err)
- }
- _, err = db.Provider.AddVerificationRequest(ctx, &models.VerificationRequest{
- Token: verificationToken,
- Identifier: params.Identifier,
- ExpiresAt: time.Now().Add(time.Minute * 30).Unix(),
- Email: params.Email,
- Nonce: nonceHash,
- RedirectURI: verificationRequest.RedirectURI,
- })
- if err != nil {
- log.Debug("Failed to add verification request: ", err)
- }
-
- // exec it as go routine so that we can reduce the api latency
- go email.SendEmail([]string{params.Email}, params.Identifier, map[string]interface{}{
- "user": user.ToMap(),
- "organization": utils.GetOrganization(),
- "verification_url": utils.GetEmailVerificationURL(verificationToken, hostname, verificationRequest.RedirectURI),
- })
-
- res = &model.Response{
- Message: `Verification email has been sent. Please check your inbox`,
- }
-
- return res, nil
-}
diff --git a/server/resolvers/reset_password.go b/server/resolvers/reset_password.go
deleted file mode 100644
index 2efcd67fa..000000000
--- a/server/resolvers/reset_password.go
+++ /dev/null
@@ -1,185 +0,0 @@
-package resolvers
-
-import (
- "context"
- "fmt"
- "strings"
- "time"
-
- log "github.com/sirupsen/logrus"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/cookie"
- "github.com/authorizerdev/authorizer/server/crypto"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/db/models"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/parsers"
- "github.com/authorizerdev/authorizer/server/refs"
- "github.com/authorizerdev/authorizer/server/token"
- "github.com/authorizerdev/authorizer/server/utils"
- "github.com/authorizerdev/authorizer/server/validators"
-)
-
-// ResetPasswordResolver is a resolver for reset password mutation
-func ResetPasswordResolver(ctx context.Context, params model.ResetPasswordInput) (*model.Response, error) {
- var res *model.Response
-
- gc, err := utils.GinContextFromContext(ctx)
- if err != nil {
- log.Debug("Failed to get GinContext: ", err)
- return res, err
- }
- verifyingToken := refs.StringValue(params.Token)
- otp := refs.StringValue(params.Otp)
- if verifyingToken == "" && otp == "" {
- log.Debug("Token or OTP is required")
- return res, fmt.Errorf(`token or otp is required`)
- }
- isTokenVerification := verifyingToken != ""
- isOtpVerification := otp != ""
- if isOtpVerification && refs.StringValue(params.PhoneNumber) == "" {
- log.Debug("Phone number is required")
- return res, fmt.Errorf(`phone number is required`)
- }
- isBasicAuthDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableBasicAuthentication)
- if err != nil {
- log.Debug("Error getting basic auth disabled: ", err)
- isBasicAuthDisabled = true
- }
- isMobileBasicAuthDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableMobileBasicAuthentication)
- if err != nil {
- log.Debug("Error getting mobile basic auth disabled: ", err)
- isBasicAuthDisabled = true
- }
- if isTokenVerification && isBasicAuthDisabled {
- log.Debug("Basic authentication is disabled")
- return res, fmt.Errorf(`basic authentication is disabled for this instance`)
- }
- if isOtpVerification && isMobileBasicAuthDisabled {
- log.Debug("Mobile basic authentication is disabled")
- return res, fmt.Errorf(`mobile basic authentication is disabled for this instance`)
- }
- email := ""
- phoneNumber := refs.StringValue(params.PhoneNumber)
- var user *models.User
- var verificationRequest *models.VerificationRequest
- var otpRequest *models.OTP
- if isTokenVerification {
- verificationRequest, err = db.Provider.GetVerificationRequestByToken(ctx, verifyingToken)
- if err != nil {
- log.Debug("Failed to get verification request: ", err)
- return res, fmt.Errorf(`invalid token`)
- }
- // verify if token exists in db
- hostname := parsers.GetHost(gc)
- claim, err := token.ParseJWTToken(verifyingToken)
- if err != nil {
- log.Debug("Failed to parse token: ", err)
- return res, fmt.Errorf(`invalid token`)
- }
-
- if ok, err := token.ValidateJWTClaims(claim, hostname, verificationRequest.Nonce, verificationRequest.Email); !ok || err != nil {
- log.Debug("Failed to validate jwt claims: ", err)
- return res, fmt.Errorf(`invalid token`)
- }
- email = claim["sub"].(string)
- user, err = db.Provider.GetUserByEmail(ctx, email)
- if err != nil {
- log.Debug("Failed to get user: ", err)
- return res, err
- }
- }
- if isOtpVerification {
- mfaSession, err := cookie.GetMfaSession(gc)
- if err != nil {
- log.Debug("Failed to get otp request by email: ", err)
- return res, fmt.Errorf(`invalid session: %s`, err.Error())
- }
- // Get user by phone number
- user, err = db.Provider.GetUserByPhoneNumber(ctx, phoneNumber)
- if err != nil {
- log.Debug("Failed to get user by phone number: ", err)
- return res, fmt.Errorf(`user not found`)
- }
- if _, err := memorystore.Provider.GetMfaSession(user.ID, mfaSession); err != nil {
- log.Debug("Failed to get mfa session: ", err)
- return res, fmt.Errorf(`invalid session: %s`, err.Error())
- }
- otpRequest, err = db.Provider.GetOTPByPhoneNumber(ctx, phoneNumber)
- if err != nil {
- log.Debug("Failed to get otp request by phone number: ", err)
- return res, fmt.Errorf(`invalid otp`)
- }
- if otpRequest.Otp != otp {
- log.Debug("Failed to verify otp request: Incorrect value")
- return res, fmt.Errorf(`invalid otp`)
- }
- }
- if params.Password != params.ConfirmPassword {
- log.Debug("Passwords do not match")
- return res, fmt.Errorf(`passwords don't match`)
- }
- if err := validators.IsValidPassword(params.Password); err != nil {
- log.Debug("Invalid password")
- return res, err
- }
- log := log.WithFields(log.Fields{
- "email": email,
- "phone": phoneNumber,
- })
- password, _ := crypto.EncryptPassword(params.Password)
- user.Password = &password
- signupMethod := user.SignupMethods
- if !strings.Contains(signupMethod, constants.AuthRecipeMethodBasicAuth) && isTokenVerification {
- signupMethod = signupMethod + "," + constants.AuthRecipeMethodBasicAuth
- // helpful if user has not signed up with basic auth
- if user.EmailVerifiedAt == nil {
- now := time.Now().Unix()
- user.EmailVerifiedAt = &now
- }
- }
- if !strings.Contains(signupMethod, constants.AuthRecipeMethodMobileOTP) && isOtpVerification {
- signupMethod = signupMethod + "," + constants.AuthRecipeMethodMobileOTP
- // helpful if user has not signed up with basic auth
- if user.PhoneNumberVerifiedAt == nil {
- now := time.Now().Unix()
- user.PhoneNumberVerifiedAt = &now
- }
- }
- user.SignupMethods = signupMethod
- isMFAEnforced, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyEnforceMultiFactorAuthentication)
- if err != nil {
- log.Debug("MFA service not enabled: ", err)
- isMFAEnforced = false
- }
- if isMFAEnforced {
- user.IsMultiFactorAuthEnabled = refs.NewBoolRef(true)
- }
- _, err = db.Provider.UpdateUser(ctx, user)
- if err != nil {
- log.Debug("Failed to update user: ", err)
- return res, err
- }
- if isTokenVerification {
- // delete from verification table
- err = db.Provider.DeleteVerificationRequest(ctx, verificationRequest)
- if err != nil {
- log.Debug("Failed to delete verification request: ", err)
- return res, err
- }
- }
- if isOtpVerification {
- // delete from otp table
- err = db.Provider.DeleteOTP(ctx, otpRequest)
- if err != nil {
- log.Debug("Failed to delete otp request: ", err)
- return res, err
- }
- }
- res = &model.Response{
- Message: `Password updated successfully.`,
- }
- return res, nil
-}
diff --git a/server/resolvers/revoke.go b/server/resolvers/revoke.go
deleted file mode 100644
index 694e36bee..000000000
--- a/server/resolvers/revoke.go
+++ /dev/null
@@ -1,16 +0,0 @@
-package resolvers
-
-import (
- "context"
-
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
-)
-
-// RevokeResolver resolver to revoke refresh token
-func RevokeResolver(ctx context.Context, params model.OAuthRevokeInput) (*model.Response, error) {
- memorystore.Provider.RemoveState(params.RefreshToken)
- return &model.Response{
- Message: "Token revoked",
- }, nil
-}
diff --git a/server/resolvers/revoke_access.go b/server/resolvers/revoke_access.go
deleted file mode 100644
index 12623975a..000000000
--- a/server/resolvers/revoke_access.go
+++ /dev/null
@@ -1,61 +0,0 @@
-package resolvers
-
-import (
- "context"
- "fmt"
- "time"
-
- log "github.com/sirupsen/logrus"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/token"
- "github.com/authorizerdev/authorizer/server/utils"
-)
-
-// RevokeAccessResolver is a resolver for revoking user access
-func RevokeAccessResolver(ctx context.Context, params model.UpdateAccessInput) (*model.Response, error) {
- var res *model.Response
-
- gc, err := utils.GinContextFromContext(ctx)
- if err != nil {
- log.Debug("Failed to get GinContext: ", err)
- return res, err
- }
-
- if !token.IsSuperAdmin(gc) {
- log.Debug("Not logged in as super admin")
- return res, fmt.Errorf("unauthorized")
- }
-
- log := log.WithFields(log.Fields{
- "user_id": params.UserID,
- })
- user, err := db.Provider.GetUserByID(ctx, params.UserID)
- if err != nil {
- log.Debug("Failed to get user by ID: ", err)
- return res, err
- }
-
- now := time.Now().Unix()
- user.RevokedTimestamp = &now
-
- user, err = db.Provider.UpdateUser(ctx, user)
- if err != nil {
- log.Debug("Failed to update user: ", err)
- return res, err
- }
-
- go func() {
- memorystore.Provider.DeleteAllUserSessions(user.ID)
- utils.RegisterEvent(ctx, constants.UserAccessRevokedWebhookEvent, "", user)
- }()
-
- res = &model.Response{
- Message: `user access revoked successfully`,
- }
-
- return res, nil
-}
diff --git a/server/resolvers/session.go b/server/resolvers/session.go
deleted file mode 100644
index 964d1b506..000000000
--- a/server/resolvers/session.go
+++ /dev/null
@@ -1,110 +0,0 @@
-package resolvers
-
-import (
- "context"
- "errors"
- "fmt"
- "time"
-
- "github.com/google/uuid"
- log "github.com/sirupsen/logrus"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/cookie"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/token"
- "github.com/authorizerdev/authorizer/server/utils"
-)
-
-// SessionResolver is a resolver for session query
-// TODO allow validating with code and code verifier instead of cookie (PKCE flow)
-func SessionResolver(ctx context.Context, params *model.SessionQueryInput) (*model.AuthResponse, error) {
- var res *model.AuthResponse
-
- gc, err := utils.GinContextFromContext(ctx)
- if err != nil {
- log.Debug("Failed to get GinContext: ", err)
- return res, err
- }
-
- sessionToken, err := cookie.GetSession(gc)
- if err != nil {
- log.Debug("Failed to get session token: ", err)
- return res, errors.New("unauthorized")
- }
-
- // get session from cookie
- claims, err := token.ValidateBrowserSession(gc, sessionToken)
- if err != nil {
- log.Debug("Failed to validate session token: ", err)
- return res, errors.New("unauthorized")
- }
- userID := claims.Subject
-
- log := log.WithFields(log.Fields{
- "user_id": userID,
- })
-
- user, err := db.Provider.GetUserByID(ctx, userID)
- if err != nil {
- return res, err
- }
-
- // refresh token has "roles" as claim
- claimRoleInterface := claims.Roles
- claimRoles := []string{}
- claimRoles = append(claimRoles, claimRoleInterface...)
-
- if params != nil && params.Roles != nil && len(params.Roles) > 0 {
- for _, v := range params.Roles {
- if !utils.StringSliceContains(claimRoles, v) {
- log.Debug("User does not have required role: ", claimRoles, v)
- return res, fmt.Errorf(`unauthorized`)
- }
- }
- }
-
- scope := []string{"openid", "email", "profile"}
- if params != nil && params.Scope != nil && len(scope) > 0 {
- scope = params.Scope
- }
-
- nonce := uuid.New().String()
- authToken, err := token.CreateAuthToken(gc, user, claimRoles, scope, claims.LoginMethod, nonce, "")
- if err != nil {
- log.Debug("Failed to create auth token: ", err)
- return res, err
- }
-
- // rollover the session for security
- sessionKey := userID
- if claims.LoginMethod != "" {
- sessionKey = claims.LoginMethod + ":" + userID
- }
- go memorystore.Provider.DeleteUserSession(sessionKey, claims.Nonce)
-
- expiresIn := authToken.AccessToken.ExpiresAt - time.Now().Unix()
- if expiresIn <= 0 {
- expiresIn = 1
- }
-
- res = &model.AuthResponse{
- Message: `Session token refreshed`,
- AccessToken: &authToken.AccessToken.Token,
- ExpiresIn: &expiresIn,
- IDToken: &authToken.IDToken.Token,
- User: user.AsAPIUser(),
- }
-
- cookie.SetSession(gc, authToken.FingerPrintHash)
- memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash, authToken.SessionTokenExpiresAt)
- memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token, authToken.AccessToken.ExpiresAt)
-
- if authToken.RefreshToken != nil {
- res.RefreshToken = &authToken.RefreshToken.Token
- memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token, authToken.RefreshToken.ExpiresAt)
- }
- return res, nil
-}
diff --git a/server/resolvers/signup.go b/server/resolvers/signup.go
deleted file mode 100644
index a42d24246..000000000
--- a/server/resolvers/signup.go
+++ /dev/null
@@ -1,403 +0,0 @@
-package resolvers
-
-import (
- "context"
- "encoding/json"
- "errors"
- "fmt"
- "strings"
- "time"
-
- "github.com/google/uuid"
- log "github.com/sirupsen/logrus"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/cookie"
- "github.com/authorizerdev/authorizer/server/crypto"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/db/models"
- emailService "github.com/authorizerdev/authorizer/server/email"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/parsers"
- "github.com/authorizerdev/authorizer/server/refs"
- "github.com/authorizerdev/authorizer/server/smsproviders"
- "github.com/authorizerdev/authorizer/server/token"
- "github.com/authorizerdev/authorizer/server/utils"
- "github.com/authorizerdev/authorizer/server/validators"
-)
-
-// SignupResolver is a resolver for signup mutation
-func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthResponse, error) {
- var res *model.AuthResponse
-
- gc, err := utils.GinContextFromContext(ctx)
- if err != nil {
- log.Debug("Failed to get GinContext: ", err)
- return res, err
- }
-
- isSignupDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableSignUp)
- if err != nil {
- log.Debug("Error getting signup disabled: ", err)
- isSignupDisabled = true
- }
- if isSignupDisabled {
- log.Debug("Signup is disabled")
- return res, fmt.Errorf(`signup is disabled for this instance`)
- }
-
- isBasicAuthDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableBasicAuthentication)
- if err != nil {
- log.Debug("Error getting basic auth disabled: ", err)
- isBasicAuthDisabled = true
- }
- isMobileBasicAuthDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableMobileBasicAuthentication)
- if err != nil {
- log.Debug("Error getting mobile basic auth disabled: ", err)
- isMobileBasicAuthDisabled = true
- }
- if params.ConfirmPassword != params.Password {
- log.Debug("Passwords do not match")
- return res, fmt.Errorf(`password and confirm password does not match`)
- }
- if err := validators.IsValidPassword(params.Password); err != nil {
- log.Debug("Invalid password")
- return res, err
- }
- email := strings.TrimSpace(refs.StringValue(params.Email))
- phoneNumber := strings.TrimSpace(refs.StringValue(params.PhoneNumber))
- if email == "" && phoneNumber == "" {
- log.Debug("Email or phone number is required")
- return res, fmt.Errorf(`email or phone number is required`)
- }
- isEmailSignup := email != ""
- isMobileSignup := phoneNumber != ""
- if isBasicAuthDisabled && isEmailSignup {
- log.Debug("Basic authentication is disabled")
- return res, fmt.Errorf(`basic authentication is disabled for this instance`)
- }
- if isMobileBasicAuthDisabled && isMobileSignup {
- log.Debug("Mobile basic authentication is disabled")
- return res, fmt.Errorf(`mobile basic authentication is disabled for this instance`)
- }
- if isEmailSignup && !validators.IsValidEmail(email) {
- log.Debug("Invalid email: ", params.Email)
- return res, fmt.Errorf(`invalid email address`)
- }
- if isMobileSignup && (phoneNumber == "" || len(phoneNumber) < 10) {
- log.Debug("Invalid phone number: ", phoneNumber)
- return res, fmt.Errorf(`invalid phone number`)
- }
- log := log.WithFields(log.Fields{
- "email": email,
- "phone_number": phoneNumber,
- })
- // find user with email / phone number
- if isEmailSignup {
- existingUser, err := db.Provider.GetUserByEmail(ctx, email)
- if err != nil {
- log.Debug("Failed to get user by email: ", err)
- }
- if existingUser != nil {
- if existingUser.EmailVerifiedAt != nil {
- // email is verified
- log.Debug("Email is already verified and signed up.")
- return res, fmt.Errorf(`%s has already signed up`, email)
- } else if existingUser.ID != "" && existingUser.EmailVerifiedAt == nil {
- log.Debug("Email is already signed up. Verification pending...")
- return res, fmt.Errorf("%s has already signed up. please complete the email verification process or reset the password", email)
- }
- }
- } else {
- existingUser, err := db.Provider.GetUserByPhoneNumber(ctx, phoneNumber)
- if err != nil {
- log.Debug("Failed to get user by phone number: ", err)
- }
- if existingUser != nil {
- if existingUser.PhoneNumberVerifiedAt != nil {
- // email is verified
- log.Debug("Phone number is already verified and signed up.")
- return res, fmt.Errorf(`%s has already signed up`, phoneNumber)
- } else if existingUser.ID != "" && existingUser.PhoneNumberVerifiedAt == nil {
- log.Debug("Phone number is already signed up. Verification pending...")
- return res, fmt.Errorf("%s has already signed up. please complete the phone number verification process or reset the password", phoneNumber)
- }
- }
- }
-
- inputRoles := []string{}
- if len(params.Roles) > 0 {
- // check if roles exists
- rolesString, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyRoles)
- roles := []string{}
- if err != nil {
- log.Debug("Error getting roles: ", err)
- return res, err
- } else {
- roles = strings.Split(rolesString, ",")
- }
- if !validators.IsValidRoles(params.Roles, roles) {
- log.Debug("Invalid roles: ", params.Roles)
- return res, fmt.Errorf(`invalid roles`)
- } else {
- inputRoles = params.Roles
- }
- } else {
- inputRolesString, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyDefaultRoles)
- if err != nil {
- log.Debug("Error getting default roles: ", err)
- return res, err
- } else {
- inputRoles = strings.Split(inputRolesString, ",")
- }
- }
- user := &models.User{}
- user.Roles = strings.Join(inputRoles, ",")
- password, _ := crypto.EncryptPassword(params.Password)
- user.Password = &password
- if email != "" {
- user.SignupMethods = constants.AuthRecipeMethodBasicAuth
- user.Email = &email
- }
- if params.GivenName != nil {
- user.GivenName = params.GivenName
- }
-
- if params.FamilyName != nil {
- user.FamilyName = params.FamilyName
- }
-
- if params.MiddleName != nil {
- user.MiddleName = params.MiddleName
- }
-
- if params.Nickname != nil {
- user.Nickname = params.Nickname
- }
-
- if params.Gender != nil {
- user.Gender = params.Gender
- }
-
- if params.Birthdate != nil {
- user.Birthdate = params.Birthdate
- }
-
- if phoneNumber != "" {
- user.SignupMethods = constants.AuthRecipeMethodMobileBasicAuth
- user.PhoneNumber = refs.NewStringRef(phoneNumber)
- }
-
- if params.Picture != nil {
- user.Picture = params.Picture
- }
-
- if params.IsMultiFactorAuthEnabled != nil {
- user.IsMultiFactorAuthEnabled = params.IsMultiFactorAuthEnabled
- }
-
- isMFAEnforced, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyEnforceMultiFactorAuthentication)
- if err != nil {
- log.Debug("MFA service not enabled: ", err)
- isMFAEnforced = false
- }
-
- if isMFAEnforced {
- user.IsMultiFactorAuthEnabled = refs.NewBoolRef(true)
- }
-
- if params.AppData != nil {
- appDataString := ""
- appDataBytes, err := json.Marshal(params.AppData)
- if err != nil {
- log.Debug("failed to marshall source app_data: ", err)
- return nil, errors.New("malformed app_data")
- }
- appDataString = string(appDataBytes)
- user.AppData = &appDataString
- }
- isEmailVerificationDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableEmailVerification)
- if err != nil {
- log.Debug("Error getting email verification disabled: ", err)
- isEmailVerificationDisabled = true
- }
- if isEmailVerificationDisabled && isEmailSignup {
- now := time.Now().Unix()
- user.EmailVerifiedAt = &now
- }
- disablePhoneVerification, _ := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisablePhoneVerification)
- if disablePhoneVerification && isMobileSignup {
- now := time.Now().Unix()
- user.PhoneNumberVerifiedAt = &now
- }
- isSMSServiceEnabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyIsSMSServiceEnabled)
- if err != nil || !isSMSServiceEnabled {
- log.Debug("SMS service not enabled: ", err)
- }
- user, err = db.Provider.AddUser(ctx, user)
- if err != nil {
- log.Debug("Failed to add user: ", err)
- return res, err
- }
- roles := strings.Split(user.Roles, ",")
- userToReturn := user.AsAPIUser()
- hostname := parsers.GetHost(gc)
- if !isEmailVerificationDisabled && isEmailSignup {
- // insert verification request
- _, nonceHash, err := utils.GenerateNonce()
- if err != nil {
- log.Debug("Failed to generate nonce: ", err)
- return res, err
- }
- verificationType := constants.VerificationTypeBasicAuthSignup
- redirectURL := parsers.GetAppURL(gc)
- if params.RedirectURI != nil {
- redirectURL = *params.RedirectURI
- }
- verificationToken, err := token.CreateVerificationToken(email, verificationType, hostname, nonceHash, redirectURL)
- if err != nil {
- log.Debug("Failed to create verification token: ", err)
- return res, err
- }
- _, err = db.Provider.AddVerificationRequest(ctx, &models.VerificationRequest{
- Token: verificationToken,
- Identifier: verificationType,
- ExpiresAt: time.Now().Add(time.Minute * 30).Unix(),
- Email: email,
- Nonce: nonceHash,
- RedirectURI: redirectURL,
- })
- if err != nil {
- log.Debug("Failed to add verification request: ", err)
- return res, err
- }
- // exec it as go routine so that we can reduce the api latency
- go func() {
- // exec it as go routine so that we can reduce the api latency
- emailService.SendEmail([]string{email}, constants.VerificationTypeBasicAuthSignup, map[string]interface{}{
- "user": user.ToMap(),
- "organization": utils.GetOrganization(),
- "verification_url": utils.GetEmailVerificationURL(verificationToken, hostname, redirectURL),
- })
- utils.RegisterEvent(ctx, constants.UserCreatedWebhookEvent, constants.AuthRecipeMethodBasicAuth, user)
- }()
-
- return &model.AuthResponse{
- Message: `Verification email has been sent. Please check your inbox`,
- User: userToReturn,
- }, nil
- } else if !disablePhoneVerification && isSMSServiceEnabled && isMobileSignup {
- duration, _ := time.ParseDuration("10m")
- smsCode := utils.GenerateOTP()
- smsBody := strings.Builder{}
- smsBody.WriteString("Your verification code is: ")
- smsBody.WriteString(smsCode)
- expiresAt := time.Now().Add(duration).Unix()
- _, err = db.Provider.UpsertOTP(ctx, &models.OTP{
- PhoneNumber: phoneNumber,
- Otp: smsCode,
- ExpiresAt: expiresAt,
- })
- if err != nil {
- log.Debug("error while upserting OTP: ", err.Error())
- return nil, err
- }
- mfaSession := uuid.NewString()
- err = memorystore.Provider.SetMfaSession(user.ID, mfaSession, expiresAt)
- if err != nil {
- log.Debug("Failed to add mfasession: ", err)
- return nil, err
- }
- cookie.SetMfaSession(gc, mfaSession)
- go func() {
- smsproviders.SendSMS(phoneNumber, smsBody.String())
- utils.RegisterEvent(ctx, constants.UserCreatedWebhookEvent, constants.AuthRecipeMethodMobileBasicAuth, user)
- }()
- return &model.AuthResponse{
- Message: "Please check the OTP in your inbox",
- ShouldShowMobileOtpScreen: refs.NewBoolRef(true),
- }, nil
- }
- scope := []string{"openid", "email", "profile"}
- if params.Scope != nil && len(scope) > 0 {
- scope = params.Scope
- }
-
- code := ""
- codeChallenge := ""
- nonce := ""
- if params.State != nil {
- // Get state from store
- authorizeState, _ := memorystore.Provider.GetState(refs.StringValue(params.State))
- if authorizeState != "" {
- authorizeStateSplit := strings.Split(authorizeState, "@@")
- if len(authorizeStateSplit) > 1 {
- code = authorizeStateSplit[0]
- codeChallenge = authorizeStateSplit[1]
- } else {
- nonce = authorizeState
- }
- go memorystore.Provider.RemoveState(refs.StringValue(params.State))
- }
- }
-
- if nonce == "" {
- nonce = uuid.New().String()
- }
-
- authToken, err := token.CreateAuthToken(gc, user, roles, scope, constants.AuthRecipeMethodBasicAuth, nonce, code)
- if err != nil {
- log.Debug("Failed to create auth token: ", err)
- return res, err
- }
-
- // Code challenge could be optional if PKCE flow is not used
- if code != "" {
- if err := memorystore.Provider.SetState(code, codeChallenge+"@@"+authToken.FingerPrintHash); err != nil {
- log.Debug("SetState failed: ", err)
- return res, err
- }
- }
-
- expiresIn := authToken.AccessToken.ExpiresAt - time.Now().Unix()
- if expiresIn <= 0 {
- expiresIn = 1
- }
-
- res = &model.AuthResponse{
- Message: `Signed up successfully.`,
- AccessToken: &authToken.AccessToken.Token,
- ExpiresIn: &expiresIn,
- User: userToReturn,
- }
-
- sessionKey := constants.AuthRecipeMethodBasicAuth + ":" + user.ID
- cookie.SetSession(gc, authToken.FingerPrintHash)
- memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash, authToken.SessionTokenExpiresAt)
- memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token, authToken.AccessToken.ExpiresAt)
-
- if authToken.RefreshToken != nil {
- res.RefreshToken = &authToken.RefreshToken.Token
- memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token, authToken.RefreshToken.ExpiresAt)
- }
-
- go func() {
- utils.RegisterEvent(ctx, constants.UserCreatedWebhookEvent, constants.AuthRecipeMethodBasicAuth, user)
- if isEmailSignup {
- utils.RegisterEvent(ctx, constants.UserSignUpWebhookEvent, constants.AuthRecipeMethodBasicAuth, user)
- utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, constants.AuthRecipeMethodBasicAuth, user)
- } else {
- utils.RegisterEvent(ctx, constants.UserSignUpWebhookEvent, constants.AuthRecipeMethodMobileBasicAuth, user)
- utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, constants.AuthRecipeMethodMobileBasicAuth, user)
- }
-
- db.Provider.AddSession(ctx, &models.Session{
- UserID: user.ID,
- UserAgent: utils.GetUserAgent(gc.Request),
- IP: utils.GetIP(gc.Request),
- })
- }()
-
- return res, nil
-}
diff --git a/server/resolvers/update_env.go b/server/resolvers/update_env.go
deleted file mode 100644
index 62bd33eea..000000000
--- a/server/resolvers/update_env.go
+++ /dev/null
@@ -1,436 +0,0 @@
-package resolvers
-
-import (
- "context"
- "encoding/json"
- "errors"
- "fmt"
- "reflect"
- "strings"
- "time"
-
- log "github.com/sirupsen/logrus"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/cookie"
- "github.com/authorizerdev/authorizer/server/crypto"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/oauth"
- "github.com/authorizerdev/authorizer/server/token"
- "github.com/authorizerdev/authorizer/server/utils"
-)
-
-// check if login methods have been disabled
-// remove the session tokens for those methods
-func clearSessionIfRequired(currentData, updatedData map[string]interface{}) {
- isCurrentBasicAuthEnabled := !currentData[constants.EnvKeyDisableBasicAuthentication].(bool)
- isCurrentMobileBasicAuthEnabled := !currentData[constants.EnvKeyDisableMobileBasicAuthentication].(bool)
- isCurrentMagicLinkLoginEnabled := !currentData[constants.EnvKeyDisableMagicLinkLogin].(bool)
- isCurrentAppleLoginEnabled := currentData[constants.EnvKeyAppleClientID] != nil && currentData[constants.EnvKeyAppleClientSecret] != nil && currentData[constants.EnvKeyAppleClientID].(string) != "" && currentData[constants.EnvKeyAppleClientSecret].(string) != ""
- isCurrentFacebookLoginEnabled := currentData[constants.EnvKeyFacebookClientID] != nil && currentData[constants.EnvKeyFacebookClientSecret] != nil && currentData[constants.EnvKeyFacebookClientID].(string) != "" && currentData[constants.EnvKeyFacebookClientSecret].(string) != ""
- isCurrentGoogleLoginEnabled := currentData[constants.EnvKeyGoogleClientID] != nil && currentData[constants.EnvKeyGoogleClientSecret] != nil && currentData[constants.EnvKeyGoogleClientID].(string) != "" && currentData[constants.EnvKeyGoogleClientSecret].(string) != ""
- isCurrentGithubLoginEnabled := currentData[constants.EnvKeyGithubClientID] != nil && currentData[constants.EnvKeyGithubClientSecret] != nil && currentData[constants.EnvKeyGithubClientID].(string) != "" && currentData[constants.EnvKeyGithubClientSecret].(string) != ""
- isCurrentLinkedInLoginEnabled := currentData[constants.EnvKeyLinkedInClientID] != nil && currentData[constants.EnvKeyLinkedInClientSecret] != nil && currentData[constants.EnvKeyLinkedInClientID].(string) != "" && currentData[constants.EnvKeyLinkedInClientSecret].(string) != ""
- isCurrentTwitterLoginEnabled := currentData[constants.EnvKeyTwitterClientID] != nil && currentData[constants.EnvKeyTwitterClientSecret] != nil && currentData[constants.EnvKeyTwitterClientID].(string) != "" && currentData[constants.EnvKeyTwitterClientSecret].(string) != ""
- isCurrentMicrosoftLoginEnabled := currentData[constants.EnvKeyMicrosoftClientID] != nil && currentData[constants.EnvKeyMicrosoftClientSecret] != nil && currentData[constants.EnvKeyMicrosoftClientID].(string) != "" && currentData[constants.EnvKeyMicrosoftClientSecret].(string) != ""
- isCurrentTwitchLoginEnabled := currentData[constants.EnvKeyTwitchClientID] != nil && currentData[constants.EnvKeyTwitchClientSecret] != nil && currentData[constants.EnvKeyTwitchClientID].(string) != "" && currentData[constants.EnvKeyTwitchClientSecret].(string) != ""
-
- isUpdatedBasicAuthEnabled := !updatedData[constants.EnvKeyDisableBasicAuthentication].(bool)
- isUpdatedMobileBasicAuthEnabled := !updatedData[constants.EnvKeyDisableMobileBasicAuthentication].(bool)
- isUpdatedMagicLinkLoginEnabled := !updatedData[constants.EnvKeyDisableMagicLinkLogin].(bool)
- isUpdatedAppleLoginEnabled := updatedData[constants.EnvKeyAppleClientID] != nil && updatedData[constants.EnvKeyAppleClientSecret] != nil && updatedData[constants.EnvKeyAppleClientID].(string) != "" && updatedData[constants.EnvKeyAppleClientSecret].(string) != ""
- isUpdatedFacebookLoginEnabled := updatedData[constants.EnvKeyFacebookClientID] != nil && updatedData[constants.EnvKeyFacebookClientSecret] != nil && updatedData[constants.EnvKeyFacebookClientID].(string) != "" && updatedData[constants.EnvKeyFacebookClientSecret].(string) != ""
- isUpdatedGoogleLoginEnabled := updatedData[constants.EnvKeyGoogleClientID] != nil && updatedData[constants.EnvKeyGoogleClientSecret] != nil && updatedData[constants.EnvKeyGoogleClientID].(string) != "" && updatedData[constants.EnvKeyGoogleClientSecret].(string) != ""
- isUpdatedGithubLoginEnabled := updatedData[constants.EnvKeyGithubClientID] != nil && updatedData[constants.EnvKeyGithubClientSecret] != nil && updatedData[constants.EnvKeyGithubClientID].(string) != "" && updatedData[constants.EnvKeyGithubClientSecret].(string) != ""
- isUpdatedLinkedInLoginEnabled := updatedData[constants.EnvKeyLinkedInClientID] != nil && updatedData[constants.EnvKeyLinkedInClientSecret] != nil && updatedData[constants.EnvKeyLinkedInClientID].(string) != "" && updatedData[constants.EnvKeyLinkedInClientSecret].(string) != ""
- isUpdatedTwitterLoginEnabled := updatedData[constants.EnvKeyTwitterClientID] != nil && updatedData[constants.EnvKeyTwitterClientSecret] != nil && updatedData[constants.EnvKeyTwitterClientID].(string) != "" && updatedData[constants.EnvKeyTwitterClientSecret].(string) != ""
- isUpdatedMicrosoftLoginEnabled := updatedData[constants.EnvKeyMicrosoftClientID] != nil && updatedData[constants.EnvKeyMicrosoftClientSecret] != nil && updatedData[constants.EnvKeyMicrosoftClientID].(string) != "" && updatedData[constants.EnvKeyMicrosoftClientSecret].(string) != ""
- isUpdatedTwitchLoginEnabled := updatedData[constants.EnvKeyTwitchClientID] != nil && updatedData[constants.EnvKeyTwitchClientSecret] != nil && updatedData[constants.EnvKeyTwitchClientID].(string) != "" && updatedData[constants.EnvKeyTwitchClientSecret].(string) != ""
-
- if isCurrentBasicAuthEnabled && !isUpdatedBasicAuthEnabled {
- memorystore.Provider.DeleteSessionForNamespace(constants.AuthRecipeMethodBasicAuth)
- }
-
- if isCurrentMobileBasicAuthEnabled && !isUpdatedMobileBasicAuthEnabled {
- memorystore.Provider.DeleteSessionForNamespace(constants.AuthRecipeMethodMobileBasicAuth)
- }
-
- if isCurrentMagicLinkLoginEnabled && !isUpdatedMagicLinkLoginEnabled {
- memorystore.Provider.DeleteSessionForNamespace(constants.AuthRecipeMethodMagicLinkLogin)
- }
-
- if isCurrentAppleLoginEnabled && !isUpdatedAppleLoginEnabled {
- memorystore.Provider.DeleteSessionForNamespace(constants.AuthRecipeMethodApple)
- }
-
- if isCurrentFacebookLoginEnabled && !isUpdatedFacebookLoginEnabled {
- memorystore.Provider.DeleteSessionForNamespace(constants.AuthRecipeMethodFacebook)
- }
-
- if isCurrentGoogleLoginEnabled && !isUpdatedGoogleLoginEnabled {
- memorystore.Provider.DeleteSessionForNamespace(constants.AuthRecipeMethodGoogle)
- }
-
- if isCurrentGithubLoginEnabled && !isUpdatedGithubLoginEnabled {
- memorystore.Provider.DeleteSessionForNamespace(constants.AuthRecipeMethodGithub)
- }
-
- if isCurrentLinkedInLoginEnabled && !isUpdatedLinkedInLoginEnabled {
- memorystore.Provider.DeleteSessionForNamespace(constants.AuthRecipeMethodLinkedIn)
- }
-
- if isCurrentTwitterLoginEnabled && !isUpdatedTwitterLoginEnabled {
- memorystore.Provider.DeleteSessionForNamespace(constants.AuthRecipeMethodTwitter)
- }
-
- if isCurrentMicrosoftLoginEnabled && !isUpdatedMicrosoftLoginEnabled {
- memorystore.Provider.DeleteSessionForNamespace(constants.AuthRecipeMethodMicrosoft)
- }
-
- if isCurrentTwitchLoginEnabled && !isUpdatedTwitchLoginEnabled {
- memorystore.Provider.DeleteSessionForNamespace(constants.AuthRecipeMethodTwitch)
- }
-}
-
-// updateRoles will update DB for user roles, if a role is deleted by admin
-// then this function will those roles from user roles if exists
-func updateRoles(ctx context.Context, deletedRoles []string) error {
- data, err := db.Provider.ListUsers(ctx, &model.Pagination{
- Limit: 1,
- Offset: 1,
- })
- if err != nil {
- return err
- }
-
- allData, err := db.Provider.ListUsers(ctx, &model.Pagination{
- Limit: data.Pagination.Total,
- })
- if err != nil {
- return err
- }
-
- chunkSize := 1000
- totalUsers := len(allData.Users)
-
- for start := 0; start < totalUsers; start += chunkSize {
- end := start + chunkSize
- if end > totalUsers {
- end = totalUsers
- }
-
- chunkUsers := allData.Users[start:end]
-
- for i := range chunkUsers {
- roles := utils.DeleteFromArray(chunkUsers[i].Roles, deletedRoles)
- if len(chunkUsers[i].Roles) != len(roles) {
- updatedValues := map[string]interface{}{
- "roles": strings.Join(roles, ","),
- "updated_at": time.Now().Unix(),
- }
- id := []string{chunkUsers[i].ID}
- err = db.Provider.UpdateUsers(ctx, updatedValues, id)
- if err != nil {
- return err
- }
- }
- }
- }
- return nil
-}
-
-// UpdateEnvResolver is a resolver for update config mutation
-// This is admin only mutation
-func UpdateEnvResolver(ctx context.Context, params model.UpdateEnvInput) (*model.Response, error) {
- var res *model.Response
-
- gc, err := utils.GinContextFromContext(ctx)
- if err != nil {
- log.Debug("Failed to get GinContext: ", err)
- return res, err
- }
-
- if !token.IsSuperAdmin(gc) {
- log.Debug("Not logged in as super admin")
- return res, fmt.Errorf("unauthorized")
- }
-
- currentData, err := memorystore.Provider.GetEnvStore()
- if err != nil {
- log.Debug("Failed to get env store: ", err)
- return res, err
- }
-
- // clone currentData in new var
- // that will be updated based on the req
- updatedData := make(map[string]interface{})
- for key, val := range currentData {
- updatedData[key] = val
- }
-
- isJWTUpdated := false
- algo := updatedData[constants.EnvKeyJwtType].(string)
- if params.JwtType != nil {
- algo = *params.JwtType
- if !crypto.IsHMACA(algo) && !crypto.IsECDSA(algo) && !crypto.IsRSA(algo) {
- log.Debug("Invalid JWT type: ", algo)
- return res, fmt.Errorf("invalid jwt type")
- }
-
- updatedData[constants.EnvKeyJwtType] = algo
- isJWTUpdated = true
- }
-
- if params.JwtSecret != nil || params.JwtPublicKey != nil || params.JwtPrivateKey != nil {
- isJWTUpdated = true
- }
-
- if isJWTUpdated {
- // use to reset when type is changed from rsa, edsa -> hmac or vice a versa
- defaultSecret := ""
- defaultPublicKey := ""
- defaultPrivateKey := ""
- // check if jwt secret is provided
- if crypto.IsHMACA(algo) {
- if params.JwtSecret == nil {
- log.Debug("JWT secret is required for HMAC")
- return res, fmt.Errorf("jwt secret is required for HMAC algorithm")
- }
-
- // reset public key and private key
- params.JwtPrivateKey = &defaultPrivateKey
- params.JwtPublicKey = &defaultPublicKey
- }
-
- if crypto.IsRSA(algo) {
- if params.JwtPrivateKey == nil || params.JwtPublicKey == nil {
- log.Debug("JWT private key and public key are required for RSA: ", *params.JwtPrivateKey, *params.JwtPublicKey)
- return res, fmt.Errorf("jwt private and public key is required for RSA (PKCS1) / ECDSA algorithm")
- }
-
- // reset the jwt secret
- params.JwtSecret = &defaultSecret
- _, err = crypto.ParseRsaPrivateKeyFromPemStr(*params.JwtPrivateKey)
- if err != nil {
- log.Debug("Invalid JWT private key: ", err)
- return res, err
- }
-
- _, err := crypto.ParseRsaPublicKeyFromPemStr(*params.JwtPublicKey)
- if err != nil {
- log.Debug("Invalid JWT public key: ", err)
- return res, err
- }
- }
-
- if crypto.IsECDSA(algo) {
- if params.JwtPrivateKey == nil || params.JwtPublicKey == nil {
- log.Debug("JWT private key and public key are required for ECDSA: ", *params.JwtPrivateKey, *params.JwtPublicKey)
- return res, fmt.Errorf("jwt private and public key is required for RSA (PKCS1) / ECDSA algorithm")
- }
-
- // reset the jwt secret
- params.JwtSecret = &defaultSecret
- _, err = crypto.ParseEcdsaPrivateKeyFromPemStr(*params.JwtPrivateKey)
- if err != nil {
- log.Debug("Invalid JWT private key: ", err)
- return res, err
- }
-
- _, err := crypto.ParseEcdsaPublicKeyFromPemStr(*params.JwtPublicKey)
- if err != nil {
- log.Debug("Invalid JWT public key: ", err)
- return res, err
- }
- }
-
- }
-
- var data map[string]interface{}
- byteData, err := json.Marshal(params)
- if err != nil {
- log.Debug("Failed to marshal update env input: ", err)
- return res, fmt.Errorf("error marshalling params: %t", err)
- }
-
- err = json.Unmarshal(byteData, &data)
- if err != nil {
- log.Debug("Failed to unmarshal update env input: ", err)
- return res, fmt.Errorf("error un-marshalling params: %t", err)
- }
-
- // in case of admin secret change update the cookie with new hash
- if params.AdminSecret != nil {
- if params.OldAdminSecret == nil {
- log.Debug("Old admin secret is required for admin secret update")
- return res, errors.New("admin secret and old admin secret are required for secret change")
- }
- oldAdminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
- if err != nil {
- log.Debug("Failed to get old admin secret: ", err)
- return res, err
- }
- if *params.OldAdminSecret != oldAdminSecret {
- log.Debug("Old admin secret is invalid")
- return res, errors.New("old admin secret is not correct")
- }
-
- if len(*params.AdminSecret) < 6 {
- log.Debug("Admin secret is too short")
- err = fmt.Errorf("admin secret must be at least 6 characters")
- return res, err
- }
-
- }
-
- for key, value := range data {
- if value != nil {
- fieldType := reflect.TypeOf(value).String()
-
- if fieldType == "string" {
- updatedData[key] = value.(string)
- }
-
- if fieldType == "bool" {
- updatedData[key] = value.(bool)
- }
- if fieldType == "[]interface {}" {
- stringArr := utils.ConvertInterfaceToStringSlice(value)
- updatedData[key] = strings.Join(stringArr, ",")
- }
- }
- }
-
- // handle derivative cases like disabling email verification & magic login
- // in case SMTP is off but env is set to true
- if updatedData[constants.EnvKeySmtpHost] == "" || updatedData[constants.EnvKeySmtpUsername] == "" || updatedData[constants.EnvKeySmtpPassword] == "" || updatedData[constants.EnvKeySenderEmail] == "" && updatedData[constants.EnvKeySmtpPort] == "" {
- updatedData[constants.EnvKeyIsEmailServiceEnabled] = false
- if !updatedData[constants.EnvKeyDisableEmailVerification].(bool) {
- updatedData[constants.EnvKeyDisableEmailVerification] = true
- }
- if !updatedData[constants.EnvKeyDisableMailOTPLogin].(bool) {
- updatedData[constants.EnvKeyDisableMailOTPLogin] = true
- }
- if !updatedData[constants.EnvKeyDisableMagicLinkLogin].(bool) {
- updatedData[constants.EnvKeyDisableMailOTPLogin] = true
- }
- }
-
- if updatedData[constants.EnvKeySmtpHost] != "" || updatedData[constants.EnvKeySmtpUsername] != "" || updatedData[constants.EnvKeySmtpPassword] != "" || updatedData[constants.EnvKeySenderEmail] != "" && updatedData[constants.EnvKeySmtpPort] != "" {
- updatedData[constants.EnvKeyIsEmailServiceEnabled] = true
- }
-
- if updatedData[constants.EnvKeyTwilioAPIKey] == "" || updatedData[constants.EnvKeyTwilioAPISecret] == "" || updatedData[constants.EnvKeyTwilioAccountSID] == "" || updatedData[constants.EnvKeyTwilioSender] == "" {
- updatedData[constants.EnvKeyIsSMSServiceEnabled] = false
- if !updatedData[constants.EnvKeyIsSMSServiceEnabled].(bool) {
- updatedData[constants.EnvKeyDisablePhoneVerification] = true
- }
- }
-
- if updatedData[constants.EnvKeyDisableMultiFactorAuthentication].(bool) && updatedData[constants.EnvKeyIsEmailServiceEnabled].(bool) {
- updatedData[constants.EnvKeyDisableMailOTPLogin] = true
- }
-
- if !currentData[constants.EnvKeyEnforceMultiFactorAuthentication].(bool) && updatedData[constants.EnvKeyEnforceMultiFactorAuthentication].(bool) && !updatedData[constants.EnvKeyDisableMultiFactorAuthentication].(bool) {
- go db.Provider.UpdateUsers(ctx, map[string]interface{}{
- "is_multi_factor_auth_enabled": true,
- }, nil)
- }
-
- previousRoles := strings.Split(currentData[constants.EnvKeyRoles].(string), ",")
- previousProtectedRoles := strings.Split(currentData[constants.EnvKeyProtectedRoles].(string), ",")
- updatedRoles := strings.Split(updatedData[constants.EnvKeyRoles].(string), ",")
- updatedDefaultRoles := strings.Split(updatedData[constants.EnvKeyDefaultRoles].(string), ",")
- updatedProtectedRoles := strings.Split(updatedData[constants.EnvKeyProtectedRoles].(string), ",")
- // check the roles change
- if len(updatedRoles) > 0 && len(updatedDefaultRoles) > 0 {
- // should be subset of roles
- for _, role := range updatedDefaultRoles {
- if !utils.StringSliceContains(updatedRoles, role) {
- log.Debug("Default roles should be subset of roles")
- return res, fmt.Errorf("default role %s is not in roles", role)
- }
- }
- }
-
- if len(updatedProtectedRoles) > 0 {
- for _, role := range updatedProtectedRoles {
- if utils.StringSliceContains(updatedRoles, role) || utils.StringSliceContains(updatedDefaultRoles, role) {
- log.Debug("Protected roles should not be in roles or default roles")
- return res, fmt.Errorf("protected role %s found roles or default roles", role)
- }
- }
- }
-
- deletedRoles := utils.FindDeletedValues(previousRoles, updatedRoles)
- if len(deletedRoles) > 0 {
- go updateRoles(ctx, deletedRoles)
- }
-
- deletedProtectedRoles := utils.FindDeletedValues(previousProtectedRoles, updatedProtectedRoles)
- if len(deletedProtectedRoles) > 0 {
- go updateRoles(ctx, deletedProtectedRoles)
- }
-
- // Update local store
- memorystore.Provider.UpdateEnvStore(updatedData)
- jwk, err := crypto.GenerateJWKBasedOnEnv()
- if err != nil {
- log.Debug("Failed to generate JWK: ", err)
- return res, err
- }
- // updating jwk
- err = memorystore.Provider.UpdateEnvVariable(constants.EnvKeyJWK, jwk)
- if err != nil {
- log.Debug("Failed to update JWK: ", err)
- return res, err
- }
-
- err = oauth.InitOAuth()
- if err != nil {
- return res, err
- }
-
- // Fetch the current db store and update it
- env, err := db.Provider.GetEnv(ctx)
- if err != nil {
- log.Debug("Failed to get env: ", err)
- return res, err
- }
-
- if params.AdminSecret != nil {
- adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
- if err != nil {
- log.Debug("Failed to get admin secret: ", err)
- return res, err
- }
- hashedKey, err := crypto.EncryptPassword(adminSecret)
- if err != nil {
- log.Debug("Failed to encrypt admin secret: ", err)
- return res, err
- }
- cookie.SetAdminCookie(gc, hashedKey)
- }
-
- encryptedConfig, err := crypto.EncryptEnvData(updatedData)
- if err != nil {
- log.Debug("Failed to encrypt env data: ", err)
- return res, err
- }
-
- env.EnvData = encryptedConfig
- _, err = db.Provider.UpdateEnv(ctx, env)
- if err != nil {
- log.Debug("Failed to update env: ", err)
- return res, err
- }
-
- go clearSessionIfRequired(currentData, updatedData)
-
- res = &model.Response{
- Message: "configurations updated successfully",
- }
- return res, nil
-}
diff --git a/server/resolvers/update_user.go b/server/resolvers/update_user.go
deleted file mode 100644
index 006c9e994..000000000
--- a/server/resolvers/update_user.go
+++ /dev/null
@@ -1,297 +0,0 @@
-package resolvers
-
-import (
- "context"
- "encoding/json"
- "errors"
- "fmt"
- "strings"
- "time"
-
- log "github.com/sirupsen/logrus"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/db/models"
- "github.com/authorizerdev/authorizer/server/email"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/parsers"
- "github.com/authorizerdev/authorizer/server/refs"
- "github.com/authorizerdev/authorizer/server/token"
- "github.com/authorizerdev/authorizer/server/utils"
- "github.com/authorizerdev/authorizer/server/validators"
-)
-
-// UpdateUserResolver is a resolver for update user mutation
-// This is admin only mutation
-func UpdateUserResolver(ctx context.Context, params model.UpdateUserInput) (*model.User, error) {
- var res *model.User
-
- gc, err := utils.GinContextFromContext(ctx)
- if err != nil {
- log.Debug("Failed to get GinContext: ", err)
- return res, err
- }
-
- if !token.IsSuperAdmin(gc) {
- log.Debug("Not logged in as super admin")
- return res, fmt.Errorf("unauthorized")
- }
-
- if params.ID == "" {
- log.Debug("UserID is empty")
- return res, fmt.Errorf("User ID is required")
- }
-
- log := log.WithFields(log.Fields{
- "user_id": params.ID,
- })
-
- if params.GivenName == nil &&
- params.FamilyName == nil &&
- params.Picture == nil &&
- params.MiddleName == nil &&
- params.Nickname == nil &&
- params.Email == nil &&
- params.Birthdate == nil &&
- params.Gender == nil &&
- params.PhoneNumber == nil &&
- params.Roles == nil &&
- params.IsMultiFactorAuthEnabled == nil &&
- params.AppData == nil {
- log.Debug("No params to update")
- return res, fmt.Errorf("please enter atleast one param to update")
- }
-
- user, err := db.Provider.GetUserByID(ctx, params.ID)
- if err != nil {
- log.Debug("Failed to get user by id: ", err)
- return res, fmt.Errorf(`User not found`)
- }
-
- if params.GivenName != nil && refs.StringValue(user.GivenName) != refs.StringValue(params.GivenName) {
- user.GivenName = params.GivenName
- }
-
- if params.FamilyName != nil && refs.StringValue(user.FamilyName) != refs.StringValue(params.FamilyName) {
- user.FamilyName = params.FamilyName
- }
-
- if params.MiddleName != nil && refs.StringValue(user.MiddleName) != refs.StringValue(params.MiddleName) {
- user.MiddleName = params.MiddleName
- }
-
- if params.Nickname != nil && refs.StringValue(user.Nickname) != refs.StringValue(params.Nickname) {
- user.Nickname = params.Nickname
- }
-
- if params.Birthdate != nil && refs.StringValue(user.Birthdate) != refs.StringValue(params.Birthdate) {
- user.Birthdate = params.Birthdate
- }
-
- if params.Gender != nil && refs.StringValue(user.Gender) != refs.StringValue(params.Gender) {
- user.Gender = params.Gender
- }
-
- if params.PhoneNumber != nil && refs.StringValue(user.PhoneNumber) != refs.StringValue(params.PhoneNumber) {
- // verify if phone number is unique
- if _, err := db.Provider.GetUserByPhoneNumber(ctx, strings.TrimSpace(refs.StringValue(params.PhoneNumber))); err == nil {
- log.Debug("user with given phone number already exists")
- return nil, errors.New("user with given phone number already exists")
- }
- user.PhoneNumber = params.PhoneNumber
- }
-
- if params.Picture != nil && refs.StringValue(user.Picture) != refs.StringValue(params.Picture) {
- user.Picture = params.Picture
- }
-
- if params.AppData != nil {
- appDataString := ""
- appDataBytes, err := json.Marshal(params.AppData)
- if err != nil {
- log.Debug("failed to marshall source app_data: ", err)
- return nil, errors.New("malformed app_data")
- }
- appDataString = string(appDataBytes)
- user.AppData = &appDataString
- }
-
- if params.IsMultiFactorAuthEnabled != nil && refs.BoolValue(user.IsMultiFactorAuthEnabled) != refs.BoolValue(params.IsMultiFactorAuthEnabled) {
- user.IsMultiFactorAuthEnabled = params.IsMultiFactorAuthEnabled
- if refs.BoolValue(params.IsMultiFactorAuthEnabled) {
- // Check if totp, email or sms is enabled
- isMailOTPEnvServiceDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableMailOTPLogin)
- if err != nil {
- log.Debug("Error getting mail otp disabled: ", err)
- isMailOTPEnvServiceDisabled = false
- }
- isTOTPEnvServiceDisabled, _ := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableTOTPLogin)
- if err != nil {
- log.Debug("Error getting totp disabled: ", err)
- isTOTPEnvServiceDisabled = false
- }
- isSMSOTPEnvServiceDisabled, _ := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisablePhoneVerification)
- if err != nil {
- log.Debug("Error getting sms otp disabled: ", err)
- isSMSOTPEnvServiceDisabled = false
- }
- // Initialize a flag to check if enabling Mail OTP is required
- if isMailOTPEnvServiceDisabled && isTOTPEnvServiceDisabled && isSMSOTPEnvServiceDisabled {
- log.Debug("Cannot enable mfa service as all mfa services are disabled")
- return nil, errors.New("cannot enable multi factor authentication as all mfa services are disabled")
- }
- }
- }
-
- if params.EmailVerified != nil {
- if *params.EmailVerified {
- now := time.Now().Unix()
- user.EmailVerifiedAt = &now
- } else {
- user.EmailVerifiedAt = nil
- }
- }
- if params.PhoneNumberVerified != nil {
- if *params.PhoneNumberVerified {
- now := time.Now().Unix()
- user.PhoneNumberVerifiedAt = &now
- } else {
- user.PhoneNumberVerifiedAt = nil
- }
-
- }
-
- if params.Email != nil && refs.StringValue(user.Email) != refs.StringValue(params.Email) {
- // check if valid email
- if !validators.IsValidEmail(*params.Email) {
- log.Debug("Invalid email: ", *params.Email)
- return res, fmt.Errorf("invalid email address")
- }
- newEmail := strings.ToLower(*params.Email)
- // check if user with new email exists
- _, err = db.Provider.GetUserByEmail(ctx, newEmail)
- // err = nil means user exists
- if err == nil {
- log.Debug("User with email already exists: ", newEmail)
- return res, fmt.Errorf("user with this email address already exists")
- }
-
- go memorystore.Provider.DeleteAllUserSessions(user.ID)
-
- hostname := parsers.GetHost(gc)
- user.Email = &newEmail
- user.EmailVerifiedAt = nil
- // insert verification request
- _, nonceHash, err := utils.GenerateNonce()
- if err != nil {
- log.Debug("Failed to generate nonce: ", err)
- return res, err
- }
- verificationType := constants.VerificationTypeUpdateEmail
- redirectURL := parsers.GetAppURL(gc)
- verificationToken, err := token.CreateVerificationToken(newEmail, verificationType, hostname, nonceHash, redirectURL)
- if err != nil {
- log.Debug("Failed to create verification token: ", err)
- }
- _, err = db.Provider.AddVerificationRequest(ctx, &models.VerificationRequest{
- Token: verificationToken,
- Identifier: verificationType,
- ExpiresAt: time.Now().Add(time.Minute * 30).Unix(),
- Email: newEmail,
- Nonce: nonceHash,
- RedirectURI: redirectURL,
- })
- if err != nil {
- log.Debug("Failed to add verification request: ", err)
- return res, err
- }
-
- // exec it as go routine so that we can reduce the api latency
- go email.SendEmail([]string{refs.StringValue(user.Email)}, constants.VerificationTypeBasicAuthSignup, map[string]interface{}{
- "user": user.ToMap(),
- "organization": utils.GetOrganization(),
- "verification_url": utils.GetEmailVerificationURL(verificationToken, hostname, redirectURL),
- })
-
- }
-
- if params.PhoneNumber != nil && refs.StringValue(user.PhoneNumber) != refs.StringValue(params.PhoneNumber) {
- phone := strings.TrimSpace(refs.StringValue(params.PhoneNumber))
- if len(phone) < 10 || len(phone) > 15 {
- log.Debug("Invalid phone number: ", *params.PhoneNumber)
- return res, fmt.Errorf("invalid phone number")
- }
- // check if user with new phone number exists
- _, err = db.Provider.GetUserByPhoneNumber(ctx, phone)
- // err = nil means user exists
- if err == nil {
- log.Debug("User with phone number already exists: ", phone)
- return res, fmt.Errorf("user with this phone number already exists")
- }
- go memorystore.Provider.DeleteAllUserSessions(user.ID)
- user.PhoneNumber = &phone
- user.PhoneNumberVerifiedAt = nil
- }
-
- rolesToSave := ""
- if params.Roles != nil && len(params.Roles) > 0 {
- currentRoles := strings.Split(user.Roles, ",")
- inputRoles := []string{}
- for _, item := range params.Roles {
- inputRoles = append(inputRoles, *item)
- }
-
- rolesString, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyRoles)
- roles := []string{}
- if err != nil {
- log.Debug("Error getting roles: ", err)
- rolesString = ""
- } else {
- roles = strings.Split(rolesString, ",")
- }
- protectedRolesString, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyProtectedRoles)
- protectedRoles := []string{}
- if err != nil {
- log.Debug("Error getting protected roles: ", err)
- protectedRolesString = ""
- } else {
- protectedRoles = strings.Split(protectedRolesString, ",")
- }
-
- if !validators.IsValidRoles(inputRoles, append([]string{}, append(roles, protectedRoles...)...)) {
- log.Debug("Invalid roles: ", params.Roles)
- return res, fmt.Errorf("invalid list of roles")
- }
-
- if !validators.IsStringArrayEqual(inputRoles, currentRoles) {
- rolesToSave = strings.Join(inputRoles, ",")
- }
-
- go memorystore.Provider.DeleteAllUserSessions(user.ID)
- }
-
- if rolesToSave != "" {
- user.Roles = rolesToSave
- }
- user, err = db.Provider.UpdateUser(ctx, user)
- if err != nil {
- log.Debug("Failed to update user: ", err)
- return res, err
- }
-
- createdAt := user.CreatedAt
- updatedAt := user.UpdatedAt
- res = &model.User{
- ID: params.ID,
- Email: user.Email,
- Picture: user.Picture,
- GivenName: user.GivenName,
- FamilyName: user.FamilyName,
- Roles: strings.Split(user.Roles, ","),
- CreatedAt: &createdAt,
- UpdatedAt: &updatedAt,
- }
- return res, nil
-}
diff --git a/server/resolvers/user.go b/server/resolvers/user.go
deleted file mode 100644
index 994348cef..000000000
--- a/server/resolvers/user.go
+++ /dev/null
@@ -1,48 +0,0 @@
-package resolvers
-
-import (
- "context"
- "fmt"
- "strings"
-
- log "github.com/sirupsen/logrus"
-
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/token"
- "github.com/authorizerdev/authorizer/server/utils"
-)
-
-// UserResolver is a resolver for user query
-// This is admin only query
-func UserResolver(ctx context.Context, params model.GetUserRequest) (*model.User, error) {
- gc, err := utils.GinContextFromContext(ctx)
- if err != nil {
- log.Debug("Failed to get GinContext: ", err)
- return nil, err
- }
- if !token.IsSuperAdmin(gc) {
- log.Debug("Not logged in as super admin.")
- return nil, fmt.Errorf("unauthorized")
- }
- // Try getting user by ID
- if params.ID != nil && strings.Trim(*params.ID, " ") != "" {
- res, err := db.Provider.GetUserByID(ctx, *params.ID)
- if err != nil {
- log.Debug("Failed to get users by ID: ", err)
- return nil, err
- }
- return res.AsAPIUser(), nil
- }
- // Try getting user by email
- if params.Email != nil && strings.Trim(*params.Email, " ") != "" {
- res, err := db.Provider.GetUserByEmail(ctx, *params.Email)
- if err != nil {
- log.Debug("Failed to get users by email: ", err)
- return nil, err
- }
- return res.AsAPIUser(), nil
- }
- // Return error if no params are provided
- return nil, fmt.Errorf("invalid params, user id or email is required")
-}
diff --git a/server/resolvers/users.go b/server/resolvers/users.go
deleted file mode 100644
index 1ee6aadc8..000000000
--- a/server/resolvers/users.go
+++ /dev/null
@@ -1,38 +0,0 @@
-package resolvers
-
-import (
- "context"
- "fmt"
-
- log "github.com/sirupsen/logrus"
-
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/token"
- "github.com/authorizerdev/authorizer/server/utils"
-)
-
-// UsersResolver is a resolver for users query
-// This is admin only query
-func UsersResolver(ctx context.Context, params *model.PaginatedInput) (*model.Users, error) {
- gc, err := utils.GinContextFromContext(ctx)
- if err != nil {
- log.Debug("Failed to get GinContext: ", err)
- return nil, err
- }
-
- if !token.IsSuperAdmin(gc) {
- log.Debug("Not logged in as super admin.")
- return nil, fmt.Errorf("unauthorized")
- }
-
- pagination := utils.GetPagination(params)
-
- res, err := db.Provider.ListUsers(ctx, pagination)
- if err != nil {
- log.Debug("Failed to get users: ", err)
- return nil, err
- }
-
- return res, nil
-}
diff --git a/server/resolvers/verification_requests.go b/server/resolvers/verification_requests.go
deleted file mode 100644
index 9a55be7d1..000000000
--- a/server/resolvers/verification_requests.go
+++ /dev/null
@@ -1,37 +0,0 @@
-package resolvers
-
-import (
- "context"
- "fmt"
-
- log "github.com/sirupsen/logrus"
-
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/token"
- "github.com/authorizerdev/authorizer/server/utils"
-)
-
-// VerificationRequestsResolver is a resolver for verification requests query
-// This is admin only query
-func VerificationRequestsResolver(ctx context.Context, params *model.PaginatedInput) (*model.VerificationRequests, error) {
- gc, err := utils.GinContextFromContext(ctx)
- if err != nil {
- log.Debug("Failed to get GinContext: ", err)
- return nil, err
- }
-
- if !token.IsSuperAdmin(gc) {
- log.Debug("Not logged in as super admin")
- return nil, fmt.Errorf("unauthorized")
- }
-
- pagination := utils.GetPagination(params)
- res, err := db.Provider.ListVerificationRequests(ctx, pagination)
- if err != nil {
- log.Debug("Failed to get verification requests: ", err)
- return nil, err
- }
-
- return res, nil
-}
diff --git a/server/resolvers/verify_email.go b/server/resolvers/verify_email.go
deleted file mode 100644
index 3ad399ebc..000000000
--- a/server/resolvers/verify_email.go
+++ /dev/null
@@ -1,224 +0,0 @@
-package resolvers
-
-import (
- "context"
- "fmt"
- "strings"
- "time"
-
- "github.com/google/uuid"
- log "github.com/sirupsen/logrus"
-
- "github.com/authorizerdev/authorizer/server/authenticators"
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/cookie"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/db/models"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/parsers"
- "github.com/authorizerdev/authorizer/server/refs"
- "github.com/authorizerdev/authorizer/server/token"
- "github.com/authorizerdev/authorizer/server/utils"
-)
-
-// VerifyEmailResolver is a resolver for verify email mutation
-func VerifyEmailResolver(ctx context.Context, params model.VerifyEmailInput) (*model.AuthResponse, error) {
- var res *model.AuthResponse
-
- gc, err := utils.GinContextFromContext(ctx)
- if err != nil {
- log.Debug("Failed to get GinContext: ", err)
- return res, err
- }
-
- verificationRequest, err := db.Provider.GetVerificationRequestByToken(ctx, params.Token)
- if err != nil {
- log.Debug("Failed to get verification request by token: ", err)
- return res, fmt.Errorf(`invalid token: %s`, err.Error())
- }
-
- // verify if token exists in db
- hostname := parsers.GetHost(gc)
- claim, err := token.ParseJWTToken(params.Token)
- if err != nil {
- log.Debug("Failed to parse token: ", err)
- return res, fmt.Errorf(`invalid token: %s`, err.Error())
- }
-
- if ok, err := token.ValidateJWTClaims(claim, hostname, verificationRequest.Nonce, verificationRequest.Email); !ok || err != nil {
- log.Debug("Failed to validate jwt claims: ", err)
- return res, fmt.Errorf(`invalid token: %s`, err.Error())
- }
-
- email := claim["sub"].(string)
- log := log.WithFields(log.Fields{
- "email": email,
- })
- user, err := db.Provider.GetUserByEmail(ctx, email)
- if err != nil {
- log.Debug("Failed to get user by email: ", err)
- return res, err
- }
-
- isMFADisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableMultiFactorAuthentication)
- if err != nil || !isMFADisabled {
- log.Debug("MFA service not enabled: ", err)
- }
-
- isTOTPLoginDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableTOTPLogin)
- if err != nil || !isTOTPLoginDisabled {
- log.Debug("totp service not enabled: ", err)
- }
-
- setOTPMFaSession := func(expiresAt int64) error {
- mfaSession := uuid.NewString()
- err = memorystore.Provider.SetMfaSession(user.ID, mfaSession, expiresAt)
- if err != nil {
- log.Debug("Failed to add mfasession: ", err)
- return err
- }
- cookie.SetMfaSession(gc, mfaSession)
- return nil
- }
-
- // If mfa enabled and also totp enabled
- if refs.BoolValue(user.IsMultiFactorAuthEnabled) && !isMFADisabled && !isTOTPLoginDisabled {
- expiresAt := time.Now().Add(3 * time.Minute).Unix()
- if err := setOTPMFaSession(expiresAt); err != nil {
- log.Debug("Failed to set mfa session: ", err)
- return nil, err
- }
- authenticator, err := db.Provider.GetAuthenticatorDetailsByUserId(ctx, user.ID, constants.EnvKeyTOTPAuthenticator)
- if err != nil || authenticator == nil || authenticator.VerifiedAt == nil {
- // generate totp
- // Generate a base64 URL and initiate the registration for TOTP
- authConfig, err := authenticators.Provider.Generate(ctx, user.ID)
- if err != nil {
- log.Debug("error while generating base64 url: ", err)
- return nil, err
- }
- recoveryCodes := []*string{}
- for _, code := range authConfig.RecoveryCodes {
- recoveryCodes = append(recoveryCodes, refs.NewStringRef(code))
- }
- // when user is first time registering for totp
- res = &model.AuthResponse{
- Message: `Proceed to totp verification screen`,
- ShouldShowTotpScreen: refs.NewBoolRef(true),
- AuthenticatorScannerImage: refs.NewStringRef(authConfig.ScannerImage),
- AuthenticatorSecret: refs.NewStringRef(authConfig.Secret),
- AuthenticatorRecoveryCodes: recoveryCodes,
- }
- return res, nil
- } else {
- //when user is already register for totp
- res = &model.AuthResponse{
- Message: `Proceed to totp screen`,
- ShouldShowTotpScreen: refs.NewBoolRef(true),
- }
- return res, nil
- }
- }
-
- isSignUp := false
- if user.EmailVerifiedAt == nil {
- isSignUp = true
- // update email_verified_at in users table
- now := time.Now().Unix()
- user.EmailVerifiedAt = &now
- user, err = db.Provider.UpdateUser(ctx, user)
- if err != nil {
- log.Debug("Failed to update user: ", err)
- return res, err
- }
- }
- // delete from verification table
- err = db.Provider.DeleteVerificationRequest(gc, verificationRequest)
- if err != nil {
- log.Debug("Failed to delete verification request: ", err)
- return res, err
- }
-
- loginMethod := constants.AuthRecipeMethodBasicAuth
- if loginMethod == constants.VerificationTypeMagicLinkLogin {
- loginMethod = constants.AuthRecipeMethodMagicLinkLogin
- }
-
- roles := strings.Split(user.Roles, ",")
- scope := []string{"openid", "email", "profile"}
- code := ""
- // Not required as /oauth/token cannot be resumed from other tab
- // codeChallenge := ""
- nonce := ""
- if params.State != nil {
- // Get state from store
- authorizeState, _ := memorystore.Provider.GetState(refs.StringValue(params.State))
- if authorizeState != "" {
- authorizeStateSplit := strings.Split(authorizeState, "@@")
- if len(authorizeStateSplit) > 1 {
- code = authorizeStateSplit[0]
- // Not required as /oauth/token cannot be resumed from other tab
- // codeChallenge = authorizeStateSplit[1]
- } else {
- nonce = authorizeState
- }
- go memorystore.Provider.RemoveState(refs.StringValue(params.State))
- }
- }
- if nonce == "" {
- nonce = uuid.New().String()
- }
- authToken, err := token.CreateAuthToken(gc, user, roles, scope, loginMethod, nonce, code)
- if err != nil {
- log.Debug("Failed to create auth token: ", err)
- return res, err
- }
-
- // Code challenge could be optional if PKCE flow is not used
- // Not required as /oauth/token cannot be resumed from other tab
- // if code != "" {
- // if err := memorystore.Provider.SetState(code, codeChallenge+"@@"+authToken.FingerPrintHash); err != nil {
- // log.Debug("SetState failed: ", err)
- // return res, err
- // }
- // }
- go func() {
- if isSignUp {
- utils.RegisterEvent(ctx, constants.UserSignUpWebhookEvent, loginMethod, user)
- // User is also logged in with signup
- utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, loginMethod, user)
- } else {
- utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, loginMethod, user)
- }
-
- db.Provider.AddSession(ctx, &models.Session{
- UserID: user.ID,
- UserAgent: utils.GetUserAgent(gc.Request),
- IP: utils.GetIP(gc.Request),
- })
- }()
- expiresIn := authToken.AccessToken.ExpiresAt - time.Now().Unix()
- if expiresIn <= 0 {
- expiresIn = 1
- }
-
- res = &model.AuthResponse{
- Message: `Email verified successfully.`,
- AccessToken: &authToken.AccessToken.Token,
- IDToken: &authToken.IDToken.Token,
- ExpiresIn: &expiresIn,
- User: user.AsAPIUser(),
- }
-
- sessionKey := loginMethod + ":" + user.ID
- cookie.SetSession(gc, authToken.FingerPrintHash)
- memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash, authToken.SessionTokenExpiresAt)
- memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token, authToken.AccessToken.ExpiresAt)
-
- if authToken.RefreshToken != nil {
- res.RefreshToken = &authToken.RefreshToken.Token
- memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token, authToken.RefreshToken.ExpiresAt)
- }
- return res, nil
-}
diff --git a/server/resolvers/verify_otp.go b/server/resolvers/verify_otp.go
deleted file mode 100644
index 16a10c707..000000000
--- a/server/resolvers/verify_otp.go
+++ /dev/null
@@ -1,214 +0,0 @@
-package resolvers
-
-import (
- "context"
- "fmt"
- "strings"
- "time"
-
- "github.com/google/uuid"
- log "github.com/sirupsen/logrus"
-
- "github.com/authorizerdev/authorizer/server/authenticators"
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/cookie"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/db/models"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/refs"
- "github.com/authorizerdev/authorizer/server/token"
- "github.com/authorizerdev/authorizer/server/utils"
-)
-
-// VerifyOtpResolver resolver for verify otp mutation
-func VerifyOtpResolver(ctx context.Context, params model.VerifyOTPRequest) (*model.AuthResponse, error) {
- var res *model.AuthResponse
- gc, err := utils.GinContextFromContext(ctx)
- if err != nil {
- log.Debug("Failed to get GinContext: ", err)
- return res, err
- }
-
- mfaSession, err := cookie.GetMfaSession(gc)
- if err != nil {
- log.Debug("Failed to get otp request by email: ", err)
- return res, fmt.Errorf(`invalid session: %s`, err.Error())
- }
-
- email := strings.TrimSpace(refs.StringValue(params.Email))
- phoneNumber := strings.TrimSpace(refs.StringValue(params.PhoneNumber))
- if email == "" && phoneNumber == "" {
- log.Debug("Email or phone number is required")
- return res, fmt.Errorf(`email or phone number is required`)
- }
- isEmailVerification := email != ""
- isMobileVerification := phoneNumber != ""
- // Get user by email or phone number
- var user *models.User
- if isEmailVerification {
- user, err = db.Provider.GetUserByEmail(ctx, refs.StringValue(params.Email))
- if err != nil {
- log.Debug("Failed to get user by email: ", err)
- }
- } else {
- user, err = db.Provider.GetUserByPhoneNumber(ctx, refs.StringValue(params.PhoneNumber))
- if err != nil {
- log.Debug("Failed to get user by phone number: ", err)
- }
- }
- if user == nil || err != nil {
- return res, fmt.Errorf(`user not found`)
- }
- // Verify OTP based on TOPT or OTP
- if refs.BoolValue(params.IsTotp) {
- status, err := authenticators.Provider.Validate(ctx, params.Otp, user.ID)
- if err != nil {
- log.Debug("Failed to validate totp: ", err)
- return nil, fmt.Errorf("error while validating passcode")
- }
- if !status {
- log.Debug("Failed to verify otp request: Incorrect value")
- log.Info("Checking if otp is recovery code")
- // Check if otp is recovery code
- isValidRecoveryCode, err := authenticators.Provider.ValidateRecoveryCode(ctx, params.Otp, user.ID)
- if err != nil {
- log.Debug("Failed to validate recovery code: ", err)
- return nil, fmt.Errorf("error while validating recovery code")
- }
- if !isValidRecoveryCode {
- log.Debug("Failed to verify otp request: Incorrect value")
- return res, fmt.Errorf(`invalid otp`)
- }
- }
- } else {
- var otp *models.OTP
- if isEmailVerification {
- otp, err = db.Provider.GetOTPByEmail(ctx, refs.StringValue(params.Email))
- if err != nil {
- log.Debug(`Failed to get otp request for email: `, err.Error())
- }
- } else {
- otp, err = db.Provider.GetOTPByPhoneNumber(ctx, refs.StringValue(params.PhoneNumber))
- if err != nil {
- log.Debug(`Failed to get otp request for phone number: `, err.Error())
- }
- }
- if otp == nil && err != nil {
- return res, fmt.Errorf(`OTP not found`)
- }
- if params.Otp != otp.Otp {
- log.Debug("Failed to verify otp request: Incorrect value")
- return res, fmt.Errorf(`invalid otp`)
- }
- expiresIn := otp.ExpiresAt - time.Now().Unix()
- if expiresIn < 0 {
- log.Debug("Failed to verify otp request: Timeout")
- return res, fmt.Errorf("otp expired")
- }
- db.Provider.DeleteOTP(gc, otp)
- }
-
- if _, err := memorystore.Provider.GetMfaSession(user.ID, mfaSession); err != nil {
- log.Debug("Failed to get mfa session: ", err)
- return res, fmt.Errorf(`invalid session: %s`, err.Error())
- }
-
- isSignUp := false
- if user.EmailVerifiedAt == nil && isEmailVerification {
- isSignUp = true
- now := time.Now().Unix()
- user.EmailVerifiedAt = &now
- }
- if user.PhoneNumberVerifiedAt == nil && isMobileVerification {
- isSignUp = true
- now := time.Now().Unix()
- user.PhoneNumberVerifiedAt = &now
- }
- if isSignUp {
- user, err = db.Provider.UpdateUser(ctx, user)
- if err != nil {
- log.Debug("Failed to update user: ", err)
- return res, err
- }
- }
- loginMethod := constants.AuthRecipeMethodBasicAuth
- if isMobileVerification {
- loginMethod = constants.AuthRecipeMethodMobileOTP
- }
- roles := strings.Split(user.Roles, ",")
- scope := []string{"openid", "email", "profile"}
- code := ""
- codeChallenge := ""
- nonce := ""
- if params.State != nil {
- // Get state from store
- authorizeState, _ := memorystore.Provider.GetState(refs.StringValue(params.State))
- if authorizeState != "" {
- authorizeStateSplit := strings.Split(authorizeState, "@@")
- if len(authorizeStateSplit) > 1 {
- code = authorizeStateSplit[0]
- codeChallenge = authorizeStateSplit[1]
- } else {
- nonce = authorizeState
- }
- go memorystore.Provider.RemoveState(refs.StringValue(params.State))
- }
- }
- if nonce == "" {
- nonce = uuid.New().String()
- }
- authToken, err := token.CreateAuthToken(gc, user, roles, scope, loginMethod, nonce, code)
- if err != nil {
- log.Debug("Failed to create auth token: ", err)
- return res, err
- }
-
- // Code challenge could be optional if PKCE flow is not used
- if code != "" {
- if err := memorystore.Provider.SetState(code, codeChallenge+"@@"+authToken.FingerPrintHash); err != nil {
- log.Debug("Failed to set code state: ", err)
- return res, err
- }
- }
-
- go func() {
- if isSignUp {
- utils.RegisterEvent(ctx, constants.UserSignUpWebhookEvent, loginMethod, user)
- // User is also logged in with signup
- utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, loginMethod, user)
- } else {
- utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, loginMethod, user)
- }
-
- db.Provider.AddSession(ctx, &models.Session{
- UserID: user.ID,
- UserAgent: utils.GetUserAgent(gc.Request),
- IP: utils.GetIP(gc.Request),
- })
- }()
-
- authTokenExpiresIn := authToken.AccessToken.ExpiresAt - time.Now().Unix()
- if authTokenExpiresIn <= 0 {
- authTokenExpiresIn = 1
- }
-
- res = &model.AuthResponse{
- Message: `OTP verified successfully.`,
- AccessToken: &authToken.AccessToken.Token,
- IDToken: &authToken.IDToken.Token,
- ExpiresIn: &authTokenExpiresIn,
- User: user.AsAPIUser(),
- }
-
- sessionKey := loginMethod + ":" + user.ID
- cookie.SetSession(gc, authToken.FingerPrintHash)
- memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash, authToken.SessionTokenExpiresAt)
- memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token, authToken.AccessToken.ExpiresAt)
-
- if authToken.RefreshToken != nil {
- res.RefreshToken = &authToken.RefreshToken.Token
- memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token, authToken.RefreshToken.ExpiresAt)
- }
- return res, nil
-}
diff --git a/server/resolvers/webhook.go b/server/resolvers/webhook.go
deleted file mode 100644
index d547e7983..000000000
--- a/server/resolvers/webhook.go
+++ /dev/null
@@ -1,33 +0,0 @@
-package resolvers
-
-import (
- "context"
- "fmt"
-
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/token"
- "github.com/authorizerdev/authorizer/server/utils"
- log "github.com/sirupsen/logrus"
-)
-
-// WebhookResolver resolver for getting webhook by identifier
-func WebhookResolver(ctx context.Context, params model.WebhookRequest) (*model.Webhook, error) {
- gc, err := utils.GinContextFromContext(ctx)
- if err != nil {
- log.Debug("Failed to get GinContext: ", err)
- return nil, err
- }
-
- if !token.IsSuperAdmin(gc) {
- log.Debug("Not logged in as super admin")
- return nil, fmt.Errorf("unauthorized")
- }
-
- webhook, err := db.Provider.GetWebhookByID(ctx, params.ID)
- if err != nil {
- log.Debug("error getting webhook: ", err)
- return nil, err
- }
- return webhook, nil
-}
diff --git a/server/resolvers/webhook_logs.go b/server/resolvers/webhook_logs.go
deleted file mode 100644
index cd7b62d6b..000000000
--- a/server/resolvers/webhook_logs.go
+++ /dev/null
@@ -1,47 +0,0 @@
-package resolvers
-
-import (
- "context"
- "fmt"
-
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/refs"
- "github.com/authorizerdev/authorizer/server/token"
- "github.com/authorizerdev/authorizer/server/utils"
- log "github.com/sirupsen/logrus"
-)
-
-// WebhookLogsResolver resolver for getting the list of webhook_logs based on pagination & webhook identifier
-func WebhookLogsResolver(ctx context.Context, params *model.ListWebhookLogRequest) (*model.WebhookLogs, error) {
- gc, err := utils.GinContextFromContext(ctx)
- if err != nil {
- log.Debug("Failed to get GinContext: ", err)
- return nil, err
- }
-
- if !token.IsSuperAdmin(gc) {
- log.Debug("Not logged in as super admin")
- return nil, fmt.Errorf("unauthorized")
- }
-
- var pagination *model.Pagination
- var webhookID string
-
- if params != nil {
- pagination = utils.GetPagination(&model.PaginatedInput{
- Pagination: params.Pagination,
- })
- webhookID = refs.StringValue(params.WebhookID)
- } else {
- pagination = utils.GetPagination(nil)
- webhookID = ""
- }
- // TODO fix
- webhookLogs, err := db.Provider.ListWebhookLogs(ctx, pagination, webhookID)
- if err != nil {
- log.Debug("failed to get webhook logs: ", err)
- return nil, err
- }
- return webhookLogs, nil
-}
diff --git a/server/resolvers/webhooks.go b/server/resolvers/webhooks.go
deleted file mode 100644
index 733df821b..000000000
--- a/server/resolvers/webhooks.go
+++ /dev/null
@@ -1,34 +0,0 @@
-package resolvers
-
-import (
- "context"
- "fmt"
-
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/token"
- "github.com/authorizerdev/authorizer/server/utils"
- log "github.com/sirupsen/logrus"
-)
-
-// WebhooksResolver resolver for getting the list of webhooks based on pagination
-func WebhooksResolver(ctx context.Context, params *model.PaginatedInput) (*model.Webhooks, error) {
- gc, err := utils.GinContextFromContext(ctx)
- if err != nil {
- log.Debug("Failed to get GinContext: ", err)
- return nil, err
- }
-
- if !token.IsSuperAdmin(gc) {
- log.Debug("Not logged in as super admin")
- return nil, fmt.Errorf("unauthorized")
- }
-
- pagination := utils.GetPagination(params)
- webhooks, err := db.Provider.ListWebhook(ctx, pagination)
- if err != nil {
- log.Debug("failed to get webhooks: ", err)
- return nil, err
- }
- return webhooks, nil
-}
diff --git a/server/routes/routes.go b/server/routes/routes.go
deleted file mode 100644
index 0f25a0288..000000000
--- a/server/routes/routes.go
+++ /dev/null
@@ -1,58 +0,0 @@
-package routes
-
-import (
- "github.com/gin-gonic/gin"
- "github.com/sirupsen/logrus"
-
- "github.com/authorizerdev/authorizer/server/handlers"
- "github.com/authorizerdev/authorizer/server/middlewares"
-)
-
-// InitRouter initializes gin router
-func InitRouter(log *logrus.Logger) *gin.Engine {
- gin.SetMode(gin.ReleaseMode)
- router := gin.New()
-
- router.Use(middlewares.Logger(log), gin.Recovery())
- router.Use(middlewares.GinContextToContextMiddleware())
- router.Use(middlewares.CORSMiddleware())
- router.Use(middlewares.ClientCheckMiddleware())
-
- router.GET("/", handlers.RootHandler())
- router.GET("/health", handlers.HealthHandler())
- router.POST("/graphql", handlers.GraphqlHandler())
- router.GET("/playground", handlers.PlaygroundHandler())
- router.GET("/oauth_login/:oauth_provider", handlers.OAuthLoginHandler())
- router.GET("/oauth_callback/:oauth_provider", handlers.OAuthCallbackHandler())
- router.POST("/oauth_callback/:oauth_provider", handlers.OAuthCallbackHandler())
- router.GET("/verify_email", handlers.VerifyEmailHandler())
- // OPEN ID routes
- router.GET("/.well-known/openid-configuration", handlers.OpenIDConfigurationHandler())
- router.GET("/.well-known/jwks.json", handlers.JWKsHandler())
- router.GET("/authorize", handlers.AuthorizeHandler())
- router.GET("/userinfo", handlers.UserInfoHandler())
- router.GET("/logout", handlers.LogoutHandler())
- router.POST("/oauth/token", handlers.TokenHandler())
- router.POST("/oauth/revoke", handlers.RevokeRefreshTokenHandler())
-
- router.LoadHTMLGlob("templates/*")
- // login page app related routes.
- app := router.Group("/app")
- {
- app.Static("/favicon_io", "app/favicon_io")
- app.Static("/build", "app/build")
- app.GET("/", handlers.AppHandler())
- app.GET("/:page", handlers.AppHandler())
- }
-
- // dashboard related routes
- dashboard := router.Group("/dashboard")
- {
- dashboard.Static("/favicon_io", "dashboard/favicon_io")
- dashboard.Static("/build", "dashboard/build")
- dashboard.Static("/public", "dashboard/public")
- dashboard.GET("/", handlers.DashboardHandler())
- dashboard.GET("/:page", handlers.DashboardHandler())
- }
- return router
-}
diff --git a/server/smsproviders/twilio.go b/server/smsproviders/twilio.go
deleted file mode 100644
index f4f1acb90..000000000
--- a/server/smsproviders/twilio.go
+++ /dev/null
@@ -1,49 +0,0 @@
-package smsproviders
-
-import (
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/memorystore"
- log "github.com/sirupsen/logrus"
- twilio "github.com/twilio/twilio-go"
- api "github.com/twilio/twilio-go/rest/api/v2010"
-)
-
-// SendSMS util to send sms
-// TODO: Should be restructured to interface when another provider is added
-func SendSMS(sendTo, messageBody string) error {
- twilioAPISecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyTwilioAPISecret)
- if err != nil || twilioAPISecret == "" {
- log.Debug("Failed to get api secret: ", err)
- return err
- }
- twilioAPIKey, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyTwilioAPIKey)
- if err != nil || twilioAPIKey == "" {
- log.Debug("Failed to get api key: ", err)
- return err
- }
- twilioSenderFrom, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyTwilioSender)
- if err != nil || twilioSenderFrom == "" {
- log.Debug("Failed to get sender: ", err)
- return err
- }
- // accountSID is not a must to send sms on twilio
- twilioAccountSID, _ := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyTwilioAccountSID)
- client := twilio.NewRestClientWithParams(twilio.ClientParams{
- Username: twilioAPIKey,
- Password: twilioAPISecret,
- AccountSid: twilioAccountSID,
- })
- message := &api.CreateMessageParams{}
- message.SetBody(messageBody)
- message.SetFrom(twilioSenderFrom)
- message.SetTo(sendTo)
-
- _, err = client.Api.CreateMessage(message)
-
- if err != nil {
- log.Debug("Failed to send sms: ", err)
- return err
- }
-
- return nil
-}
diff --git a/server/test/add_email_template_test.go b/server/test/add_email_template_test.go
deleted file mode 100644
index 4af66090b..000000000
--- a/server/test/add_email_template_test.go
+++ /dev/null
@@ -1,76 +0,0 @@
-package test
-
-import (
- "fmt"
- "testing"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/crypto"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/resolvers"
- "github.com/stretchr/testify/assert"
-)
-
-func addEmailTemplateTest(t *testing.T, s TestSetup) {
- t.Helper()
- t.Run("should add email templates", func(t *testing.T) {
- req, ctx := createContext(s)
- adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
- assert.NoError(t, err)
- h, err := crypto.EncryptPassword(adminSecret)
- assert.NoError(t, err)
- req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
-
- t.Run("should not add email template for invalid event type", func(t *testing.T) {
- emailTemplate, err := resolvers.AddEmailTemplateResolver(ctx, model.AddEmailTemplateRequest{
- EventName: "test",
- })
- assert.Error(t, err)
- assert.Nil(t, emailTemplate)
- })
-
- t.Run("should not add email template for empty subject", func(t *testing.T) {
- emailTemplate, err := resolvers.AddEmailTemplateResolver(ctx, model.AddEmailTemplateRequest{
- EventName: s.TestInfo.TestEmailTemplateEventTypes[0],
- Template: " test ",
- Subject: " ",
- })
- assert.Error(t, err)
- assert.Nil(t, emailTemplate)
- })
-
- t.Run("should not add email template for empty template", func(t *testing.T) {
- emailTemplate, err := resolvers.AddEmailTemplateResolver(ctx, model.AddEmailTemplateRequest{
- EventName: s.TestInfo.TestEmailTemplateEventTypes[0],
- Template: " ",
- Subject: "test",
- })
- assert.Error(t, err)
- assert.Nil(t, emailTemplate)
- })
-
- design := ""
-
- for _, eventType := range s.TestInfo.TestEmailTemplateEventTypes {
- t.Run("should add email template with empty design for "+eventType, func(t *testing.T) {
- emailTemplate, err := resolvers.AddEmailTemplateResolver(ctx, model.AddEmailTemplateRequest{
- EventName: eventType,
- Template: "Test email",
- Subject: "Test email",
- Design: &design,
- })
- assert.NoError(t, err)
- assert.NotNil(t, emailTemplate)
- assert.NotEmpty(t, emailTemplate.Message)
-
- et, err := db.Provider.GetEmailTemplateByEventName(ctx, eventType)
- assert.NoError(t, err)
- assert.Equal(t, et.EventName, eventType)
- assert.Equal(t, "Test email", et.Subject)
- assert.Equal(t, "", et.Design)
- })
- }
- })
-}
diff --git a/server/test/add_webhook_test.go b/server/test/add_webhook_test.go
deleted file mode 100644
index 500049f55..000000000
--- a/server/test/add_webhook_test.go
+++ /dev/null
@@ -1,56 +0,0 @@
-package test
-
-import (
- "fmt"
- "testing"
- "time"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/crypto"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/refs"
- "github.com/authorizerdev/authorizer/server/resolvers"
- "github.com/stretchr/testify/assert"
-)
-
-func addWebhookTest(t *testing.T, s TestSetup) {
- t.Helper()
- t.Run("should add webhook", func(t *testing.T) {
- req, ctx := createContext(s)
- adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
- assert.NoError(t, err)
- h, err := crypto.EncryptPassword(adminSecret)
- assert.NoError(t, err)
- req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
- for _, eventType := range s.TestInfo.TestWebhookEventTypes {
- webhook, err := resolvers.AddWebhookResolver(ctx, model.AddWebhookRequest{
- EventName: eventType,
- Endpoint: s.TestInfo.WebhookEndpoint,
- Enabled: true,
- Headers: map[string]interface{}{
- "x-test": "foo",
- },
- })
- assert.NoError(t, err)
- assert.NotNil(t, webhook)
- assert.NotEmpty(t, webhook.Message)
- }
- time.Sleep(2 * time.Second)
- // Allow setting multiple webhooks for same event
- for _, eventType := range s.TestInfo.TestWebhookEventTypes {
- webhook, err := resolvers.AddWebhookResolver(ctx, model.AddWebhookRequest{
- EventName: eventType,
- Endpoint: s.TestInfo.WebhookEndpoint,
- Enabled: true,
- EventDescription: refs.NewStringRef(eventType + "-2"),
- Headers: map[string]interface{}{
- "x-test": "foo",
- },
- })
- assert.NoError(t, err)
- assert.NotNil(t, webhook)
- assert.NotEmpty(t, webhook.Message)
- }
- })
-}
diff --git a/server/test/admin_login_test.go b/server/test/admin_login_test.go
deleted file mode 100644
index 4b8cc8516..000000000
--- a/server/test/admin_login_test.go
+++ /dev/null
@@ -1,31 +0,0 @@
-package test
-
-import (
- "testing"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/resolvers"
- "github.com/stretchr/testify/assert"
-)
-
-func adminLoginTests(t *testing.T, s TestSetup) {
- t.Helper()
- t.Run(`should complete admin login`, func(t *testing.T) {
- _, ctx := createContext(s)
- _, err := resolvers.AdminLoginResolver(ctx, model.AdminLoginInput{
- AdminSecret: "admin_test",
- })
-
- assert.NotNil(t, err)
-
- adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
- assert.Nil(t, err)
- _, err = resolvers.AdminLoginResolver(ctx, model.AdminLoginInput{
- AdminSecret: adminSecret,
- })
-
- assert.Nil(t, err)
- })
-}
diff --git a/server/test/admin_logout_test.go b/server/test/admin_logout_test.go
deleted file mode 100644
index d37b1405e..000000000
--- a/server/test/admin_logout_test.go
+++ /dev/null
@@ -1,31 +0,0 @@
-package test
-
-import (
- "fmt"
- "testing"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/crypto"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/resolvers"
- "github.com/stretchr/testify/assert"
-)
-
-func adminLogoutTests(t *testing.T, s TestSetup) {
- t.Helper()
- t.Run(`should get admin session`, func(t *testing.T) {
- req, ctx := createContext(s)
- _, err := resolvers.AdminLogoutResolver(ctx)
- assert.NotNil(t, err)
-
- adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
- assert.Nil(t, err)
-
- h, err := crypto.EncryptPassword(adminSecret)
- assert.Nil(t, err)
- req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
- _, err = resolvers.AdminLogoutResolver(ctx)
-
- assert.Nil(t, err)
- })
-}
diff --git a/server/test/admin_session_test.go b/server/test/admin_session_test.go
deleted file mode 100644
index fb28c96e5..000000000
--- a/server/test/admin_session_test.go
+++ /dev/null
@@ -1,31 +0,0 @@
-package test
-
-import (
- "fmt"
- "testing"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/crypto"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/resolvers"
- "github.com/stretchr/testify/assert"
-)
-
-func adminSessionTests(t *testing.T, s TestSetup) {
- t.Helper()
- t.Run(`should get admin session`, func(t *testing.T) {
- req, ctx := createContext(s)
- _, err := resolvers.AdminSessionResolver(ctx)
- assert.NotNil(t, err)
-
- adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
- assert.Nil(t, err)
-
- h, err := crypto.EncryptPassword(adminSecret)
- assert.Nil(t, err)
- req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
- _, err = resolvers.AdminSessionResolver(ctx)
-
- assert.Nil(t, err)
- })
-}
diff --git a/server/test/admin_signup_test.go b/server/test/admin_signup_test.go
deleted file mode 100644
index 9e425532b..000000000
--- a/server/test/admin_signup_test.go
+++ /dev/null
@@ -1,29 +0,0 @@
-package test
-
-import (
- "testing"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/resolvers"
- "github.com/stretchr/testify/assert"
-)
-
-func adminSignupTests(t *testing.T, s TestSetup) {
- t.Helper()
- t.Run(`should complete admin signup`, func(t *testing.T) {
- _, ctx := createContext(s)
- _, err := resolvers.AdminSignupResolver(ctx, model.AdminSignupInput{
- AdminSecret: "admin",
- })
- assert.NotNil(t, err)
- // reset env for test to pass
- err = memorystore.Provider.UpdateEnvVariable(constants.EnvKeyAdminSecret, "")
- assert.Nil(t, err)
- _, err = resolvers.AdminSignupResolver(ctx, model.AdminSignupInput{
- AdminSecret: "admin123",
- })
- assert.NoError(t, err)
- })
-}
diff --git a/server/test/cors_test.go b/server/test/cors_test.go
deleted file mode 100644
index 0dc5c777c..000000000
--- a/server/test/cors_test.go
+++ /dev/null
@@ -1,27 +0,0 @@
-package test
-
-import (
- "net/http"
- "testing"
-
- "github.com/stretchr/testify/assert"
-)
-
-func TestCors(t *testing.T) {
- allowedOrigin := "http://localhost:8080" // The allowed origin that you want to check
- notAllowedOrigin := "http://myapp.com"
-
- s := testSetup()
- defer s.Server.Close()
- client := &http.Client{}
-
- req, _ := createContext(s)
- req.Header.Add("Origin", allowedOrigin)
- res, _ := client.Do(req)
-
- // You should get your origin (or a * depending on your config) if the
- // passed origin is allowed.
- o := res.Header.Get("Access-Control-Allow-Origin")
- assert.NotEqual(t, o, notAllowedOrigin, "Origins should not match")
- assert.Equal(t, o, allowedOrigin, "Origins do match")
-}
diff --git a/server/test/deactivate_account_test.go b/server/test/deactivate_account_test.go
deleted file mode 100644
index 665c5ccc4..000000000
--- a/server/test/deactivate_account_test.go
+++ /dev/null
@@ -1,46 +0,0 @@
-package test
-
-import (
- "context"
- "testing"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/refs"
- "github.com/authorizerdev/authorizer/server/resolvers"
- "github.com/stretchr/testify/assert"
-)
-
-func deactivateAccountTests(t *testing.T, s TestSetup) {
- t.Helper()
- t.Run(`should deactiavte the user account with access token only`, func(t *testing.T) {
- req, ctx := createContext(s)
- email := "deactiavte_account." + s.TestInfo.Email
-
- resolvers.SignupResolver(ctx, model.SignUpInput{
- Email: refs.NewStringRef(email),
- Password: s.TestInfo.Password,
- ConfirmPassword: s.TestInfo.Password,
- })
- _, err := resolvers.DeactivateAccountResolver(ctx)
- assert.NotNil(t, err, "unauthorized")
- verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeBasicAuthSignup)
- assert.NoError(t, err)
- assert.NotNil(t, verificationRequest)
- verifyRes, err := resolvers.VerifyEmailResolver(ctx, model.VerifyEmailInput{
- Token: verificationRequest.Token,
- })
- assert.NoError(t, err)
- assert.NotNil(t, verifyRes)
- s.GinContext.Request.Header.Set("Authorization", "Bearer "+*verifyRes.AccessToken)
- ctx = context.WithValue(req.Context(), "GinContextKey", s.GinContext)
- _, err = resolvers.DeactivateAccountResolver(ctx)
- assert.NoError(t, err)
- s.GinContext.Request.Header.Set("Authorization", "")
- assert.Nil(t, err)
- _, err = resolvers.ProfileResolver(ctx)
- assert.NotNil(t, err, "unauthorized")
- cleanData(email)
- })
-}
diff --git a/server/test/delete_email_template_test.go b/server/test/delete_email_template_test.go
deleted file mode 100644
index c32b6d5b6..000000000
--- a/server/test/delete_email_template_test.go
+++ /dev/null
@@ -1,52 +0,0 @@
-package test
-
-import (
- "fmt"
- "testing"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/crypto"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/resolvers"
- "github.com/stretchr/testify/assert"
-)
-
-func deleteEmailTemplateTest(t *testing.T, s TestSetup) {
- t.Helper()
- t.Run("should delete email templates", func(t *testing.T) {
- req, ctx := createContext(s)
- adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
- assert.NoError(t, err)
- h, err := crypto.EncryptPassword(adminSecret)
- assert.NoError(t, err)
- req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
-
- // get all email templates
- emailTemplates, err := db.Provider.ListEmailTemplate(ctx, &model.Pagination{
- Limit: 10,
- Page: 1,
- Offset: 0,
- })
- assert.NoError(t, err)
-
- for _, e := range emailTemplates.EmailTemplates {
- res, err := resolvers.DeleteEmailTemplateResolver(ctx, model.DeleteEmailTemplateRequest{
- ID: e.ID,
- })
-
- assert.NoError(t, err)
- assert.NotNil(t, res)
- assert.NotEmpty(t, res.Message)
- }
-
- emailTemplates, err = db.Provider.ListEmailTemplate(ctx, &model.Pagination{
- Limit: 10,
- Page: 1,
- Offset: 0,
- })
- assert.NoError(t, err)
- assert.Len(t, emailTemplates.EmailTemplates, 0)
- })
-}
diff --git a/server/test/delete_user_test.go b/server/test/delete_user_test.go
deleted file mode 100644
index 94957f0e8..000000000
--- a/server/test/delete_user_test.go
+++ /dev/null
@@ -1,44 +0,0 @@
-package test
-
-import (
- "fmt"
- "testing"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/crypto"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/refs"
- "github.com/authorizerdev/authorizer/server/resolvers"
- "github.com/stretchr/testify/assert"
-)
-
-func deleteUserTest(t *testing.T, s TestSetup) {
- t.Helper()
- t.Run(`should delete users with admin secret only`, func(t *testing.T) {
- req, ctx := createContext(s)
- email := "delete_user." + s.TestInfo.Email
- resolvers.SignupResolver(ctx, model.SignUpInput{
- Email: refs.NewStringRef(email),
- Password: s.TestInfo.Password,
- ConfirmPassword: s.TestInfo.Password,
- })
-
- _, err := resolvers.DeleteUserResolver(ctx, model.DeleteUserInput{
- Email: email,
- })
- assert.NotNil(t, err, "unauthorized")
- adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
- assert.Nil(t, err)
-
- h, err := crypto.EncryptPassword(adminSecret)
- assert.Nil(t, err)
- req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
-
- _, err = resolvers.DeleteUserResolver(ctx, model.DeleteUserInput{
- Email: email,
- })
- assert.Nil(t, err)
- cleanData(email)
- })
-}
diff --git a/server/test/delete_webhook_test.go b/server/test/delete_webhook_test.go
deleted file mode 100644
index 3404a4258..000000000
--- a/server/test/delete_webhook_test.go
+++ /dev/null
@@ -1,59 +0,0 @@
-package test
-
-import (
- "fmt"
- "testing"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/crypto"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/resolvers"
- "github.com/stretchr/testify/assert"
-)
-
-func deleteWebhookTest(t *testing.T, s TestSetup) {
- t.Helper()
- t.Run("should delete webhook", func(t *testing.T) {
- req, ctx := createContext(s)
- adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
- assert.NoError(t, err)
- h, err := crypto.EncryptPassword(adminSecret)
- assert.NoError(t, err)
- req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
-
- // get all webhooks
- webhooks, err := db.Provider.ListWebhook(ctx, &model.Pagination{
- Limit: 20,
- Page: 1,
- Offset: 0,
- })
- assert.NoError(t, err)
-
- for _, w := range webhooks.Webhooks {
- res, err := resolvers.DeleteWebhookResolver(ctx, model.WebhookRequest{
- ID: w.ID,
- })
-
- assert.NoError(t, err)
- assert.NotNil(t, res)
- assert.NotEmpty(t, res.Message)
- }
-
- webhooks, err = db.Provider.ListWebhook(ctx, &model.Pagination{
- Limit: 20,
- Page: 1,
- Offset: 0,
- })
- assert.NoError(t, err)
- assert.Len(t, webhooks.Webhooks, 0)
- webhookLogs, err := db.Provider.ListWebhookLogs(ctx, &model.Pagination{
- Limit: 100,
- Page: 1,
- Offset: 0,
- }, "")
- assert.NoError(t, err)
- assert.Len(t, webhookLogs.WebhookLogs, 0)
- })
-}
diff --git a/server/test/email_templates_test.go b/server/test/email_templates_test.go
deleted file mode 100644
index b5c908386..000000000
--- a/server/test/email_templates_test.go
+++ /dev/null
@@ -1,29 +0,0 @@
-package test
-
-import (
- "fmt"
- "testing"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/crypto"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/resolvers"
- "github.com/stretchr/testify/assert"
-)
-
-func emailTemplatesTest(t *testing.T, s TestSetup) {
- t.Helper()
- t.Run("should get email templates", func(t *testing.T) {
- req, ctx := createContext(s)
- adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
- assert.NoError(t, err)
- h, err := crypto.EncryptPassword(adminSecret)
- assert.NoError(t, err)
- req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
-
- emailTemplates, err := resolvers.EmailTemplatesResolver(ctx, nil)
- assert.NoError(t, err)
- assert.NotEmpty(t, emailTemplates)
- assert.Len(t, emailTemplates.EmailTemplates, len(s.TestInfo.TestEmailTemplateEventTypes))
- })
-}
diff --git a/server/test/enable_access_test.go b/server/test/enable_access_test.go
deleted file mode 100644
index 9549968b3..000000000
--- a/server/test/enable_access_test.go
+++ /dev/null
@@ -1,60 +0,0 @@
-package test
-
-import (
- "fmt"
- "testing"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/crypto"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/resolvers"
- "github.com/stretchr/testify/assert"
-)
-
-func enableAccessTest(t *testing.T, s TestSetup) {
- t.Helper()
- t.Run(`should enable access`, func(t *testing.T) {
- req, ctx := createContext(s)
- email := "enable_access." + s.TestInfo.Email
- _, err := resolvers.MagicLinkLoginResolver(ctx, model.MagicLinkLoginInput{
- Email: email,
- })
- assert.NoError(t, err)
- verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeMagicLinkLogin)
- assert.NoError(t, err)
- assert.NotNil(t, verificationRequest)
- verifyRes, err := resolvers.VerifyEmailResolver(ctx, model.VerifyEmailInput{
- Token: verificationRequest.Token,
- })
- assert.NoError(t, err)
- assert.NotNil(t, verifyRes.AccessToken)
- adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
- assert.Nil(t, err)
- h, err := crypto.EncryptPassword(adminSecret)
- assert.Nil(t, err)
- req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
-
- res, err := resolvers.RevokeAccessResolver(ctx, model.UpdateAccessInput{
- UserID: verifyRes.User.ID,
- })
- assert.NoError(t, err)
- assert.NotEmpty(t, res.Message)
-
- res, err = resolvers.EnableAccessResolver(ctx, model.UpdateAccessInput{
- UserID: verifyRes.User.ID,
- })
- assert.NoError(t, err)
- assert.NotEmpty(t, res.Message)
-
- // it should allow login with enabled access
- res, err = resolvers.MagicLinkLoginResolver(ctx, model.MagicLinkLoginInput{
- Email: email,
- })
- assert.Nil(t, err)
- assert.NotEmpty(t, res.Message)
-
- cleanData(email)
- })
-}
diff --git a/server/test/env_file_test.go b/server/test/env_file_test.go
deleted file mode 100644
index 31d5c7024..000000000
--- a/server/test/env_file_test.go
+++ /dev/null
@@ -1,33 +0,0 @@
-package test
-
-import (
- "os"
- "testing"
-
- "github.com/stretchr/testify/assert"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/env"
- "github.com/authorizerdev/authorizer/server/memorystore"
-)
-
-func TestEnvs(t *testing.T) {
- err := os.Setenv(constants.EnvKeyEnvPath, "../../.env.test")
- assert.Nil(t, err)
- err = memorystore.InitRequiredEnv()
- assert.Nil(t, err)
- err = env.InitAllEnv()
- assert.Nil(t, err)
- store, err := memorystore.Provider.GetEnvStore()
- assert.Nil(t, err)
-
- assert.Equal(t, "test", store[constants.EnvKeyEnv].(string))
- assert.False(t, store[constants.EnvKeyDisableEmailVerification].(bool))
- assert.False(t, store[constants.EnvKeyDisableMagicLinkLogin].(bool))
- assert.False(t, store[constants.EnvKeyDisableBasicAuthentication].(bool))
- assert.Equal(t, "RS256", store[constants.EnvKeyJwtType].(string))
- assert.Equal(t, store[constants.EnvKeyJwtRoleClaim].(string), "role")
- assert.EqualValues(t, store[constants.EnvKeyRoles].(string), "user")
- assert.EqualValues(t, store[constants.EnvKeyDefaultRoles].(string), "user")
- assert.EqualValues(t, store[constants.EnvKeyAllowedOrigins].(string), "*")
-}
diff --git a/server/test/env_test.go b/server/test/env_test.go
deleted file mode 100644
index 725a8341d..000000000
--- a/server/test/env_test.go
+++ /dev/null
@@ -1,31 +0,0 @@
-package test
-
-import (
- "fmt"
- "testing"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/crypto"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/resolvers"
- "github.com/stretchr/testify/assert"
-)
-
-func envTests(t *testing.T, s TestSetup) {
- t.Helper()
- t.Run(`should get envs`, func(t *testing.T) {
- req, ctx := createContext(s)
- _, err := resolvers.EnvResolver(ctx)
- assert.NotNil(t, err)
-
- adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
- assert.Nil(t, err)
-
- h, err := crypto.EncryptPassword(adminSecret)
- assert.Nil(t, err)
- req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
- res, err := resolvers.EnvResolver(ctx)
- assert.Nil(t, err)
- assert.Equal(t, *res.AdminSecret, adminSecret)
- })
-}
diff --git a/server/test/forgot_password_mobile_test.go b/server/test/forgot_password_mobile_test.go
deleted file mode 100644
index 276027975..000000000
--- a/server/test/forgot_password_mobile_test.go
+++ /dev/null
@@ -1,61 +0,0 @@
-package test
-
-import (
- "fmt"
- "strings"
- "testing"
- "time"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/refs"
- "github.com/authorizerdev/authorizer/server/resolvers"
- "github.com/google/uuid"
- "github.com/stretchr/testify/assert"
-)
-
-func forgotPasswordMobileTest(t *testing.T, s TestSetup) {
- t.Helper()
- t.Run(`should run forgot password for mobile`, func(t *testing.T) {
- req, ctx := createContext(s)
- phoneNumber := "6240345678"
- res, err := resolvers.SignupResolver(ctx, model.SignUpInput{
- PhoneNumber: refs.NewStringRef(phoneNumber),
- Password: s.TestInfo.Password,
- ConfirmPassword: s.TestInfo.Password,
- })
- assert.NoError(t, err)
- assert.NotNil(t, res)
- forgotPasswordRes, err := resolvers.ForgotPasswordResolver(ctx, model.ForgotPasswordInput{
- PhoneNumber: refs.NewStringRef(phoneNumber),
- })
- assert.Nil(t, err, "no errors for forgot password")
- assert.NotNil(t, forgotPasswordRes)
- assert.True(t, *forgotPasswordRes.ShouldShowMobileOtpScreen)
- otpReq, err := db.Provider.GetOTPByPhoneNumber(ctx, phoneNumber)
- assert.Nil(t, err)
- mfaSession := uuid.NewString()
- memorystore.Provider.SetMfaSession(res.User.ID, mfaSession, time.Now().Add(1*time.Minute).Unix())
- cookie := fmt.Sprintf("%s=%s;", constants.MfaCookieName+"_session", mfaSession)
- cookie = strings.TrimSuffix(cookie, ";")
- req.Header.Set("Cookie", cookie)
- // Reset password
- resetPasswordRes, err := resolvers.ResetPasswordResolver(ctx, model.ResetPasswordInput{
- PhoneNumber: refs.NewStringRef(phoneNumber),
- Otp: refs.NewStringRef(otpReq.Otp),
- Password: s.TestInfo.Password + "test",
- ConfirmPassword: s.TestInfo.Password + "test",
- })
- assert.Nil(t, err)
- assert.NotNil(t, resetPasswordRes)
- // Test login
- loginRes, err := resolvers.LoginResolver(ctx, model.LoginInput{
- PhoneNumber: refs.NewStringRef(phoneNumber),
- Password: s.TestInfo.Password + "test",
- })
- assert.Nil(t, err)
- assert.NotNil(t, loginRes)
- })
-}
diff --git a/server/test/forgot_password_test.go b/server/test/forgot_password_test.go
deleted file mode 100644
index dd9165af0..000000000
--- a/server/test/forgot_password_test.go
+++ /dev/null
@@ -1,38 +0,0 @@
-package test
-
-import (
- "testing"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/refs"
- "github.com/authorizerdev/authorizer/server/resolvers"
- "github.com/stretchr/testify/assert"
-)
-
-func forgotPasswordTest(t *testing.T, s TestSetup) {
- t.Helper()
- t.Run(`should run forgot password`, func(t *testing.T) {
- _, ctx := createContext(s)
- email := "forgot_password." + s.TestInfo.Email
- res, err := resolvers.SignupResolver(ctx, model.SignUpInput{
- Email: refs.NewStringRef(email),
- Password: s.TestInfo.Password,
- ConfirmPassword: s.TestInfo.Password,
- })
- assert.NoError(t, err)
- assert.NotNil(t, res)
- forgotPasswordRes, err := resolvers.ForgotPasswordResolver(ctx, model.ForgotPasswordInput{
- Email: refs.NewStringRef(email),
- })
- assert.Nil(t, err, "no errors for forgot password")
- assert.NotNil(t, forgotPasswordRes)
- verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeForgotPassword)
- assert.Nil(t, err)
-
- assert.Equal(t, verificationRequest.Identifier, constants.VerificationTypeForgotPassword)
-
- cleanData(email)
- })
-}
diff --git a/server/test/generate_jwt_keys_test.go b/server/test/generate_jwt_keys_test.go
deleted file mode 100644
index e9ef63970..000000000
--- a/server/test/generate_jwt_keys_test.go
+++ /dev/null
@@ -1,66 +0,0 @@
-package test
-
-import (
- "fmt"
- "testing"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/crypto"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/resolvers"
- "github.com/stretchr/testify/assert"
-)
-
-func generateJWTkeyTest(t *testing.T, s TestSetup) {
- t.Helper()
- req, ctx := createContext(s)
- t.Run(`generate_jwt_keys`, func(t *testing.T) {
- t.Run(`should throw unauthorized`, func(t *testing.T) {
- res, err := resolvers.GenerateJWTKeysResolver(ctx, model.GenerateJWTKeysInput{
- Type: "HS256",
- })
- assert.Error(t, err)
- assert.Nil(t, res)
- })
- t.Run(`should throw invalid`, func(t *testing.T) {
- res, err := resolvers.GenerateJWTKeysResolver(ctx, model.GenerateJWTKeysInput{
- Type: "test",
- })
- assert.Error(t, err)
- assert.Nil(t, res)
- })
-
- adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
- assert.Nil(t, err)
-
- h, err := crypto.EncryptPassword(adminSecret)
- assert.Nil(t, err)
- req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
- t.Run(`should generate HS256 secret`, func(t *testing.T) {
- res, err := resolvers.GenerateJWTKeysResolver(ctx, model.GenerateJWTKeysInput{
- Type: "HS256",
- })
- assert.NoError(t, err)
- assert.NotEmpty(t, res.Secret)
- })
-
- t.Run(`should generate RS256 secret`, func(t *testing.T) {
- res, err := resolvers.GenerateJWTKeysResolver(ctx, model.GenerateJWTKeysInput{
- Type: "RS256",
- })
- assert.NoError(t, err)
- assert.NotEmpty(t, res.PrivateKey)
- assert.NotEmpty(t, res.PublicKey)
- })
-
- t.Run(`should generate ES256 secret`, func(t *testing.T) {
- res, err := resolvers.GenerateJWTKeysResolver(ctx, model.GenerateJWTKeysInput{
- Type: "ES256",
- })
- assert.NoError(t, err)
- assert.NotEmpty(t, res.PrivateKey)
- assert.NotEmpty(t, res.PublicKey)
- })
- })
-}
diff --git a/server/test/integration_test.go b/server/test/integration_test.go
deleted file mode 100644
index 5329e993d..000000000
--- a/server/test/integration_test.go
+++ /dev/null
@@ -1,157 +0,0 @@
-package test
-
-import (
- "context"
- "os"
- "strings"
- "testing"
- "time"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/db/models"
- "github.com/authorizerdev/authorizer/server/env"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/utils"
-)
-
-func TestResolvers(t *testing.T) {
- databases := map[string]string{
- constants.DbTypeSqlite: "../../test.db",
- 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",
- constants.DbTypeCouchbaseDB: "couchbase://127.0.0.1",
- }
-
- testDBs := strings.Split(os.Getenv("TEST_DBS"), ",")
- t.Log("Running tests for following dbs: ", testDBs)
- for dbType := range databases {
- if !utils.StringSliceContains(testDBs, dbType) {
- delete(databases, dbType)
- }
- }
-
- if utils.StringSliceContains(testDBs, constants.DbTypeSqlite) && len(testDBs) == 1 {
- // do nothing
- } else {
- t.Log("waiting for docker containers to start...")
- // wait for docker containers to spun up
- time.Sleep(30 * time.Second)
- }
-
- testDb := "authorizer_test"
- s := testSetup()
- defer s.Server.Close()
-
- for dbType, dbURL := range databases {
- ctx := context.Background()
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDatabaseURL, dbURL)
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDatabaseType, dbType)
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDatabaseName, testDb)
- 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")
- os.Unsetenv(constants.EnvAwsAccessKeyID)
- os.Unsetenv(constants.EnvAwsSecretAccessKey)
- // Remove aws credentials from env, so that local dynamodb can be used
- memorystore.Provider.UpdateEnvVariable(constants.EnvAwsAccessKeyID, "")
- memorystore.Provider.UpdateEnvVariable(constants.EnvAwsSecretAccessKey, "")
- }
- if dbType == constants.DbTypeCouchbaseDB {
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDatabaseUsername, "Administrator")
- os.Setenv(constants.EnvKeyDatabaseUsername, "Administrator")
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDatabasePassword, "password")
- os.Setenv(constants.EnvKeyDatabasePassword, "password")
- }
-
- memorystore.InitRequiredEnv()
-
- err := db.InitDB()
- if err != nil {
- 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 && envData == nil {
- envData = &models.Env{
- EnvData: "",
- }
- _, err = db.Provider.UpdateEnv(ctx, envData)
- if err != nil {
- 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.Logf("Error persisting env: %s", err.Error())
- }
-
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyEnv, "test")
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyIsProd, false)
- t.Run("should pass tests for "+dbType, func(t *testing.T) {
- // admin resolvers tests
- adminSignupTests(t, s)
- addWebhookTest(t, s) // add webhooks for all the system events
- testEndpointTest(t, s)
- verificationRequestsTest(t, s)
- updateWebhookTest(t, s)
- webhookTest(t, s)
- webhooksTest(t, s)
- //usersTest(t, s)
- userTest(t, s)
- deleteUserTest(t, s)
- //updateUserTest(t, s)
- adminLoginTests(t, s)
- adminLogoutTests(t, s)
- adminSessionTests(t, s)
- updateEnvTests(t, s)
- envTests(t, s)
- revokeAccessTest(t, s)
- enableAccessTest(t, s)
- generateJWTkeyTest(t, s)
- addEmailTemplateTest(t, s)
- updateEmailTemplateTest(t, s)
- emailTemplatesTest(t, s)
- deleteEmailTemplateTest(t, s)
- RoleDeletionTest(t, s)
-
- // user resolvers tests
- loginTests(t, s)
- signupTests(t, s)
- mobileSingupTest(t, s)
- mobileLoginTests(t, s)
- totpLoginTest(t, s)
- totpSignupTest(t, s)
- forgotPasswordTest(t, s)
- forgotPasswordMobileTest(t, s)
- resendVerifyEmailTests(t, s)
- resetPasswordTest(t, s)
- verifyEmailTest(t, s)
- sessionTests(t, s)
- profileTests(t, s)
- updateProfileTests(t, s)
- magicLinkLoginTests(t, s)
- logoutTests(t, s)
- metaTests(t, s)
- inviteUserTest(t, s)
- validateJwtTokenTest(t, s)
- verifyOTPTest(t, s)
- resendOTPTest(t, s)
- validateSessionTests(t, s)
- deactivateAccountTests(t, s)
-
- updateAllUsersTest(t, s)
- webhookLogsTest(t, s) // get logs after above resolver tests are done
- deleteWebhookTest(t, s) // delete webhooks (admin resolver)
- })
- }
-}
diff --git a/server/test/invite_member_test.go b/server/test/invite_member_test.go
deleted file mode 100644
index a9aa80677..000000000
--- a/server/test/invite_member_test.go
+++ /dev/null
@@ -1,62 +0,0 @@
-package test
-
-import (
- "fmt"
- "testing"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/crypto"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/resolvers"
- "github.com/stretchr/testify/assert"
-)
-
-func inviteUserTest(t *testing.T, s TestSetup) {
- t.Helper()
- t.Run(`should invite user successfully`, func(t *testing.T) {
- req, ctx := createContext(s)
- emails := []string{"invite_member1." + s.TestInfo.Email}
-
- // unauthorized error
- res, err := resolvers.InviteMembersResolver(ctx, model.InviteMemberInput{
- Emails: emails,
- })
-
- assert.Error(t, err)
- assert.Nil(t, res)
-
- adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
- assert.Nil(t, err)
-
- h, err := crypto.EncryptPassword(adminSecret)
- assert.Nil(t, err)
- req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
-
- // invalid emails test
- invalidEmailsTest := []string{
- "test",
- "test.com",
- }
- res, err = resolvers.InviteMembersResolver(ctx, model.InviteMemberInput{
- Emails: invalidEmailsTest,
- })
- assert.Error(t, err)
- assert.Nil(t, res)
- // valid test
- res, err = resolvers.InviteMembersResolver(ctx, model.InviteMemberInput{
- Emails: emails,
- })
- assert.Nil(t, err)
- assert.NotNil(t, res)
- assert.NotNil(t, res.Message)
- assert.NotNil(t, res.Users)
- // duplicate error test
- res, err = resolvers.InviteMembersResolver(ctx, model.InviteMemberInput{
- Emails: emails,
- })
- assert.Error(t, err)
- assert.Nil(t, res)
- cleanData(emails[0])
- })
-}
diff --git a/server/test/jwt_test.go b/server/test/jwt_test.go
deleted file mode 100644
index 5082689b1..000000000
--- a/server/test/jwt_test.go
+++ /dev/null
@@ -1,203 +0,0 @@
-package test
-
-import (
- "testing"
- "time"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/crypto"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/token"
- "github.com/golang-jwt/jwt"
- "github.com/google/uuid"
- "github.com/stretchr/testify/assert"
-)
-
-func TestJwt(t *testing.T) {
- // persist older data till test is done and then reset it
- jwtType, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyJwtType)
- assert.Nil(t, err)
- publicKey, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyJwtPublicKey)
- assert.Nil(t, err)
- privateKey, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyJwtPrivateKey)
- assert.Nil(t, err)
- clientID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyClientID)
- assert.Nil(t, err)
- nonce := uuid.New().String()
- hostname := "localhost"
- subject := "test"
- claims := jwt.MapClaims{
- "exp": time.Now().Add(time.Minute * 30).Unix(),
- "iat": time.Now().Unix(),
- "email": "test@yopmail.com",
- "sub": subject,
- "aud": clientID,
- "nonce": nonce,
- "iss": hostname,
- }
-
- t.Run("invalid jwt type", func(t *testing.T) {
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyJwtType, "invalid")
- token, err := token.SignJWTToken(claims)
- assert.Error(t, err, "unsupported signing method")
- assert.Empty(t, token)
- })
- t.Run("expired jwt token", func(t *testing.T) {
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyJwtType, "HS256")
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyJwtSecret, "test")
- expiredClaims := jwt.MapClaims{
- "exp": time.Now().Add(-time.Minute * 30).Unix(),
- "iat": time.Now().Unix(),
- "email": "test@yopmail.com",
- }
- jwtToken, err := token.SignJWTToken(expiredClaims)
- assert.NoError(t, err)
- _, err = token.ParseJWTToken(jwtToken)
- assert.Error(t, err, err.Error(), "Token is expired")
- })
- t.Run("HMAC algorithms", func(t *testing.T) {
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyJwtSecret, "test")
- t.Run("HS256", func(t *testing.T) {
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyJwtType, "HS256")
- jwtToken, err := token.SignJWTToken(claims)
- assert.NoError(t, err)
- assert.NotEmpty(t, jwtToken)
- c, err := token.ParseJWTToken(jwtToken)
- assert.NoError(t, err)
- assert.Equal(t, c["email"].(string), claims["email"])
- valid, err := token.ValidateJWTClaims(c, hostname, nonce, subject)
- assert.NoError(t, err)
- assert.True(t, valid)
- })
- t.Run("HS384", func(t *testing.T) {
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyJwtType, "HS384")
- jwtToken, err := token.SignJWTToken(claims)
- assert.NoError(t, err)
- assert.NotEmpty(t, jwtToken)
- c, err := token.ParseJWTToken(jwtToken)
- assert.NoError(t, err)
- assert.Equal(t, c["email"].(string), claims["email"])
- valid, err := token.ValidateJWTClaims(c, hostname, nonce, subject)
- assert.NoError(t, err)
- assert.True(t, valid)
- })
- t.Run("HS512", func(t *testing.T) {
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyJwtType, "HS512")
- jwtToken, err := token.SignJWTToken(claims)
- assert.NoError(t, err)
- assert.NotEmpty(t, jwtToken)
- c, err := token.ParseJWTToken(jwtToken)
- assert.NoError(t, err)
- assert.Equal(t, c["email"].(string), claims["email"])
- valid, err := token.ValidateJWTClaims(c, hostname, nonce, subject)
- assert.NoError(t, err)
- assert.True(t, valid)
- })
- })
-
- t.Run("RSA algorithms", func(t *testing.T) {
- t.Run("RS256", func(t *testing.T) {
- _, privateKey, publickKey, _, err := crypto.NewRSAKey("RS256", clientID)
- assert.NoError(t, err)
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyJwtType, "RS256")
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyJwtPrivateKey, privateKey)
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyJwtPublicKey, publickKey)
- jwtToken, err := token.SignJWTToken(claims)
- assert.NoError(t, err)
- assert.NotEmpty(t, jwtToken)
- c, err := token.ParseJWTToken(jwtToken)
- assert.NoError(t, err)
- assert.Equal(t, c["email"].(string), claims["email"])
- valid, err := token.ValidateJWTClaims(c, hostname, nonce, subject)
- assert.NoError(t, err)
- assert.True(t, valid)
- })
- t.Run("RS384", func(t *testing.T) {
- _, privateKey, publickKey, _, err := crypto.NewRSAKey("RS384", clientID)
- assert.NoError(t, err)
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyJwtType, "RS384")
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyJwtPrivateKey, privateKey)
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyJwtPublicKey, publickKey)
- jwtToken, err := token.SignJWTToken(claims)
- assert.NoError(t, err)
- assert.NotEmpty(t, jwtToken)
- c, err := token.ParseJWTToken(jwtToken)
- assert.NoError(t, err)
- assert.Equal(t, c["email"].(string), claims["email"])
- valid, err := token.ValidateJWTClaims(c, hostname, nonce, subject)
- assert.NoError(t, err)
- assert.True(t, valid)
- })
- t.Run("RS512", func(t *testing.T) {
- _, privateKey, publickKey, _, err := crypto.NewRSAKey("RS512", clientID)
- assert.NoError(t, err)
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyJwtType, "RS512")
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyJwtPrivateKey, privateKey)
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyJwtPublicKey, publickKey)
- jwtToken, err := token.SignJWTToken(claims)
- assert.NoError(t, err)
- assert.NotEmpty(t, jwtToken)
- c, err := token.ParseJWTToken(jwtToken)
- assert.NoError(t, err)
- assert.Equal(t, c["email"].(string), claims["email"])
- valid, err := token.ValidateJWTClaims(c, hostname, nonce, subject)
- assert.NoError(t, err)
- assert.True(t, valid)
- })
- })
-
- t.Run("ECDSA algorithms", func(t *testing.T) {
- t.Run("ES256", func(t *testing.T) {
- _, privateKey, publickKey, _, err := crypto.NewECDSAKey("ES256", clientID)
- assert.NoError(t, err)
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyJwtType, "ES256")
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyJwtPrivateKey, privateKey)
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyJwtPublicKey, publickKey)
- jwtToken, err := token.SignJWTToken(claims)
- assert.NoError(t, err)
- assert.NotEmpty(t, jwtToken)
- c, err := token.ParseJWTToken(jwtToken)
- assert.NoError(t, err)
- assert.Equal(t, c["email"].(string), claims["email"])
- valid, err := token.ValidateJWTClaims(c, hostname, nonce, subject)
- assert.NoError(t, err)
- assert.True(t, valid)
- })
- t.Run("ES384", func(t *testing.T) {
- _, privateKey, publickKey, _, err := crypto.NewECDSAKey("ES384", clientID)
- assert.NoError(t, err)
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyJwtType, "ES384")
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyJwtPrivateKey, privateKey)
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyJwtPublicKey, publickKey)
- jwtToken, err := token.SignJWTToken(claims)
- assert.NoError(t, err)
- assert.NotEmpty(t, jwtToken)
- c, err := token.ParseJWTToken(jwtToken)
- assert.NoError(t, err)
- assert.Equal(t, c["email"].(string), claims["email"])
- valid, err := token.ValidateJWTClaims(c, hostname, nonce, subject)
- assert.NoError(t, err)
- assert.True(t, valid)
- })
- t.Run("ES512", func(t *testing.T) {
- _, privateKey, publickKey, _, err := crypto.NewECDSAKey("ES512", clientID)
- assert.NoError(t, err)
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyJwtType, "ES512")
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyJwtPrivateKey, privateKey)
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyJwtPublicKey, publickKey)
- jwtToken, err := token.SignJWTToken(claims)
- assert.NoError(t, err)
- assert.NotEmpty(t, jwtToken)
- c, err := token.ParseJWTToken(jwtToken)
- assert.NoError(t, err)
- assert.Equal(t, c["email"].(string), claims["email"])
- valid, err := token.ValidateJWTClaims(c, hostname, nonce, subject)
- assert.NoError(t, err)
- assert.True(t, valid)
- })
- })
-
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyJwtType, jwtType)
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyJwtPublicKey, publicKey)
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyJwtPrivateKey, privateKey)
-}
diff --git a/server/test/login_test.go b/server/test/login_test.go
deleted file mode 100644
index 83b68b791..000000000
--- a/server/test/login_test.go
+++ /dev/null
@@ -1,71 +0,0 @@
-package test
-
-import (
- "testing"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/refs"
- "github.com/authorizerdev/authorizer/server/resolvers"
- "github.com/authorizerdev/authorizer/server/utils"
- "github.com/stretchr/testify/assert"
-)
-
-func loginTests(t *testing.T, s TestSetup) {
- t.Helper()
- t.Run(`should login`, func(t *testing.T) {
- _, ctx := createContext(s)
- email := "login." + s.TestInfo.Email
- signUpRes, err := resolvers.SignupResolver(ctx, model.SignUpInput{
- Email: refs.NewStringRef(email),
- Password: s.TestInfo.Password,
- ConfirmPassword: s.TestInfo.Password,
- })
- assert.NoError(t, err)
- assert.NotNil(t, signUpRes)
- res, err := resolvers.LoginResolver(ctx, model.LoginInput{
- Email: refs.NewStringRef(email),
- Password: s.TestInfo.Password,
- })
- // access token should be empty as email is not verified
- assert.NoError(t, err)
- assert.NotNil(t, res)
- assert.Nil(t, res.AccessToken)
- assert.NotEmpty(t, res.Message)
- verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeBasicAuthSignup)
- assert.NoError(t, err)
- assert.NotNil(t, verificationRequest)
- n, err := utils.EncryptNonce(verificationRequest.Nonce)
- assert.NoError(t, err)
- assert.NotEmpty(t, n)
- assert.NotNil(t, verificationRequest)
- res, err = resolvers.VerifyEmailResolver(ctx, model.VerifyEmailInput{
- Token: verificationRequest.Token,
- })
- assert.NoError(t, err)
- assert.NotNil(t, res)
- _, err = resolvers.LoginResolver(ctx, model.LoginInput{
- Email: refs.NewStringRef(email),
- Password: s.TestInfo.Password,
- Roles: []string{"test"},
- })
- assert.NotNil(t, err, "invalid roles")
-
- _, err = resolvers.LoginResolver(ctx, model.LoginInput{
- Email: refs.NewStringRef(email),
- Password: s.TestInfo.Password + "s",
- })
- assert.NotNil(t, err, "invalid password")
-
- loginRes, err := resolvers.LoginResolver(ctx, model.LoginInput{
- Email: refs.NewStringRef(email),
- Password: s.TestInfo.Password,
- })
-
- assert.Nil(t, err, "login successful")
- assert.NotNil(t, loginRes.AccessToken, "access token should not be empty")
-
- cleanData(email)
- })
-}
diff --git a/server/test/logout_test.go b/server/test/logout_test.go
deleted file mode 100644
index 0a79c0bc5..000000000
--- a/server/test/logout_test.go
+++ /dev/null
@@ -1,83 +0,0 @@
-package test
-
-import (
- "fmt"
- "strings"
- "testing"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/resolvers"
- "github.com/authorizerdev/authorizer/server/token"
- "github.com/stretchr/testify/assert"
-)
-
-func logoutTests(t *testing.T, s TestSetup) {
- t.Helper()
- t.Run(`should logout user`, func(t *testing.T) {
- req, ctx := createContext(s)
- email := "logout." + s.TestInfo.Email
-
- magicLoginRes, err := resolvers.MagicLinkLoginResolver(ctx, model.MagicLinkLoginInput{
- Email: email,
- })
- assert.NoError(t, err)
- assert.NotNil(t, magicLoginRes)
- verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeMagicLinkLogin)
- assert.NoError(t, err)
- assert.NotNil(t, verificationRequest)
- verifyRes, err := resolvers.VerifyEmailResolver(ctx, model.VerifyEmailInput{
- Token: verificationRequest.Token,
- })
- assert.NoError(t, err)
- assert.NotNil(t, verifyRes)
- accessToken := *verifyRes.AccessToken
- assert.NotEmpty(t, accessToken)
- // Test logout with access token
- req.Header.Set("Authorization", "Bearer "+accessToken)
- logoutRes, err := resolvers.LogoutResolver(ctx)
- assert.Nil(t, err)
- assert.NotNil(t, logoutRes)
- assert.NotEmpty(t, logoutRes.Message)
- req.Header.Set("Authorization", "")
-
- // Test logout with session cookie
- magicLoginRes, err = resolvers.MagicLinkLoginResolver(ctx, model.MagicLinkLoginInput{
- Email: email,
- })
- assert.NoError(t, err)
- assert.NotNil(t, magicLoginRes)
- verificationRequest, err = db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeMagicLinkLogin)
- assert.NoError(t, err)
- assert.NotNil(t, verificationRequest)
- verifyRes, err = resolvers.VerifyEmailResolver(ctx, model.VerifyEmailInput{
- Token: verificationRequest.Token,
- })
- assert.NoError(t, err)
- assert.NotNil(t, verifyRes)
- accessToken = *verifyRes.AccessToken
- assert.NotEmpty(t, accessToken)
- claims, err := token.ParseJWTToken(accessToken)
- assert.NoError(t, err)
- assert.NotEmpty(t, claims)
- loginMethod := claims["login_method"]
- sessionKey := verifyRes.User.ID
- if loginMethod != nil && loginMethod != "" {
- sessionKey = loginMethod.(string) + ":" + verifyRes.User.ID
- }
-
- sessionToken, err := memorystore.Provider.GetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+claims["nonce"].(string))
- assert.NoError(t, err)
- assert.NotEmpty(t, sessionToken)
-
- cookie := fmt.Sprintf("%s=%s;", constants.AppCookieName+"_session", sessionToken)
- cookie = strings.TrimSuffix(cookie, ";")
-
- req.Header.Set("Cookie", cookie)
- _, err = resolvers.LogoutResolver(ctx)
- assert.Nil(t, err)
- cleanData(email)
- })
-}
diff --git a/server/test/magic_link_login_test.go b/server/test/magic_link_login_test.go
deleted file mode 100644
index 03b9c86fa..000000000
--- a/server/test/magic_link_login_test.go
+++ /dev/null
@@ -1,47 +0,0 @@
-package test
-
-import (
- "context"
- "testing"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/resolvers"
- "github.com/stretchr/testify/assert"
-)
-
-func magicLinkLoginTests(t *testing.T, s TestSetup) {
- t.Helper()
- t.Run(`should login with magic link`, func(t *testing.T) {
- req, ctx := createContext(s)
- email := "magic_link_login." + s.TestInfo.Email
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDisableSignUp, true)
- _, err := resolvers.MagicLinkLoginResolver(ctx, model.MagicLinkLoginInput{
- Email: email,
- })
- assert.NotNil(t, err, "signup disabled")
-
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDisableSignUp, false)
- _, err = resolvers.MagicLinkLoginResolver(ctx, model.MagicLinkLoginInput{
- Email: email,
- })
- assert.Nil(t, err, "signup should be successful")
-
- verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeMagicLinkLogin)
- assert.NoError(t, err)
- assert.NotNil(t, verificationRequest)
- verifyRes, err := resolvers.VerifyEmailResolver(ctx, model.VerifyEmailInput{
- Token: verificationRequest.Token,
- })
- assert.NoError(t, err)
- assert.NotNil(t, verifyRes.AccessToken)
- s.GinContext.Request.Header.Set("Authorization", "Bearer "+*verifyRes.AccessToken)
- ctx = context.WithValue(req.Context(), "GinContextKey", s.GinContext)
- _, err = resolvers.ProfileResolver(ctx)
- assert.Nil(t, err)
- s.GinContext.Request.Header.Set("Authorization", "")
- cleanData(email)
- })
-}
diff --git a/server/test/meta_test.go b/server/test/meta_test.go
deleted file mode 100644
index 130ccc7dd..000000000
--- a/server/test/meta_test.go
+++ /dev/null
@@ -1,24 +0,0 @@
-package test
-
-import (
- "context"
- "testing"
-
- "github.com/authorizerdev/authorizer/server/resolvers"
- "github.com/stretchr/testify/assert"
-)
-
-func metaTests(t *testing.T, s TestSetup) {
- t.Helper()
- t.Run(`should get meta information`, func(t *testing.T) {
- ctx := context.Background()
- meta, err := resolvers.MetaResolver(ctx)
- assert.Nil(t, err)
- assert.False(t, meta.IsFacebookLoginEnabled)
- assert.False(t, meta.IsGoogleLoginEnabled)
- assert.False(t, meta.IsGithubLoginEnabled)
- assert.True(t, meta.IsEmailVerificationEnabled)
- assert.True(t, meta.IsBasicAuthenticationEnabled)
- assert.True(t, meta.IsMagicLinkLoginEnabled)
- })
-}
diff --git a/server/test/mobile_login_test.go b/server/test/mobile_login_test.go
deleted file mode 100644
index fa0d5de3b..000000000
--- a/server/test/mobile_login_test.go
+++ /dev/null
@@ -1,65 +0,0 @@
-package test
-
-import (
- "fmt"
- "strings"
- "testing"
- "time"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/refs"
- "github.com/authorizerdev/authorizer/server/resolvers"
- "github.com/google/uuid"
- "github.com/stretchr/testify/assert"
-)
-
-func mobileLoginTests(t *testing.T, s TestSetup) {
- t.Helper()
- t.Run(`should login via mobile`, func(t *testing.T) {
- _, ctx := createContext(s)
- phoneNumber := "2234567890"
- signUpRes, err := resolvers.SignupResolver(ctx, model.SignUpInput{
- PhoneNumber: refs.NewStringRef(phoneNumber),
- Password: s.TestInfo.Password,
- ConfirmPassword: s.TestInfo.Password,
- })
- assert.NoError(t, err)
- assert.NotNil(t, signUpRes)
- // should fail because phone is not verified
- res, err := resolvers.LoginResolver(ctx, model.LoginInput{
- PhoneNumber: refs.NewStringRef(phoneNumber),
- Password: s.TestInfo.Password,
- })
- // access token should be empty as email is not verified
- assert.NoError(t, err)
- assert.NotNil(t, res)
- assert.Nil(t, res.AccessToken)
- assert.NotEmpty(t, res.Message)
- assert.True(t, *res.ShouldShowMobileOtpScreen)
- smsRequest, err := db.Provider.GetOTPByPhoneNumber(ctx, phoneNumber)
- assert.NoError(t, err)
- assert.NotEmpty(t, smsRequest.Otp)
- // Get user by phone number
- user, err := db.Provider.GetUserByPhoneNumber(ctx, phoneNumber)
- assert.NoError(t, err)
- assert.NotNil(t, user)
- // Set mfa cookie session
- mfaSession := uuid.NewString()
- memorystore.Provider.SetMfaSession(user.ID, mfaSession, time.Now().Add(1*time.Minute).Unix())
- cookie := fmt.Sprintf("%s=%s;", constants.MfaCookieName+"_session", mfaSession)
- cookie = strings.TrimSuffix(cookie, ";")
- req, ctx := createContext(s)
- req.Header.Set("Cookie", cookie)
- verifySMSRequest, err := resolvers.VerifyOtpResolver(ctx, model.VerifyOTPRequest{
- PhoneNumber: &phoneNumber,
- Otp: smsRequest.Otp,
- })
- assert.Nil(t, err)
- assert.NotEqual(t, verifySMSRequest.Message, "", "message should not be empty")
- assert.NotEmpty(t, verifySMSRequest.AccessToken)
- assert.NotEmpty(t, verifySMSRequest.IDToken)
- })
-}
diff --git a/server/test/mobile_signup_test.go b/server/test/mobile_signup_test.go
deleted file mode 100644
index 7bfba1c18..000000000
--- a/server/test/mobile_signup_test.go
+++ /dev/null
@@ -1,115 +0,0 @@
-package test
-
-import (
- "fmt"
- "strings"
- "testing"
- "time"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/refs"
- "github.com/authorizerdev/authorizer/server/resolvers"
- "github.com/google/uuid"
- "github.com/stretchr/testify/assert"
-)
-
-func mobileSingupTest(t *testing.T, s TestSetup) {
- t.Helper()
- t.Run(`should complete the signup with mobile and check duplicates`, func(t *testing.T) {
- _, ctx := createContext(s)
- phoneNumber := "1234567890"
- res, err := resolvers.SignupResolver(ctx, model.SignUpInput{
- PhoneNumber: refs.NewStringRef(phoneNumber),
- Password: s.TestInfo.Password,
- ConfirmPassword: s.TestInfo.Password + "s",
- })
- assert.NotNil(t, err, "invalid password")
- assert.Nil(t, res)
- res, err = resolvers.SignupResolver(ctx, model.SignUpInput{
- Password: "test",
- ConfirmPassword: "test",
- })
- assert.Error(t, err, "phone number or email should be provided")
- assert.Nil(t, res)
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDisableSignUp, true)
- res, err = resolvers.SignupResolver(ctx, model.SignUpInput{
- PhoneNumber: refs.NewStringRef(phoneNumber),
- Password: s.TestInfo.Password,
- ConfirmPassword: s.TestInfo.Password,
- })
- assert.Error(t, err)
- assert.Nil(t, res)
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDisableSignUp, false)
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDisableMobileBasicAuthentication, true)
- res, err = resolvers.SignupResolver(ctx, model.SignUpInput{
- PhoneNumber: refs.NewStringRef(phoneNumber),
- Password: s.TestInfo.Password,
- ConfirmPassword: s.TestInfo.Password,
- })
- assert.Error(t, err)
- assert.Nil(t, res)
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDisableMobileBasicAuthentication, false)
-
- res, err = resolvers.SignupResolver(ctx, model.SignUpInput{
- PhoneNumber: refs.NewStringRef(" "),
- Password: s.TestInfo.Password,
- ConfirmPassword: s.TestInfo.Password,
- })
- assert.Error(t, err)
- assert.Nil(t, res)
-
- res, err = resolvers.SignupResolver(ctx, model.SignUpInput{
- PhoneNumber: refs.NewStringRef("test"),
- Password: s.TestInfo.Password,
- ConfirmPassword: s.TestInfo.Password,
- })
- assert.Error(t, err)
- assert.Nil(t, res)
-
- res, err = resolvers.SignupResolver(ctx, model.SignUpInput{
- PhoneNumber: refs.NewStringRef(phoneNumber),
- Password: s.TestInfo.Password,
- ConfirmPassword: s.TestInfo.Password,
- })
- assert.NoError(t, err)
- assert.NotNil(t, res)
- assert.True(t, *res.ShouldShowMobileOtpScreen)
- // Verify with otp
- otp, err := db.Provider.GetOTPByPhoneNumber(ctx, phoneNumber)
- assert.Nil(t, err)
- assert.NotEmpty(t, otp.Otp)
- // Get user by phone number
- user, err := db.Provider.GetUserByPhoneNumber(ctx, phoneNumber)
- assert.NoError(t, err)
- assert.NotNil(t, user)
- // Set mfa cookie session
- mfaSession := uuid.NewString()
- memorystore.Provider.SetMfaSession(user.ID, mfaSession, time.Now().Add(1*time.Minute).Unix())
- cookie := fmt.Sprintf("%s=%s;", constants.MfaCookieName+"_session", mfaSession)
- cookie = strings.TrimSuffix(cookie, ";")
- req, ctx := createContext(s)
- req.Header.Set("Cookie", cookie)
- otpRes, err := resolvers.VerifyOtpResolver(ctx, model.VerifyOTPRequest{
- PhoneNumber: refs.NewStringRef(phoneNumber),
- Otp: otp.Otp,
- })
- assert.Nil(t, err)
- assert.NotEmpty(t, otpRes.Message)
- // Check if phone number is verified
- user, err = db.Provider.GetUserByPhoneNumber(ctx, phoneNumber)
- assert.NoError(t, err)
- assert.NotNil(t, user)
- assert.NotNil(t, user.PhoneNumberVerifiedAt)
- res, err = resolvers.SignupResolver(ctx, model.SignUpInput{
- PhoneNumber: refs.NewStringRef(phoneNumber),
- Password: s.TestInfo.Password,
- ConfirmPassword: s.TestInfo.Password,
- })
- assert.Error(t, err, "should throw duplicate error")
- assert.Nil(t, res)
- cleanData("1234567890@authorizer.dev")
- })
-}
diff --git a/server/test/profile_test.go b/server/test/profile_test.go
deleted file mode 100644
index a49ba9d0b..000000000
--- a/server/test/profile_test.go
+++ /dev/null
@@ -1,49 +0,0 @@
-package test
-
-import (
- "context"
- "testing"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/refs"
- "github.com/authorizerdev/authorizer/server/resolvers"
- "github.com/stretchr/testify/assert"
-)
-
-func profileTests(t *testing.T, s TestSetup) {
- t.Helper()
- t.Run(`should get profile only access_token token`, func(t *testing.T) {
- req, ctx := createContext(s)
- email := "profile." + s.TestInfo.Email
-
- resolvers.SignupResolver(ctx, model.SignUpInput{
- Email: refs.NewStringRef(email),
- Password: s.TestInfo.Password,
- ConfirmPassword: s.TestInfo.Password,
- })
-
- _, err := resolvers.ProfileResolver(ctx)
- assert.NotNil(t, err, "unauthorized")
-
- verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeBasicAuthSignup)
- assert.NoError(t, err)
- assert.NotNil(t, verificationRequest)
- verifyRes, err := resolvers.VerifyEmailResolver(ctx, model.VerifyEmailInput{
- Token: verificationRequest.Token,
- })
- assert.NoError(t, err)
- assert.NotNil(t, verifyRes.AccessToken)
-
- s.GinContext.Request.Header.Set("Authorization", "Bearer "+*verifyRes.AccessToken)
- ctx = context.WithValue(req.Context(), "GinContextKey", s.GinContext)
- profileRes, err := resolvers.ProfileResolver(ctx)
- assert.Nil(t, err)
- assert.NotNil(t, profileRes)
- s.GinContext.Request.Header.Set("Authorization", "")
- newEmail := profileRes.Email
- assert.Equal(t, email, refs.StringValue(newEmail), "emails should be equal")
- cleanData(email)
- })
-}
diff --git a/server/test/resend_otp_test.go b/server/test/resend_otp_test.go
deleted file mode 100644
index 20b169587..000000000
--- a/server/test/resend_otp_test.go
+++ /dev/null
@@ -1,114 +0,0 @@
-package test
-
-import (
- "context"
- "fmt"
- "strings"
- "testing"
- "time"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/refs"
- "github.com/authorizerdev/authorizer/server/resolvers"
- "github.com/google/uuid"
- "github.com/stretchr/testify/assert"
-)
-
-func resendOTPTest(t *testing.T, s TestSetup) {
- t.Helper()
- t.Run(`should resend otp`, func(t *testing.T) {
- req, ctx := createContext(s)
- email := "resend_otp." + s.TestInfo.Email
- res, err := resolvers.SignupResolver(ctx, model.SignUpInput{
- Email: refs.NewStringRef(email),
- Password: s.TestInfo.Password,
- ConfirmPassword: s.TestInfo.Password,
- })
- assert.NoError(t, err)
- assert.NotNil(t, res)
-
- // Login should fail as email is not verified
- loginRes, err := resolvers.LoginResolver(ctx, model.LoginInput{
- Email: refs.NewStringRef(email),
- Password: s.TestInfo.Password,
- })
- // access token should be empty as email is not verified
- assert.NoError(t, err)
- assert.NotNil(t, loginRes)
- assert.Nil(t, loginRes.AccessToken)
- assert.NotEmpty(t, loginRes.Message)
- verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeBasicAuthSignup)
- assert.Nil(t, err)
- assert.Equal(t, email, verificationRequest.Email)
- verifyRes, err := resolvers.VerifyEmailResolver(ctx, model.VerifyEmailInput{
- Token: verificationRequest.Token,
- })
- assert.Nil(t, err)
- assert.NotEqual(t, verifyRes.AccessToken, "", "access token should not be empty")
-
- // Using access token update profile
- s.GinContext.Request.Header.Set("Authorization", "Bearer "+refs.StringValue(verifyRes.AccessToken))
- ctx = context.WithValue(req.Context(), "GinContextKey", s.GinContext)
- updateRes, err := resolvers.UpdateProfileResolver(ctx, model.UpdateProfileInput{
- IsMultiFactorAuthEnabled: refs.NewBoolRef(true),
- })
- assert.NoError(t, err)
- assert.NotNil(t, updateRes)
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDisableMailOTPLogin, false)
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDisableTOTPLogin, true)
-
- // Login should not return error but access token should be empty as otp should have been sent
- loginRes, err = resolvers.LoginResolver(ctx, model.LoginInput{
- Email: refs.NewStringRef(email),
- Password: s.TestInfo.Password,
- })
- assert.NoError(t, err)
- assert.NotNil(t, loginRes)
- assert.Nil(t, loginRes.AccessToken)
-
- // Get otp from db
- otp, err := db.Provider.GetOTPByEmail(ctx, email)
- assert.NoError(t, err)
- assert.NotEmpty(t, otp.Otp)
-
- // resend otp
- resendOtpRes, err := resolvers.ResendOTPResolver(ctx, model.ResendOTPRequest{
- Email: refs.NewStringRef(email),
- })
- assert.NoError(t, err)
- assert.NotEmpty(t, resendOtpRes.Message)
-
- newOtp, err := db.Provider.GetOTPByEmail(ctx, email)
- assert.NoError(t, err)
- assert.NotEmpty(t, newOtp.Otp)
- assert.NotEqual(t, otp.Otp, newOtp)
-
- // Should return error for older otp
- verifyOtpRes, err := resolvers.VerifyOtpResolver(ctx, model.VerifyOTPRequest{
- Email: &email,
- Otp: otp.Otp,
- })
- assert.Error(t, err)
- assert.Nil(t, verifyOtpRes)
- // Get user by email
- user, err := db.Provider.GetUserByEmail(ctx, email)
- assert.NoError(t, err)
- assert.NotNil(t, user)
- // Set mfa cookie session
- mfaSession := uuid.NewString()
- memorystore.Provider.SetMfaSession(user.ID, mfaSession, time.Now().Add(1*time.Minute).Unix())
- cookie := fmt.Sprintf("%s=%s;", constants.MfaCookieName+"_session", mfaSession)
- cookie = strings.TrimSuffix(cookie, ";")
- req.Header.Set("Cookie", cookie)
- verifyOtpRes, err = resolvers.VerifyOtpResolver(ctx, model.VerifyOTPRequest{
- Email: &email,
- Otp: newOtp.Otp,
- })
- assert.NoError(t, err)
- assert.NotEqual(t, verifyOtpRes.AccessToken, "", "access token should not be empty")
- cleanData(email)
- })
-}
diff --git a/server/test/resend_verify_email_test.go b/server/test/resend_verify_email_test.go
deleted file mode 100644
index 028d89a31..000000000
--- a/server/test/resend_verify_email_test.go
+++ /dev/null
@@ -1,32 +0,0 @@
-package test
-
-import (
- "testing"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/refs"
- "github.com/authorizerdev/authorizer/server/resolvers"
- "github.com/stretchr/testify/assert"
-)
-
-func resendVerifyEmailTests(t *testing.T, s TestSetup) {
- t.Helper()
- t.Run(`should resend verification email`, func(t *testing.T) {
- _, ctx := createContext(s)
- email := "resend_verify_email." + s.TestInfo.Email
- _, err := resolvers.SignupResolver(ctx, model.SignUpInput{
- Email: refs.NewStringRef(email),
- Password: s.TestInfo.Password,
- ConfirmPassword: s.TestInfo.Password,
- })
- assert.NoError(t, err)
- _, err = resolvers.ResendVerifyEmailResolver(ctx, model.ResendVerifyEmailInput{
- Email: email,
- Identifier: constants.VerificationTypeBasicAuthSignup,
- })
- assert.NoError(t, err)
-
- cleanData(email)
- })
-}
diff --git a/server/test/reset_password_test.go b/server/test/reset_password_test.go
deleted file mode 100644
index f784b48e7..000000000
--- a/server/test/reset_password_test.go
+++ /dev/null
@@ -1,52 +0,0 @@
-package test
-
-import (
- "testing"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/refs"
- "github.com/authorizerdev/authorizer/server/resolvers"
- "github.com/stretchr/testify/assert"
-)
-
-func resetPasswordTest(t *testing.T, s TestSetup) {
- t.Helper()
- t.Run(`should reset password`, func(t *testing.T) {
- email := "reset_password." + s.TestInfo.Email
- _, ctx := createContext(s)
- _, err := resolvers.SignupResolver(ctx, model.SignUpInput{
- Email: refs.NewStringRef(email),
- Password: s.TestInfo.Password,
- ConfirmPassword: s.TestInfo.Password,
- })
- assert.NoError(t, err)
- _, err = resolvers.ForgotPasswordResolver(ctx, model.ForgotPasswordInput{
- Email: refs.NewStringRef(email),
- })
- assert.Nil(t, err, "no errors for forgot password")
- verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeForgotPassword)
- assert.Nil(t, err, "should get forgot password request")
- assert.NotNil(t, verificationRequest)
- _, err = resolvers.ResetPasswordResolver(ctx, model.ResetPasswordInput{
- Token: refs.NewStringRef(verificationRequest.Token),
- Password: "test1",
- ConfirmPassword: "test",
- })
- assert.NotNil(t, err, "passwords don't match")
- _, err = resolvers.ResetPasswordResolver(ctx, model.ResetPasswordInput{
- Token: refs.NewStringRef(verificationRequest.Token),
- Password: "test1",
- ConfirmPassword: "test1",
- })
- assert.NotNil(t, err, "invalid password")
- _, err = resolvers.ResetPasswordResolver(ctx, model.ResetPasswordInput{
- Token: refs.NewStringRef(verificationRequest.Token),
- Password: "Test@1234",
- ConfirmPassword: "Test@1234",
- })
- assert.Nil(t, err, "password changed successfully")
- cleanData(email)
- })
-}
diff --git a/server/test/revoke_access_test.go b/server/test/revoke_access_test.go
deleted file mode 100644
index 4be042d0d..000000000
--- a/server/test/revoke_access_test.go
+++ /dev/null
@@ -1,59 +0,0 @@
-package test
-
-import (
- "fmt"
- "testing"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/crypto"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/resolvers"
- "github.com/stretchr/testify/assert"
-)
-
-func revokeAccessTest(t *testing.T, s TestSetup) {
- t.Helper()
- t.Run(`should revoke access`, func(t *testing.T) {
- req, ctx := createContext(s)
- email := "revoke_access." + s.TestInfo.Email
- _, err := resolvers.MagicLinkLoginResolver(ctx, model.MagicLinkLoginInput{
- Email: email,
- })
- assert.NoError(t, err)
- verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeMagicLinkLogin)
- assert.NoError(t, err)
- assert.NotNil(t, verificationRequest)
- verifyRes, err := resolvers.VerifyEmailResolver(ctx, model.VerifyEmailInput{
- Token: verificationRequest.Token,
- })
- assert.NoError(t, err)
- assert.NotNil(t, verifyRes.AccessToken)
-
- res, err := resolvers.RevokeAccessResolver(ctx, model.UpdateAccessInput{
- UserID: verifyRes.User.ID,
- })
- assert.Error(t, err)
- assert.Nil(t, res)
- adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
- assert.Nil(t, err)
-
- h, err := crypto.EncryptPassword(adminSecret)
- assert.Nil(t, err)
- req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
-
- res, err = resolvers.RevokeAccessResolver(ctx, model.UpdateAccessInput{
- UserID: verifyRes.User.ID,
- })
- assert.NoError(t, err)
- assert.NotEmpty(t, res.Message)
-
- // it should not allow login with revoked access
- _, err = resolvers.MagicLinkLoginResolver(ctx, model.MagicLinkLoginInput{
- Email: email,
- })
- assert.Error(t, err)
- cleanData(email)
- })
-}
diff --git a/server/test/role_deletion_test.go b/server/test/role_deletion_test.go
deleted file mode 100644
index ed0ed9000..000000000
--- a/server/test/role_deletion_test.go
+++ /dev/null
@@ -1,98 +0,0 @@
-package test
-
-import (
- "fmt"
- "github.com/authorizerdev/authorizer/server/crypto"
- "strings"
- "testing"
-
- "github.com/stretchr/testify/assert"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/refs"
- "github.com/authorizerdev/authorizer/server/resolvers"
-)
-
-func RoleDeletionTest(t *testing.T, s TestSetup) {
- t.Helper()
- t.Run(`should complete role deletion`, func(t *testing.T) {
- // login as admin
- req, ctx := createContext(s)
-
- _, err := resolvers.AdminLoginResolver(ctx, model.AdminLoginInput{
- AdminSecret: "admin_test",
- })
- assert.NotNil(t, err)
-
- adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
- assert.Nil(t, err)
- _, err = resolvers.AdminLoginResolver(ctx, model.AdminLoginInput{
- AdminSecret: adminSecret,
- })
- assert.Nil(t, err)
-
- h, err := crypto.EncryptPassword(adminSecret)
- assert.Nil(t, err)
- req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
-
- // add new default role to get role, if not present in roles
- originalDefaultRoles, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyDefaultRoles)
- assert.Nil(t, err)
- originalDefaultRolesSlice := strings.Split(originalDefaultRoles, ",")
-
- data := model.UpdateEnvInput{
- DefaultRoles: append(originalDefaultRolesSlice, "abc"),
- }
- _, err = resolvers.UpdateEnvResolver(ctx, data)
- assert.Error(t, err)
-
- // add new role
- originalRoles, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyRoles)
- assert.Nil(t, err)
- originalRolesSlice := strings.Split(originalRoles, ",")
- roleToBeAdded := "abc"
- newRoles := append(originalRolesSlice, roleToBeAdded)
- data = model.UpdateEnvInput{
- Roles: newRoles,
- }
- _, err = resolvers.UpdateEnvResolver(ctx, data)
- assert.Nil(t, err)
-
- // register a user with all roles
- email := "update_user." + s.TestInfo.Email
- _, err = resolvers.SignupResolver(ctx, model.SignUpInput{
- Email: refs.NewStringRef(email),
- Password: s.TestInfo.Password,
- ConfirmPassword: s.TestInfo.Password,
- Roles: newRoles,
- })
- assert.Nil(t, err)
-
- regUserDetails, _ := resolvers.UserResolver(ctx, model.GetUserRequest{
- Email: refs.NewStringRef(email),
- })
-
- // update env by removing role "abc"
- var newRolesAfterDeletion []string
- for _, value := range newRoles {
- if value != roleToBeAdded {
- newRolesAfterDeletion = append(newRolesAfterDeletion, value)
- }
- }
- data = model.UpdateEnvInput{
- Roles: newRolesAfterDeletion,
- }
- _, err = resolvers.UpdateEnvResolver(ctx, data)
- assert.Nil(t, err)
-
- // check user if role still exist
- userDetails, err := resolvers.UserResolver(ctx, model.GetUserRequest{
- Email: refs.NewStringRef(email),
- })
- assert.Nil(t, err)
- assert.Equal(t, newRolesAfterDeletion, userDetails.Roles)
- assert.NotEqual(t, newRolesAfterDeletion, regUserDetails.Roles)
- })
-}
diff --git a/server/test/session_test.go b/server/test/session_test.go
deleted file mode 100644
index e80633c6b..000000000
--- a/server/test/session_test.go
+++ /dev/null
@@ -1,62 +0,0 @@
-package test
-
-import (
- "fmt"
- "strings"
- "testing"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/refs"
- "github.com/authorizerdev/authorizer/server/resolvers"
- "github.com/authorizerdev/authorizer/server/token"
- "github.com/stretchr/testify/assert"
-)
-
-func sessionTests(t *testing.T, s TestSetup) {
- t.Helper()
- t.Run(`should allow access to profile with session only`, func(t *testing.T) {
- req, ctx := createContext(s)
- email := "session." + s.TestInfo.Email
-
- resolvers.SignupResolver(ctx, model.SignUpInput{
- Email: refs.NewStringRef(email),
- Password: s.TestInfo.Password,
- ConfirmPassword: s.TestInfo.Password,
- })
-
- _, err := resolvers.SessionResolver(ctx, &model.SessionQueryInput{})
- assert.NotNil(t, err, "unauthorized")
-
- verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeBasicAuthSignup)
- assert.NoError(t, err)
- assert.NotNil(t, verificationRequest)
- verifyRes, err := resolvers.VerifyEmailResolver(ctx, model.VerifyEmailInput{
- Token: verificationRequest.Token,
- })
- assert.NoError(t, err)
- assert.NotNil(t, verifyRes)
- accessToken := *verifyRes.AccessToken
- assert.NotEmpty(t, accessToken)
-
- claims, err := token.ParseJWTToken(accessToken)
- assert.NoError(t, err)
- assert.NotEmpty(t, claims)
-
- sessionKey := constants.AuthRecipeMethodBasicAuth + ":" + verifyRes.User.ID
- sessionToken, err := memorystore.Provider.GetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+claims["nonce"].(string))
- assert.NoError(t, err)
- assert.NotEmpty(t, sessionToken)
-
- cookie := fmt.Sprintf("%s=%s;", constants.AppCookieName+"_session", sessionToken)
- cookie = strings.TrimSuffix(cookie, ";")
-
- req.Header.Set("Cookie", cookie)
- _, err = resolvers.SessionResolver(ctx, &model.SessionQueryInput{})
- assert.Nil(t, err)
-
- cleanData(email)
- })
-}
diff --git a/server/test/signup_test.go b/server/test/signup_test.go
deleted file mode 100644
index ec8cdb36b..000000000
--- a/server/test/signup_test.go
+++ /dev/null
@@ -1,68 +0,0 @@
-package test
-
-import (
- "testing"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/refs"
- "github.com/authorizerdev/authorizer/server/resolvers"
- "github.com/stretchr/testify/assert"
-)
-
-func signupTests(t *testing.T, s TestSetup) {
- t.Helper()
- t.Run(`should complete the signup and check duplicates`, func(t *testing.T) {
- _, ctx := createContext(s)
- email := "signup." + s.TestInfo.Email
- res, err := resolvers.SignupResolver(ctx, model.SignUpInput{
- Email: refs.NewStringRef(email),
- Password: s.TestInfo.Password,
- ConfirmPassword: s.TestInfo.Password + "s",
- })
- assert.NotNil(t, err, "invalid password")
- assert.Nil(t, res)
- res, err = resolvers.SignupResolver(ctx, model.SignUpInput{
- Email: refs.NewStringRef(email),
- Password: "test",
- ConfirmPassword: "test",
- })
- assert.NotNil(t, err, "invalid password")
- assert.Nil(t, res)
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDisableSignUp, true)
- res, err = resolvers.SignupResolver(ctx, model.SignUpInput{
- Email: refs.NewStringRef(email),
- Password: s.TestInfo.Password,
- ConfirmPassword: s.TestInfo.Password,
- })
- assert.NotNil(t, err, "signup disabled")
- assert.Nil(t, res)
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDisableSignUp, false)
- res, err = resolvers.SignupResolver(ctx, model.SignUpInput{
- Email: refs.NewStringRef(email),
- Password: s.TestInfo.Password,
- ConfirmPassword: s.TestInfo.Password,
- AppData: map[string]interface{}{
- "test": "test",
- },
- })
- assert.Nil(t, err, "signup should be successful")
- user := *res.User
- assert.Equal(t, email, refs.StringValue(user.Email))
- assert.Equal(t, "test", user.AppData["test"])
- assert.Nil(t, res.AccessToken, "access token should be nil")
- res, err = resolvers.SignupResolver(ctx, model.SignUpInput{
- Email: refs.NewStringRef(email),
- Password: s.TestInfo.Password,
- ConfirmPassword: s.TestInfo.Password,
- })
- assert.NotNil(t, err, "should throw duplicate email error")
- assert.Nil(t, res)
- verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeBasicAuthSignup)
- assert.Nil(t, err)
- assert.Equal(t, email, verificationRequest.Email)
- cleanData(email)
- })
-}
diff --git a/server/test/test.go b/server/test/test.go
deleted file mode 100644
index 524aeb4b1..000000000
--- a/server/test/test.go
+++ /dev/null
@@ -1,159 +0,0 @@
-package test
-
-import (
- "context"
- "fmt"
- "net/http"
- "net/http/httptest"
- "os"
- "time"
-
- log "github.com/sirupsen/logrus"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/env"
- "github.com/authorizerdev/authorizer/server/handlers"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/middlewares"
- "github.com/gin-gonic/gin"
-)
-
-// common user data to share across tests
-type TestData struct {
- Email string
- Password string
- WebhookEndpoint string
- TestWebhookEventTypes []string
- TestEmailTemplateEventTypes []string
-}
-
-type TestSetup struct {
- GinEngine *gin.Engine
- GinContext *gin.Context
- Server *httptest.Server
- TestInfo TestData
-}
-
-func cleanData(email string) {
- ctx := context.Background()
- verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeBasicAuthSignup)
- if err == nil {
- err = db.Provider.DeleteVerificationRequest(ctx, verificationRequest)
- if err != nil {
- log.Debug("DeleteVerificationRequest err", err)
- }
- }
-
- verificationRequest, err = db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeForgotPassword)
- if err == nil {
- err = db.Provider.DeleteVerificationRequest(ctx, verificationRequest)
- if err != nil {
- log.Debug("DeleteVerificationRequest err", err)
- }
- }
-
- verificationRequest, err = db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeUpdateEmail)
- if err == nil {
- err = db.Provider.DeleteVerificationRequest(ctx, verificationRequest)
- if err != nil {
- log.Debug("DeleteVerificationRequest err", err)
- }
- }
-
- verificationRequest, err = db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeMagicLinkLogin)
- if err == nil {
- err = db.Provider.DeleteVerificationRequest(ctx, verificationRequest)
- if err != nil {
- log.Debug("DeleteVerificationRequest err", err)
- }
- }
-
- otp, err := db.Provider.GetOTPByEmail(ctx, email)
- if err == nil {
- err = db.Provider.DeleteOTP(ctx, otp)
- if err != nil {
- log.Debug("DeleteOTP err", err)
- }
- }
-
- dbUser, err := db.Provider.GetUserByEmail(ctx, email)
- if err == nil {
- err = db.Provider.DeleteUser(ctx, dbUser)
- if err != nil {
- log.Debug("DeleteUser err", err)
- }
- }
-}
-
-func createContext(s TestSetup) (*http.Request, context.Context) {
- req, _ := http.NewRequest(
- "POST",
- "http://"+s.Server.Listener.Addr().String()+"/graphql",
- nil,
- )
-
- ctx := context.WithValue(req.Context(), "GinContextKey", s.GinContext)
- s.GinContext.Request = req
- return req, ctx
-}
-
-func testSetup() TestSetup {
- testData := TestData{
- Email: fmt.Sprintf("%d_authorizer_tester@yopmail.com", time.Now().Unix()),
- Password: "Test@123",
- WebhookEndpoint: "https://62f93101e05644803533cf36.mockapi.io/authorizer/webhook",
- TestWebhookEventTypes: []string{constants.UserAccessEnabledWebhookEvent, constants.UserAccessRevokedWebhookEvent, constants.UserCreatedWebhookEvent, constants.UserDeletedWebhookEvent, constants.UserLoginWebhookEvent, constants.UserSignUpWebhookEvent, constants.UserDeactivatedWebhookEvent},
- TestEmailTemplateEventTypes: []string{constants.VerificationTypeBasicAuthSignup, constants.VerificationTypeForgotPassword, constants.VerificationTypeMagicLinkLogin, constants.VerificationTypeUpdateEmail},
- }
-
- err := os.Setenv(constants.EnvKeyEnvPath, "../../.env.test")
- if err != nil {
- log.Fatal("Error loading .env.sample file")
- }
- err = memorystore.InitRequiredEnv()
- if err != nil {
- log.Fatal("Error loading required env: ", err)
- }
-
- err = memorystore.InitMemStore()
- if err != nil {
- log.Fatal("Error loading memory store: ", err)
- }
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeySmtpHost, "smtp.yopmail.com")
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeySmtpPort, "2525")
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeySmtpUsername, "lakhan@yopmail.com")
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeySmtpPassword, "test")
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeySenderEmail, "info@yopmail.com")
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyProtectedRoles, "admin")
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyTwilioAPIKey, "test")
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyTwilioAPISecret, "test")
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyTwilioAccountSID, "test")
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyTwilioSender, "1234567890")
-
- err = db.InitDB()
- if err != nil {
- log.Fatal("Error loading db: ", err)
- }
-
- err = env.InitAllEnv()
- if err != nil {
- log.Fatal("Error loading env: ", err)
- }
-
- w := httptest.NewRecorder()
- c, r := gin.CreateTestContext(w)
- r.Use(middlewares.GinContextToContextMiddleware())
- r.Use(middlewares.CORSMiddleware())
-
- r.POST("/graphql", handlers.GraphqlHandler())
-
- server := httptest.NewServer(r)
-
- return TestSetup{
- GinEngine: r,
- GinContext: c,
- Server: server,
- TestInfo: testData,
- }
-}
diff --git a/server/test/test_endpoint_test.go b/server/test/test_endpoint_test.go
deleted file mode 100644
index 1b29395ac..000000000
--- a/server/test/test_endpoint_test.go
+++ /dev/null
@@ -1,37 +0,0 @@
-package test
-
-import (
- "fmt"
- "testing"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/crypto"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/resolvers"
- "github.com/stretchr/testify/assert"
-)
-
-func testEndpointTest(t *testing.T, s TestSetup) {
- t.Helper()
- t.Run("should test endpoint", func(t *testing.T) {
- req, ctx := createContext(s)
- adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
- assert.NoError(t, err)
- h, err := crypto.EncryptPassword(adminSecret)
- assert.NoError(t, err)
- req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
-
- res, err := resolvers.TestEndpointResolver(ctx, model.TestEndpointRequest{
- Endpoint: s.TestInfo.WebhookEndpoint,
- EventName: constants.UserLoginWebhookEvent,
- Headers: map[string]interface{}{
- "x-test": "test",
- },
- })
- assert.NoError(t, err)
- assert.NotNil(t, res)
- assert.GreaterOrEqual(t, *res.HTTPStatus, int64(200))
- assert.NotEmpty(t, res.Response)
- })
-}
diff --git a/server/test/totp_login_test.go b/server/test/totp_login_test.go
deleted file mode 100644
index 3b9321ef7..000000000
--- a/server/test/totp_login_test.go
+++ /dev/null
@@ -1,164 +0,0 @@
-package test
-
-import (
- "bytes"
- "context"
- "encoding/base64"
- "fmt"
- "strings"
- "testing"
- "time"
-
- "github.com/authorizerdev/authorizer/server/authenticators"
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/refs"
- "github.com/authorizerdev/authorizer/server/resolvers"
- "github.com/authorizerdev/authorizer/server/token"
- "github.com/gokyle/twofactor"
- "github.com/google/uuid"
- "github.com/stretchr/testify/assert"
- "github.com/tuotoo/qrcode"
-)
-
-func totpLoginTest(t *testing.T, s TestSetup) {
- t.Helper()
- t.Run(`should verify totp`, func(t *testing.T) {
- req, ctx := createContext(s)
- email := "verify_totp." + s.TestInfo.Email
- cleanData(email)
- res, err := resolvers.SignupResolver(ctx, model.SignUpInput{
- Email: &email,
- Password: s.TestInfo.Password,
- ConfirmPassword: s.TestInfo.Password,
- })
- assert.NoError(t, err)
- assert.NotNil(t, res)
-
- // Login should fail as email is not verified
- loginRes, err := resolvers.LoginResolver(ctx, model.LoginInput{
- Email: &email,
- Password: s.TestInfo.Password,
- })
- // access token should be empty as email is not verified
- assert.NoError(t, err)
- assert.NotNil(t, loginRes)
- assert.Nil(t, loginRes.AccessToken)
- assert.NotEmpty(t, loginRes.Message)
- verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeBasicAuthSignup)
- assert.Nil(t, err)
- assert.Equal(t, email, verificationRequest.Email)
- verifyRes, err := resolvers.VerifyEmailResolver(ctx, model.VerifyEmailInput{
- Token: verificationRequest.Token,
- })
- assert.Nil(t, err)
- assert.NotEqual(t, verifyRes.AccessToken, "", "access token should not be empty")
-
- // Using access token update profile
- s.GinContext.Request.Header.Set("Authorization", "Bearer "+refs.StringValue(verifyRes.AccessToken))
- ctx = context.WithValue(req.Context(), "GinContextKey", s.GinContext)
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDisableTOTPLogin, false)
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDisableMailOTPLogin, true)
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDisablePhoneVerification, true)
- updateProfileRes, err := resolvers.UpdateProfileResolver(ctx, model.UpdateProfileInput{
- IsMultiFactorAuthEnabled: refs.NewBoolRef(true),
- })
- assert.NoError(t, err)
- assert.NotEmpty(t, updateProfileRes.Message)
-
- authenticators.InitTOTPStore()
- // Login should not return error but access token should be empty
- loginRes, err = resolvers.LoginResolver(ctx, model.LoginInput{
- Email: &email,
- Password: s.TestInfo.Password,
- })
- assert.NoError(t, err)
- assert.NotNil(t, loginRes)
- assert.True(t, *loginRes.ShouldShowTotpScreen)
- assert.NotNil(t, *loginRes.AuthenticatorScannerImage)
- assert.NotNil(t, *loginRes.AuthenticatorSecret)
- assert.NotNil(t, loginRes.AuthenticatorRecoveryCodes)
- assert.Nil(t, loginRes.AccessToken)
- assert.NotEmpty(t, loginRes.Message)
-
- // get totp url for validation
- pngBytes, err := base64.StdEncoding.DecodeString(*loginRes.AuthenticatorScannerImage)
- assert.NoError(t, err)
- qrmatrix, err := qrcode.Decode(bytes.NewReader(pngBytes))
- assert.NoError(t, err)
- tf, label, err := twofactor.FromURL(qrmatrix.Content)
- data := strings.Split(label, ":")
- assert.NoError(t, err)
- assert.Equal(t, email, data[1])
- assert.NotNil(t, tf)
- code := tf.OTP()
- assert.NotEmpty(t, code)
-
- // Set mfa cookie session
- mfaSession := uuid.NewString()
- memorystore.Provider.SetMfaSession(verifyRes.User.ID, mfaSession, time.Now().Add(1*time.Minute).Unix())
- cookie := fmt.Sprintf("%s=%s;", constants.MfaCookieName+"_session", mfaSession)
- cookie = strings.TrimSuffix(cookie, ";")
- req.Header.Set("Cookie", cookie)
- valid, err := resolvers.VerifyOtpResolver(ctx, model.VerifyOTPRequest{
- Email: &email,
- IsTotp: refs.NewBoolRef(true),
- Otp: code,
- })
- accessToken := valid.AccessToken
- assert.NoError(t, err)
- assert.NotNil(t, accessToken)
- assert.NotEmpty(t, valid.Message)
- assert.NotEmpty(t, accessToken)
- claims, err := token.ParseJWTToken(*accessToken)
- assert.NoError(t, err)
- assert.NotEmpty(t, claims)
- loginMethod := claims["login_method"]
- sessionKey := verifyRes.User.ID
- if loginMethod != nil && loginMethod != "" {
- sessionKey = loginMethod.(string) + ":" + verifyRes.User.ID
- }
- sessionToken, err := memorystore.Provider.GetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+claims["nonce"].(string))
- assert.NoError(t, err)
- assert.NotEmpty(t, sessionToken)
- cookie = fmt.Sprintf("%s=%s;", constants.AppCookieName+"_session", sessionToken)
- cookie = strings.TrimSuffix(cookie, ";")
- req.Header.Set("Cookie", cookie)
-
- //logged out
- logout, err := resolvers.LogoutResolver(ctx)
- assert.NoError(t, err)
- assert.NotEmpty(t, logout.Message)
- loginRes, err = resolvers.LoginResolver(ctx, model.LoginInput{
- Email: &email,
- Password: s.TestInfo.Password,
- })
- assert.NoError(t, err)
- assert.NotNil(t, loginRes)
- assert.Nil(t, loginRes.AuthenticatorRecoveryCodes)
- assert.Nil(t, loginRes.AccessToken)
- assert.Nil(t, loginRes.AuthenticatorScannerImage)
- assert.Nil(t, loginRes.AuthenticatorSecret)
- assert.True(t, *loginRes.ShouldShowTotpScreen)
- assert.NotEmpty(t, loginRes.Message)
- code = tf.OTP()
- assert.NotEmpty(t, code)
- // Set mfa cookie session
- mfaSession = uuid.NewString()
- memorystore.Provider.SetMfaSession(verifyRes.User.ID, mfaSession, time.Now().Add(1*time.Minute).Unix())
- cookie = fmt.Sprintf("%s=%s;", constants.MfaCookieName+"_session", mfaSession)
- cookie = strings.TrimSuffix(cookie, ";")
- req.Header.Set("Cookie", cookie)
- valid, err = resolvers.VerifyOtpResolver(ctx, model.VerifyOTPRequest{
- Otp: code,
- Email: &email,
- IsTotp: refs.NewBoolRef(true),
- })
- assert.NoError(t, err)
- assert.NotNil(t, *valid.AccessToken)
- assert.NotEmpty(t, valid.Message)
- cleanData(email)
- })
-}
diff --git a/server/test/totp_signup_test.go b/server/test/totp_signup_test.go
deleted file mode 100644
index 6dc5a0d3c..000000000
--- a/server/test/totp_signup_test.go
+++ /dev/null
@@ -1,187 +0,0 @@
-package test
-
-import (
- "bytes"
- "encoding/base64"
- "fmt"
- "strings"
- "testing"
- "time"
-
- "github.com/authorizerdev/authorizer/server/authenticators"
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/refs"
- "github.com/authorizerdev/authorizer/server/resolvers"
- "github.com/authorizerdev/authorizer/server/token"
- "github.com/gokyle/twofactor"
- "github.com/google/uuid"
- "github.com/stretchr/testify/assert"
- "github.com/tuotoo/qrcode"
-)
-
-func totpSignupTest(t *testing.T, s TestSetup) {
- t.Helper()
- // Test case to verify TOTP for signup
- t.Run(`should verify totp for signup`, func(t *testing.T) {
- // Create request and context using test setup
- req, ctx := createContext(s)
- email := "verify_totp." + s.TestInfo.Email
-
- // Test case: Invalid password (confirm password mismatch)
- res, err := resolvers.SignupResolver(ctx, model.SignUpInput{
- Email: refs.NewStringRef(email),
- Password: s.TestInfo.Password,
- ConfirmPassword: s.TestInfo.Password + "s",
- })
- assert.NotNil(t, err, "invalid password")
- assert.Nil(t, res)
-
- {
- // Test case: Invalid password ("test" as the password)
- res, err = resolvers.SignupResolver(ctx, model.SignUpInput{
- Email: refs.NewStringRef(email),
- Password: "test",
- ConfirmPassword: "test",
- })
- assert.NotNil(t, err, "invalid password")
- assert.Nil(t, res)
- }
-
- {
- // Test case: Signup disabled
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDisableSignUp, true)
- res, err = resolvers.SignupResolver(ctx, model.SignUpInput{
- Email: refs.NewStringRef(email),
- Password: s.TestInfo.Password,
- ConfirmPassword: s.TestInfo.Password,
- })
- assert.NotNil(t, err, "signup disabled")
- assert.Nil(t, res)
- }
-
- {
- // Test case: Successful signup
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDisableSignUp, false)
- res, err = resolvers.SignupResolver(ctx, model.SignUpInput{
- Email: refs.NewStringRef(email),
- Password: s.TestInfo.Password,
- ConfirmPassword: s.TestInfo.Password,
- AppData: map[string]interface{}{
- "test": "test",
- },
- })
- assert.Nil(t, err, "signup should be successful")
- user := *res.User
- assert.Equal(t, email, refs.StringValue(user.Email))
- assert.Equal(t, "test", user.AppData["test"])
- assert.Nil(t, res.AccessToken, "access token should be nil")
- }
-
- {
- // Test case: Duplicate email (should throw an error)
- res, err = resolvers.SignupResolver(ctx, model.SignUpInput{
- Email: refs.NewStringRef(email),
- Password: s.TestInfo.Password,
- ConfirmPassword: s.TestInfo.Password,
- })
- assert.NotNil(t, err, "should throw duplicate email error")
- assert.Nil(t, res)
- }
-
- // Clean up data for the email
- cleanData(email)
-
- {
- // Test case: Email verification and TOTP setup
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDisableEmailVerification, false)
-
- // Sign up a user
- res, err := resolvers.SignupResolver(ctx, model.SignUpInput{
- Email: refs.NewStringRef(email),
- Password: s.TestInfo.Password,
- ConfirmPassword: s.TestInfo.Password,
- })
- assert.Nil(t, err, "Expected no error but got: %v", err)
- assert.Equal(t, "Verification email has been sent. Please check your inbox", res.Message)
-
- // Retrieve user and update for TOTP setup
- user, err := db.Provider.GetUserByID(ctx, res.User.ID)
- assert.Nil(t, err, "Expected no error but got: %v", err)
- assert.NotNil(t, user)
-
- // Enable multi-factor authentication and update the user
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDisableTOTPLogin, false)
- user.IsMultiFactorAuthEnabled = refs.NewBoolRef(true)
- updatedUser, err := db.Provider.UpdateUser(ctx, user)
- assert.Nil(t, err, "Expected no error but got: %v", err)
- assert.Equal(t, true, *updatedUser.IsMultiFactorAuthEnabled)
-
- // Initialise totp authenticator store
- authenticators.InitTOTPStore()
-
- // Verify an email and get TOTP response
- verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeBasicAuthSignup)
- assert.Nil(t, err)
- assert.Equal(t, email, verificationRequest.Email)
- verifyRes, err := resolvers.VerifyEmailResolver(ctx, model.VerifyEmailInput{
- Token: verificationRequest.Token,
- })
- assert.Nil(t, err, "Expected no error but got: %v", err)
- assert.NotNil(t, &verifyRes)
- assert.Nil(t, verifyRes.AccessToken)
- assert.Equal(t, "Proceed to totp verification screen", verifyRes.Message)
- assert.NotEqual(t, *verifyRes.AuthenticatorScannerImage, "", "totp url should not be empty")
- assert.NotEqual(t, *verifyRes.AuthenticatorSecret, "", "totp secret should not be empty")
- assert.NotNil(t, verifyRes.AuthenticatorRecoveryCodes)
-
- // Get TOTP URL for for validation
- pngBytes, err := base64.StdEncoding.DecodeString(*verifyRes.AuthenticatorScannerImage)
- assert.NoError(t, err)
- qrmatrix, err := qrcode.Decode(bytes.NewReader(pngBytes))
- assert.NoError(t, err)
- tf, label, err := twofactor.FromURL(qrmatrix.Content)
- data := strings.Split(label, ":")
- assert.NoError(t, err)
- assert.Equal(t, email, data[1])
- assert.NotNil(t, tf)
- code := tf.OTP()
- assert.NotEmpty(t, code)
-
- // Set MFA cookie session
- mfaSession := uuid.NewString()
- memorystore.Provider.SetMfaSession(res.User.ID, mfaSession, time.Now().Add(1*time.Minute).Unix())
- cookie := fmt.Sprintf("%s=%s;", constants.MfaCookieName+"_session", mfaSession)
- cookie = strings.TrimSuffix(cookie, ";")
- req.Header.Set("Cookie", cookie)
- valid, err := resolvers.VerifyOtpResolver(ctx, model.VerifyOTPRequest{
- Email: &email,
- IsTotp: refs.NewBoolRef(true),
- Otp: code,
- })
- accessToken := *valid.AccessToken
- assert.NoError(t, err)
- assert.NotNil(t, accessToken)
- assert.NotEmpty(t, valid.Message)
- assert.NotEmpty(t, accessToken)
- claims, err := token.ParseJWTToken(accessToken)
- assert.NoError(t, err)
- assert.NotEmpty(t, claims)
- signUpMethod := claims["login_method"]
- sessionKey := res.User.ID
- if signUpMethod != nil && signUpMethod != "" {
- sessionKey = signUpMethod.(string) + ":" + res.User.ID
- }
- sessionToken, err := memorystore.Provider.GetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+claims["nonce"].(string))
- assert.NoError(t, err)
- assert.NotEmpty(t, sessionToken)
- cookie = fmt.Sprintf("%s=%s;", constants.AppCookieName+"_session", sessionToken)
- cookie = strings.TrimSuffix(cookie, ";")
- req.Header.Set("Cookie", cookie)
- }
- // Clean up data for the email
- cleanData(email)
- })
-}
diff --git a/server/test/update_all_users_tests.go b/server/test/update_all_users_tests.go
deleted file mode 100644
index f3cc82fc7..000000000
--- a/server/test/update_all_users_tests.go
+++ /dev/null
@@ -1,67 +0,0 @@
-package test
-
-import (
- "fmt"
- "testing"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/db/models"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/refs"
- "github.com/authorizerdev/authorizer/server/utils"
- "github.com/stretchr/testify/assert"
-)
-
-func updateAllUsersTest(t *testing.T, s TestSetup) {
- t.Helper()
- t.Run("Should update all users", func(t *testing.T) {
- _, ctx := createContext(s)
- for i := 0; i < 10; i++ {
- user := &models.User{
- Email: refs.NewStringRef(fmt.Sprintf("update_all_user_%d_%s", i, s.TestInfo.Email)),
- SignupMethods: constants.AuthRecipeMethodBasicAuth,
- Roles: "user",
- }
- u, err := db.Provider.AddUser(ctx, user)
- assert.NoError(t, err)
- assert.NotNil(t, u)
- }
-
- err := db.Provider.UpdateUsers(ctx, map[string]interface{}{
- "is_multi_factor_auth_enabled": true,
- }, nil)
- assert.NoError(t, err)
-
- listUsers, err := db.Provider.ListUsers(ctx, &model.Pagination{
- Limit: 20,
- Offset: 0,
- })
- assert.NoError(t, err)
- assert.Greater(t, len(listUsers.Users), 0)
- for _, u := range listUsers.Users {
- assert.True(t, refs.BoolValue(u.IsMultiFactorAuthEnabled))
- }
- // // update few users
- updateIds := []string{listUsers.Users[0].ID, listUsers.Users[1].ID}
- err = db.Provider.UpdateUsers(ctx, map[string]interface{}{
- "is_multi_factor_auth_enabled": false,
- }, updateIds)
- assert.NoError(t, err)
- listUsers, err = db.Provider.ListUsers(ctx, &model.Pagination{
- Limit: 20,
- Offset: 0,
- })
- assert.NoError(t, err)
- assert.NotNil(t, listUsers)
- assert.Greater(t, len(listUsers.Users), 0)
- for _, u := range listUsers.Users {
- if utils.StringSliceContains(updateIds, u.ID) {
- assert.False(t, refs.BoolValue(u.IsMultiFactorAuthEnabled))
- } else {
- assert.True(t, refs.BoolValue(u.IsMultiFactorAuthEnabled))
- }
- cleanData(refs.StringValue(u.Email))
- }
- })
-}
diff --git a/server/test/update_email_template_test.go b/server/test/update_email_template_test.go
deleted file mode 100644
index 94b9de53c..000000000
--- a/server/test/update_email_template_test.go
+++ /dev/null
@@ -1,50 +0,0 @@
-package test
-
-import (
- "fmt"
- "testing"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/crypto"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/refs"
- "github.com/authorizerdev/authorizer/server/resolvers"
- "github.com/stretchr/testify/assert"
-)
-
-func updateEmailTemplateTest(t *testing.T, s TestSetup) {
- t.Helper()
- t.Run("should update email template", func(t *testing.T) {
- req, ctx := createContext(s)
- adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
- assert.NoError(t, err)
- h, err := crypto.EncryptPassword(adminSecret)
- assert.NoError(t, err)
- req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
- // get email template
- emailTemplate, err := db.Provider.GetEmailTemplateByEventName(ctx, constants.VerificationTypeBasicAuthSignup)
- assert.NoError(t, err)
- assert.NotNil(t, emailTemplate)
-
- res, err := resolvers.UpdateEmailTemplateResolver(ctx, model.UpdateEmailTemplateRequest{
- ID: emailTemplate.ID,
- Template: refs.NewStringRef("Updated test template"),
- Subject: refs.NewStringRef("Updated subject"),
- Design: refs.NewStringRef("Updated design"),
- })
-
- assert.NoError(t, err)
- assert.NotEmpty(t, res)
- assert.NotEmpty(t, res.Message)
-
- updatedEmailTemplate, err := db.Provider.GetEmailTemplateByEventName(ctx, constants.VerificationTypeBasicAuthSignup)
- assert.NoError(t, err)
- assert.NotNil(t, updatedEmailTemplate)
- assert.Equal(t, emailTemplate.ID, updatedEmailTemplate.ID)
- assert.Equal(t, updatedEmailTemplate.Template, "Updated test template")
- assert.Equal(t, updatedEmailTemplate.Subject, "Updated subject")
- assert.Equal(t, updatedEmailTemplate.Design, "Updated design")
- })
-}
diff --git a/server/test/update_env_test.go b/server/test/update_env_test.go
deleted file mode 100644
index c602b4a8a..000000000
--- a/server/test/update_env_test.go
+++ /dev/null
@@ -1,66 +0,0 @@
-package test
-
-import (
- "fmt"
- "strings"
- "testing"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/crypto"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/resolvers"
- "github.com/stretchr/testify/assert"
-)
-
-func updateEnvTests(t *testing.T, s TestSetup) {
- t.Helper()
- t.Run(`should update envs`, func(t *testing.T) {
- req, ctx := createContext(s)
- originalAppURL, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAppURL)
- assert.Nil(t, err)
-
- data := model.UpdateEnvInput{}
- _, err = resolvers.UpdateEnvResolver(ctx, data)
-
- assert.NotNil(t, err)
-
- adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
- assert.Nil(t, err)
- h, err := crypto.EncryptPassword(adminSecret)
- assert.Nil(t, err)
- req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
- newURL := "https://test.com"
- disableLoginPage := true
- allowedOrigins := []string{"http://localhost:8080"}
- data = model.UpdateEnvInput{
- AppURL: &newURL,
- DisableLoginPage: &disableLoginPage,
- AllowedOrigins: allowedOrigins,
- }
- _, err = resolvers.UpdateEnvResolver(ctx, data)
- assert.Nil(t, err)
-
- appURL, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAppURL)
- assert.Nil(t, err)
- assert.Equal(t, appURL, newURL)
-
- isLoginPageDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableLoginPage)
- assert.Nil(t, err)
- assert.True(t, isLoginPageDisabled)
-
- storedOriginsStrings, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAllowedOrigins)
- assert.Nil(t, err)
- storedOrigins := strings.Split(storedOriginsStrings, ",")
- assert.Equal(t, storedOrigins, allowedOrigins)
-
- disableLoginPage = false
- data = model.UpdateEnvInput{
- AppURL: &originalAppURL,
- DisableLoginPage: &disableLoginPage,
- AllowedOrigins: []string{"*"},
- }
- _, err = resolvers.UpdateEnvResolver(ctx, data)
- assert.Nil(t, err)
- })
-}
diff --git a/server/test/update_profile_test.go b/server/test/update_profile_test.go
deleted file mode 100644
index 12a0ab550..000000000
--- a/server/test/update_profile_test.go
+++ /dev/null
@@ -1,56 +0,0 @@
-package test
-
-import (
- "context"
- "testing"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/refs"
- "github.com/authorizerdev/authorizer/server/resolvers"
- "github.com/stretchr/testify/assert"
-)
-
-func updateProfileTests(t *testing.T, s TestSetup) {
- t.Helper()
- t.Run(`should update the profile with access token only`, func(t *testing.T) {
- req, ctx := createContext(s)
- email := "update_profile." + s.TestInfo.Email
-
- resolvers.SignupResolver(ctx, model.SignUpInput{
- Email: refs.NewStringRef(email),
- Password: s.TestInfo.Password,
- ConfirmPassword: s.TestInfo.Password,
- })
-
- fName := "samani"
- _, err := resolvers.UpdateProfileResolver(ctx, model.UpdateProfileInput{
- FamilyName: &fName,
- })
- assert.NotNil(t, err, "unauthorized")
-
- verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeBasicAuthSignup)
- assert.NoError(t, err)
- assert.NotNil(t, verificationRequest)
- verifyRes, err := resolvers.VerifyEmailResolver(ctx, model.VerifyEmailInput{
- Token: verificationRequest.Token,
- })
- assert.NoError(t, err)
- assert.NotNil(t, verifyRes)
- s.GinContext.Request.Header.Set("Authorization", "Bearer "+*verifyRes.AccessToken)
- ctx = context.WithValue(req.Context(), "GinContextKey", s.GinContext)
-
- newEmail := "new_" + email
- _, err = resolvers.UpdateProfileResolver(ctx, model.UpdateProfileInput{
- Email: &newEmail,
- })
- s.GinContext.Request.Header.Set("Authorization", "")
- assert.Nil(t, err)
- _, err = resolvers.ProfileResolver(ctx)
- assert.NotNil(t, err, "unauthorized")
-
- cleanData(newEmail)
- cleanData(email)
- })
-}
diff --git a/server/test/update_user_test.go b/server/test/update_user_test.go
deleted file mode 100644
index eab173112..000000000
--- a/server/test/update_user_test.go
+++ /dev/null
@@ -1,69 +0,0 @@
-package test
-
-import (
- "fmt"
- "testing"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/crypto"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/refs"
- "github.com/authorizerdev/authorizer/server/resolvers"
- "github.com/stretchr/testify/assert"
-)
-
-func updateUserTest(t *testing.T, s TestSetup) {
- t.Helper()
- t.Run(`should update the user with admin secret only`, func(t *testing.T) {
- req, ctx := createContext(s)
- email := "update_user." + s.TestInfo.Email
- signupRes, _ := resolvers.SignupResolver(ctx, model.SignUpInput{
- Email: refs.NewStringRef(email),
- Password: s.TestInfo.Password,
- ConfirmPassword: s.TestInfo.Password,
- })
-
- user := *signupRes.User
-
- adminRole := "supplier"
- userRole := "user"
- newRoles := []*string{&adminRole, &userRole}
- _, err := resolvers.UpdateUserResolver(ctx, model.UpdateUserInput{
- ID: user.ID,
- Roles: newRoles,
- })
- assert.NotNil(t, err, "unauthorized")
- adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
- assert.Nil(t, err)
- h, err := crypto.EncryptPassword(adminSecret)
- assert.Nil(t, err)
- req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
- _, err = resolvers.UpdateUserResolver(ctx, model.UpdateUserInput{
- ID: user.ID,
- Roles: newRoles,
- })
- // supplier is not part of envs
- assert.Error(t, err)
- adminRole = "admin"
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyProtectedRoles, adminRole)
- newRoles = []*string{&adminRole, &userRole}
- _, err = resolvers.UpdateUserResolver(ctx, model.UpdateUserInput{
- ID: user.ID,
- Roles: newRoles,
- AppData: map[string]interface{}{
- "test": "test",
- },
- })
- assert.Nil(t, err)
- // Get user and check if roles are updated
- users, err := resolvers.UsersResolver(ctx, nil)
- assert.Nil(t, err)
- for _, u := range users.Users {
- if u.ID == user.ID {
- assert.Equal(t, u.AppData["test"], "test")
- }
- }
- cleanData(email)
- })
-}
diff --git a/server/test/update_webhook_test.go b/server/test/update_webhook_test.go
deleted file mode 100644
index 6e2d023b4..000000000
--- a/server/test/update_webhook_test.go
+++ /dev/null
@@ -1,96 +0,0 @@
-package test
-
-import (
- "fmt"
- "testing"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/crypto"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/refs"
- "github.com/authorizerdev/authorizer/server/resolvers"
- "github.com/stretchr/testify/assert"
-)
-
-func updateWebhookTest(t *testing.T, s TestSetup) {
- t.Helper()
- t.Run("should update webhook", func(t *testing.T) {
- req, ctx := createContext(s)
- adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
- assert.NoError(t, err)
- h, err := crypto.EncryptPassword(adminSecret)
- assert.NoError(t, err)
- req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
- // get webhook
- webhooks, err := db.Provider.GetWebhookByEventName(ctx, constants.UserDeletedWebhookEvent)
- assert.NoError(t, err)
- assert.NotNil(t, webhooks)
- assert.GreaterOrEqual(t, len(webhooks), 2)
- for _, webhook := range webhooks {
- // it should completely replace headers
- webhook.Headers = map[string]interface{}{
- "x-new-test": "test",
- }
- res, err := resolvers.UpdateWebhookResolver(ctx, model.UpdateWebhookRequest{
- ID: webhook.ID,
- Headers: webhook.Headers,
- Enabled: refs.NewBoolRef(false),
- Endpoint: refs.NewStringRef("https://sometest.com"),
- })
- assert.NoError(t, err)
- assert.NotEmpty(t, res)
- assert.NotEmpty(t, res.Message)
- }
- if len(webhooks) == 0 {
- // avoid index out of range error
- return
- }
- // Test updating webhook name
- w := webhooks[0]
- res, err := resolvers.UpdateWebhookResolver(ctx, model.UpdateWebhookRequest{
- ID: w.ID,
- EventName: refs.NewStringRef(constants.UserAccessEnabledWebhookEvent),
- })
- assert.NoError(t, err)
- assert.NotNil(t, res)
- // Check if webhooks with new name is as per expected len
- accessWebhooks, err := db.Provider.GetWebhookByEventName(ctx, constants.UserAccessEnabledWebhookEvent)
- assert.NoError(t, err)
- assert.GreaterOrEqual(t, len(accessWebhooks), 3)
- // Revert name change
- res, err = resolvers.UpdateWebhookResolver(ctx, model.UpdateWebhookRequest{
- ID: w.ID,
- EventName: refs.NewStringRef(constants.UserDeletedWebhookEvent),
- })
- assert.NoError(t, err)
- assert.NotNil(t, res)
- updatedWebhooks, err := db.Provider.GetWebhookByEventName(ctx, constants.UserDeletedWebhookEvent)
- assert.NoError(t, err)
- assert.NotNil(t, updatedWebhooks)
- assert.GreaterOrEqual(t, len(updatedWebhooks), 2)
- for _, updatedWebhook := range updatedWebhooks {
- assert.Contains(t, refs.StringValue(updatedWebhook.EventName), constants.UserDeletedWebhookEvent)
- assert.Len(t, updatedWebhook.Headers, 1)
- assert.False(t, refs.BoolValue(updatedWebhook.Enabled))
- foundUpdatedHeader := false
- for key, val := range updatedWebhook.Headers {
- if key == "x-new-test" && val == "test" {
- foundUpdatedHeader = true
- }
- }
- assert.True(t, foundUpdatedHeader)
- assert.Equal(t, "https://sometest.com", refs.StringValue(updatedWebhook.Endpoint))
- res, err := resolvers.UpdateWebhookResolver(ctx, model.UpdateWebhookRequest{
- ID: updatedWebhook.ID,
- Headers: updatedWebhook.Headers,
- Enabled: refs.NewBoolRef(true),
- Endpoint: refs.NewStringRef(s.TestInfo.WebhookEndpoint),
- })
- assert.NoError(t, err)
- assert.NotEmpty(t, res)
- assert.NotEmpty(t, res.Message)
- }
- })
-}
diff --git a/server/test/urls_test.go b/server/test/urls_test.go
deleted file mode 100644
index 3ec2a534d..000000000
--- a/server/test/urls_test.go
+++ /dev/null
@@ -1,27 +0,0 @@
-package test
-
-import (
- "testing"
-
- "github.com/authorizerdev/authorizer/server/parsers"
- "github.com/stretchr/testify/assert"
-)
-
-func TestGetHostName(t *testing.T) {
- url := "http://test.herokuapp.com:80"
-
- host, port := parsers.GetHostParts(url)
- expectedHost := "test.herokuapp.com"
-
- assert.Equal(t, host, expectedHost, "hostname should be equal")
- assert.Equal(t, port, "80", "port should be 80")
-}
-
-func TestGetDomainName(t *testing.T) {
- url := "http://test.herokuapp.com"
-
- got := parsers.GetDomainName(url)
- want := "herokuapp.com"
-
- assert.Equal(t, got, want, "domain name should be equal")
-}
diff --git a/server/test/user_test.go b/server/test/user_test.go
deleted file mode 100644
index 97a870fc9..000000000
--- a/server/test/user_test.go
+++ /dev/null
@@ -1,72 +0,0 @@
-package test
-
-import (
- "fmt"
- "testing"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/crypto"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/refs"
- "github.com/authorizerdev/authorizer/server/resolvers"
- "github.com/stretchr/testify/assert"
-)
-
-func userTest(t *testing.T, s TestSetup) {
- t.Helper()
- t.Run(`should get users list with admin secret only`, func(t *testing.T) {
- req, ctx := createContext(s)
- email := "user." + s.TestInfo.Email
- res, err := resolvers.SignupResolver(ctx, model.SignUpInput{
- Email: refs.NewStringRef(email),
- Password: s.TestInfo.Password,
- ConfirmPassword: s.TestInfo.Password,
- })
- assert.NoError(t, err)
- assert.NotEmpty(t, res.User)
-
- userRes, err := resolvers.UserResolver(ctx, model.GetUserRequest{
- ID: &res.User.ID,
- })
- assert.Nil(t, userRes)
- assert.NotNil(t, err, "unauthorized")
-
- adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
- assert.Nil(t, err)
- h, err := crypto.EncryptPassword(adminSecret)
- assert.Nil(t, err)
- req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
- // Should throw error for invalid params
- userRes, err = resolvers.UserResolver(ctx, model.GetUserRequest{})
- assert.Nil(t, userRes)
- assert.NotNil(t, err, "invalid params, user id or email is required")
- // Should throw error for invalid params with empty id
- userRes, err = resolvers.UserResolver(ctx, model.GetUserRequest{
- ID: refs.NewStringRef(" "),
- })
- assert.Nil(t, userRes)
- assert.NotNil(t, err, "invalid params, user id or email is required")
- // Should throw error for invalid params with empty email
- userRes, err = resolvers.UserResolver(ctx, model.GetUserRequest{
- Email: refs.NewStringRef(" "),
- })
- assert.Nil(t, userRes)
- assert.NotNil(t, err, "invalid params, user id or email is required")
- // Should get user by id
- userRes, err = resolvers.UserResolver(ctx, model.GetUserRequest{
- ID: &res.User.ID,
- })
- assert.Nil(t, err)
- assert.Equal(t, res.User.ID, userRes.ID)
- assert.Equal(t, email, refs.StringValue(userRes.Email))
- // Should get user by email
- userRes, err = resolvers.UserResolver(ctx, model.GetUserRequest{
- Email: &email,
- })
- assert.Nil(t, err)
- assert.Equal(t, res.User.ID, userRes.ID)
- assert.Equal(t, email, refs.StringValue(userRes.Email))
- cleanData(email)
- })
-}
diff --git a/server/test/users_test.go b/server/test/users_test.go
deleted file mode 100644
index 22551ecb4..000000000
--- a/server/test/users_test.go
+++ /dev/null
@@ -1,52 +0,0 @@
-package test
-
-import (
- "fmt"
- "testing"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/crypto"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/refs"
- "github.com/authorizerdev/authorizer/server/resolvers"
- "github.com/stretchr/testify/assert"
-)
-
-func usersTest(t *testing.T, s TestSetup) {
- t.Helper()
- t.Run(`should get users list with admin secret only`, func(t *testing.T) {
- req, ctx := createContext(s)
- email := "users." + s.TestInfo.Email
- resolvers.SignupResolver(ctx, model.SignUpInput{
- Email: refs.NewStringRef(email),
- Password: s.TestInfo.Password,
- ConfirmPassword: s.TestInfo.Password,
- })
-
- limit := int64(10)
- page := int64(1)
- pagination := &model.PaginatedInput{
- Pagination: &model.PaginationInput{
- Limit: &limit,
- Page: &page,
- },
- }
-
- usersRes, err := resolvers.UsersResolver(ctx, pagination)
- assert.NotNil(t, err, "unauthorized")
- assert.Nil(t, usersRes)
- adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
- assert.Nil(t, err)
- h, err := crypto.EncryptPassword(adminSecret)
- assert.Nil(t, err)
- req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
-
- usersRes, err = resolvers.UsersResolver(ctx, pagination)
- assert.Nil(t, err)
- rLen := len(usersRes.Users)
- assert.GreaterOrEqual(t, rLen, 1)
-
- cleanData(email)
- })
-}
diff --git a/server/test/validate_jwt_token_test.go b/server/test/validate_jwt_token_test.go
deleted file mode 100644
index 879cc20e4..000000000
--- a/server/test/validate_jwt_token_test.go
+++ /dev/null
@@ -1,102 +0,0 @@
-package test
-
-import (
- "testing"
- "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/authorizerdev/authorizer/server/refs"
- "github.com/authorizerdev/authorizer/server/resolvers"
- "github.com/authorizerdev/authorizer/server/token"
- "github.com/authorizerdev/authorizer/server/utils"
- "github.com/google/uuid"
- "github.com/stretchr/testify/assert"
-)
-
-func validateJwtTokenTest(t *testing.T, s TestSetup) {
- t.Helper()
- _, ctx := createContext(s)
- t.Run(`validate params`, func(t *testing.T) {
- res, err := resolvers.ValidateJwtTokenResolver(ctx, model.ValidateJWTTokenInput{
- TokenType: "access_token",
- Token: "",
- })
- assert.Error(t, err)
- assert.Nil(t, res)
- res, err = resolvers.ValidateJwtTokenResolver(ctx, model.ValidateJWTTokenInput{
- TokenType: "access_token",
- Token: "invalid",
- })
- assert.Error(t, err)
- assert.Nil(t, res)
- _, err = resolvers.ValidateJwtTokenResolver(ctx, model.ValidateJWTTokenInput{
- TokenType: "access_token_invalid",
- Token: "invalid@invalid",
- })
- assert.Error(t, err, "invalid token")
- })
-
- scope := []string{"openid", "email", "profile", "offline_access"}
- user := &models.User{
- ID: uuid.New().String(),
- Email: refs.NewStringRef("jwt_test_" + s.TestInfo.Email),
- Roles: "user",
- UpdatedAt: time.Now().Unix(),
- CreatedAt: time.Now().Unix(),
- }
-
- roles := []string{"user"}
- gc, err := utils.GinContextFromContext(ctx)
- assert.NoError(t, err)
- sessionKey := constants.AuthRecipeMethodBasicAuth + ":" + user.ID
- nonce := uuid.New().String()
- authToken, err := token.CreateAuthToken(gc, user, roles, scope, constants.AuthRecipeMethodBasicAuth, nonce, "")
- assert.NoError(t, err)
- assert.NotNil(t, authToken)
- memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash, authToken.SessionTokenExpiresAt)
- memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token, authToken.AccessToken.ExpiresAt)
-
- if authToken.RefreshToken != nil {
- memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token, authToken.RefreshToken.ExpiresAt)
- }
-
- t.Run(`should validate the access token`, func(t *testing.T) {
- res, err := resolvers.ValidateJwtTokenResolver(ctx, model.ValidateJWTTokenInput{
- TokenType: "access_token",
- Token: authToken.AccessToken.Token,
- Roles: []string{"user"},
- })
- assert.NoError(t, err)
- assert.True(t, res.IsValid)
-
- res, err = resolvers.ValidateJwtTokenResolver(ctx, model.ValidateJWTTokenInput{
- TokenType: "access_token",
- Token: authToken.AccessToken.Token,
- Roles: []string{"invalid_role"},
- })
- assert.Error(t, err)
- assert.Nil(t, res)
- })
-
- t.Run(`should validate the refresh token`, func(t *testing.T) {
- res, err := resolvers.ValidateJwtTokenResolver(ctx, model.ValidateJWTTokenInput{
- TokenType: "refresh_token",
- Token: authToken.RefreshToken.Token,
- })
- assert.NoError(t, err)
- assert.True(t, res.IsValid)
- })
-
- t.Run(`should validate the id token`, func(t *testing.T) {
- res, err := resolvers.ValidateJwtTokenResolver(ctx, model.ValidateJWTTokenInput{
- TokenType: "id_token",
- Token: authToken.IDToken.Token,
- })
- assert.NoError(t, err)
- assert.True(t, res.IsValid)
- assert.Equal(t, refs.StringValue(user.Email), res.Claims["email"])
- })
-}
diff --git a/server/test/validate_session_test.go b/server/test/validate_session_test.go
deleted file mode 100644
index 9e2cbd5c7..000000000
--- a/server/test/validate_session_test.go
+++ /dev/null
@@ -1,63 +0,0 @@
-package test
-
-import (
- "fmt"
- "strings"
- "testing"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/refs"
- "github.com/authorizerdev/authorizer/server/resolvers"
- "github.com/authorizerdev/authorizer/server/token"
- "github.com/stretchr/testify/assert"
-)
-
-// ValidateSessionTests tests all the validate session resolvers
-func validateSessionTests(t *testing.T, s TestSetup) {
- t.Helper()
- t.Run(`should validate session`, func(t *testing.T) {
- req, ctx := createContext(s)
- email := "validate_session." + s.TestInfo.Email
-
- resolvers.SignupResolver(ctx, model.SignUpInput{
- Email: refs.NewStringRef(email),
- Password: s.TestInfo.Password,
- ConfirmPassword: s.TestInfo.Password,
- })
- _, err := resolvers.ValidateSessionResolver(ctx, &model.ValidateSessionInput{})
- assert.NotNil(t, err, "unauthorized")
- verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeBasicAuthSignup)
- assert.NoError(t, err)
- assert.NotNil(t, verificationRequest)
- verifyRes, err := resolvers.VerifyEmailResolver(ctx, model.VerifyEmailInput{
- Token: verificationRequest.Token,
- })
- assert.NoError(t, err)
- assert.NotNil(t, verifyRes)
- accessToken := *verifyRes.AccessToken
- assert.NotEmpty(t, accessToken)
- claims, err := token.ParseJWTToken(accessToken)
- assert.NoError(t, err)
- assert.NotEmpty(t, claims)
- sessionKey := constants.AuthRecipeMethodBasicAuth + ":" + verifyRes.User.ID
- sessionToken, err := memorystore.Provider.GetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+claims["nonce"].(string))
- assert.NoError(t, err)
- assert.NotEmpty(t, sessionToken)
- cookie := fmt.Sprintf("%s=%s;", constants.AppCookieName+"_session", sessionToken)
- cookie = strings.TrimSuffix(cookie, ";")
- res, err := resolvers.ValidateSessionResolver(ctx, &model.ValidateSessionInput{
- Cookie: sessionToken,
- })
- assert.Nil(t, err)
- assert.True(t, res.IsValid)
- req.Header.Set("Cookie", cookie)
- res, err = resolvers.ValidateSessionResolver(ctx, &model.ValidateSessionInput{})
- assert.Nil(t, err)
- assert.True(t, res.IsValid)
- assert.Equal(t, res.User.ID, verifyRes.User.ID)
- cleanData(email)
- })
-}
diff --git a/server/test/validator_test.go b/server/test/validator_test.go
deleted file mode 100644
index 70611a231..000000000
--- a/server/test/validator_test.go
+++ /dev/null
@@ -1,51 +0,0 @@
-package test
-
-import (
- "testing"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/validators"
- "github.com/stretchr/testify/assert"
-)
-
-func TestIsValidEmail(t *testing.T) {
- validEmail := "lakhan@gmail.com"
- invalidEmail1 := "lakhan"
- invalidEmail2 := "lakhan.me"
-
- assert.True(t, validators.IsValidEmail(validEmail), "it should be valid email")
- assert.False(t, validators.IsValidEmail(invalidEmail1), "it should be invalid email")
- assert.False(t, validators.IsValidEmail(invalidEmail2), "it should be invalid email")
-}
-
-func TestIsValidOrigin(t *testing.T) {
- // don't use portocal(http/https) for ALLOWED_ORIGINS while testing,
- // as we trim them off while running the main function
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyAllowedOrigins, "localhost:8080,*.google.com,*.google.in,*abc.*")
- assert.False(t, validators.IsValidOrigin("http://myapp.com"), "it should be invalid origin")
- assert.False(t, validators.IsValidOrigin("http://appgoogle.com"), "it should be invalid origin")
- assert.True(t, validators.IsValidOrigin("http://app.google.com"), "it should be valid origin")
- assert.False(t, validators.IsValidOrigin("http://app.google.ind"), "it should be invalid origin")
- assert.True(t, validators.IsValidOrigin("http://app.google.in"), "it should be valid origin")
- assert.True(t, validators.IsValidOrigin("http://xyx.abc.com"), "it should be valid origin")
- assert.True(t, validators.IsValidOrigin("http://xyx.abc.in"), "it should be valid origin")
- assert.True(t, validators.IsValidOrigin("http://xyxabc.in"), "it should be valid origin")
- assert.True(t, validators.IsValidOrigin("http://localhost:8080"), "it should be valid origin")
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyAllowedOrigins, "*")
-}
-
-func TestIsValidIdentifier(t *testing.T) {
- assert.False(t, validators.IsValidVerificationIdentifier("test"), "it should be invalid identifier")
- assert.True(t, validators.IsValidVerificationIdentifier(constants.VerificationTypeBasicAuthSignup), "it should be valid identifier")
- assert.True(t, validators.IsValidVerificationIdentifier(constants.VerificationTypeUpdateEmail), "it should be valid identifier")
- assert.True(t, validators.IsValidVerificationIdentifier(constants.VerificationTypeForgotPassword), "it should be valid identifier")
-}
-
-func TestIsValidPassword(t *testing.T) {
- assert.Error(t, validators.IsValidPassword("test"), "it should be invalid password")
- assert.Error(t, validators.IsValidPassword("Te@1"), "it should be invalid password")
- assert.Error(t, validators.IsValidPassword("n*rp7GGTd29V{xx%{pDb@7n{](SD.!+.Mp#*$EHDGk&$pAMf7e#432Sg,Gr](j3n]jV/3F8BJJT+9u9{q=8zK:8u!rpQBaXJp%A+7r!jQj)M(vC$UX,h;;WKm$U6i#7dBnC&2ryKzKd+(y&=Ud)hErT/j;v3t..CM).8nS)9qLtV7pmP;@2QuzDyGfL7KB()k:BpjAGL@bxD%r5gcBfh7$&wutk!wzMfPFY#nkjjqyZbEHku,{jc;gvbYq2)3w=KExnYz9Vbv:;*;?f##faxkULdMpmm&yEfePixzx+[{[38zGN;3TzF;6M#Xy_tMtx:yK*n$bc(bPyGz%EYkC&]ttUF@#aZ%$QZ:u!icF@+"), "it should be invalid password")
- assert.Error(t, validators.IsValidPassword("test@123"), "it should be invalid password")
- assert.NoError(t, validators.IsValidPassword("Test@123"), "it should be valid password")
-}
diff --git a/server/test/verification_requests_test.go b/server/test/verification_requests_test.go
deleted file mode 100644
index 93b464357..000000000
--- a/server/test/verification_requests_test.go
+++ /dev/null
@@ -1,54 +0,0 @@
-package test
-
-import (
- "fmt"
- "testing"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/crypto"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/refs"
- "github.com/authorizerdev/authorizer/server/resolvers"
- "github.com/stretchr/testify/assert"
-)
-
-func verificationRequestsTest(t *testing.T, s TestSetup) {
- t.Helper()
-
- t.Run(`should get verification requests with admin secret only`, func(t *testing.T) {
- req, ctx := createContext(s)
- email := "verification_requests." + s.TestInfo.Email
- res, err := resolvers.SignupResolver(ctx, model.SignUpInput{
- Email: refs.NewStringRef(email),
- Password: s.TestInfo.Password,
- ConfirmPassword: s.TestInfo.Password,
- })
- assert.NoError(t, err)
- assert.NotNil(t, res)
- limit := int64(10)
- page := int64(1)
- pagination := &model.PaginatedInput{
- Pagination: &model.PaginationInput{
- Limit: &limit,
- Page: &page,
- },
- }
-
- requests, err := resolvers.VerificationRequestsResolver(ctx, pagination)
- assert.NotNil(t, err, "unauthorized")
- assert.Nil(t, requests)
- adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
- assert.Nil(t, err)
-
- h, err := crypto.EncryptPassword(adminSecret)
- assert.Nil(t, err)
- req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
- requests, err = resolvers.VerificationRequestsResolver(ctx, pagination)
- assert.Nil(t, err)
- rLen := len(requests.VerificationRequests)
- assert.GreaterOrEqual(t, rLen, 1)
-
- cleanData(email)
- })
-}
diff --git a/server/test/verify_email_test.go b/server/test/verify_email_test.go
deleted file mode 100644
index 19416c14c..000000000
--- a/server/test/verify_email_test.go
+++ /dev/null
@@ -1,45 +0,0 @@
-package test
-
-import (
- "testing"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/refs"
- "github.com/authorizerdev/authorizer/server/resolvers"
- "github.com/stretchr/testify/assert"
-)
-
-func verifyEmailTest(t *testing.T, s TestSetup) {
- t.Helper()
- t.Run(`should verify email`, func(t *testing.T) {
- _, ctx := createContext(s)
- email := "verify_email." + s.TestInfo.Email
- res, err := resolvers.SignupResolver(ctx, model.SignUpInput{
- Email: refs.NewStringRef(email),
- Password: s.TestInfo.Password,
- ConfirmPassword: s.TestInfo.Password,
- })
- assert.NoError(t, err)
- assert.NotNil(t, res)
- user := *res.User
- assert.Equal(t, email, refs.StringValue(user.Email))
- assert.Nil(t, res.AccessToken, "access token should be nil")
- verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeBasicAuthSignup)
- assert.Nil(t, err)
- assert.Equal(t, email, verificationRequest.Email)
-
- verifyRes, err := resolvers.VerifyEmailResolver(ctx, model.VerifyEmailInput{
- Token: verificationRequest.Token,
- })
- assert.Nil(t, err)
- assert.NotEqual(t, verifyRes.AccessToken, "", "access token should not be empty")
- // Check if phone number is verified
- user1, err := db.Provider.GetUserByEmail(ctx, email)
- assert.NoError(t, err)
- assert.NotNil(t, user1)
- assert.NotNil(t, user1.EmailVerifiedAt)
- cleanData(email)
- })
-}
diff --git a/server/test/verify_otp_test.go b/server/test/verify_otp_test.go
deleted file mode 100644
index 917505ef7..000000000
--- a/server/test/verify_otp_test.go
+++ /dev/null
@@ -1,204 +0,0 @@
-package test
-
-import (
- "bytes"
- "context"
- "encoding/base64"
- "fmt"
- "strings"
- "testing"
- "time"
-
- "github.com/gokyle/twofactor"
- "github.com/google/uuid"
- "github.com/stretchr/testify/assert"
- "github.com/tuotoo/qrcode"
-
- "github.com/authorizerdev/authorizer/server/authenticators"
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/refs"
- "github.com/authorizerdev/authorizer/server/resolvers"
- "github.com/authorizerdev/authorizer/server/token"
-)
-
-func verifyOTPTest(t *testing.T, s TestSetup) {
- t.Helper()
- t.Run(`should verify otp`, func(t *testing.T) {
- // Set up request and context using test setup
- req, ctx := createContext(s)
- email := "verify_otp." + s.TestInfo.Email
-
- // Test case: Setup email OTP MFA for login
- {
- // Sign up a user
- res, err := resolvers.SignupResolver(ctx, model.SignUpInput{
- Email: refs.NewStringRef(email),
- Password: s.TestInfo.Password,
- ConfirmPassword: s.TestInfo.Password,
- })
- assert.NoError(t, err)
- assert.NotNil(t, res)
-
- // Attempt to login should fail as email is not verified
- loginRes, err := resolvers.LoginResolver(ctx, model.LoginInput{
- Email: refs.NewStringRef(email),
- Password: s.TestInfo.Password,
- })
- assert.NoError(t, err)
- assert.NotNil(t, loginRes)
- assert.Nil(t, loginRes.AccessToken)
- assert.NotEmpty(t, loginRes.Message)
-
- // Verify the email
- verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeBasicAuthSignup)
- assert.Nil(t, err)
- assert.Equal(t, email, verificationRequest.Email)
- verifyRes, err := resolvers.VerifyEmailResolver(ctx, model.VerifyEmailInput{
- Token: verificationRequest.Token,
- })
- assert.Nil(t, err)
- assert.NotEqual(t, verifyRes.AccessToken, "", "access token should not be empty")
-
- // Use access token to update the profile
- s.GinContext.Request.Header.Set("Authorization", "Bearer "+refs.StringValue(verifyRes.AccessToken))
- ctx = context.WithValue(req.Context(), "GinContextKey", s.GinContext)
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDisableMailOTPLogin, false)
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDisableTOTPLogin, true)
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDisablePhoneVerification, true)
- updateProfileRes, err := resolvers.UpdateProfileResolver(ctx, model.UpdateProfileInput{
- IsMultiFactorAuthEnabled: refs.NewBoolRef(true),
- })
- assert.NoError(t, err)
- assert.NotEmpty(t, updateProfileRes.Message)
-
- // Login should not return an error, but the access token should be empty as OTP should have been sent
- loginRes, err = resolvers.LoginResolver(ctx, model.LoginInput{
- Email: refs.NewStringRef(email),
- Password: s.TestInfo.Password,
- })
- assert.NoError(t, err)
- assert.NotNil(t, loginRes)
- assert.Nil(t, loginRes.AccessToken)
-
- // Get OTP from db
- otp, err := db.Provider.GetOTPByEmail(ctx, email)
- assert.NoError(t, err)
- assert.NotEmpty(t, otp.Otp)
-
- // Get user by email
- user, err := db.Provider.GetUserByEmail(ctx, email)
- assert.NoError(t, err)
- assert.NotNil(t, user)
-
- // Set MFA cookie session
- mfaSession := uuid.NewString()
- memorystore.Provider.SetMfaSession(user.ID, mfaSession, time.Now().Add(1*time.Minute).Unix())
- cookie := fmt.Sprintf("%s=%s;", constants.MfaCookieName+"_session", mfaSession)
- cookie = strings.TrimSuffix(cookie, ";")
- req.Header.Set("Cookie", cookie)
-
- // Verify OTP
- verifyOtpRes, err := resolvers.VerifyOtpResolver(ctx, model.VerifyOTPRequest{
- Email: &email,
- Otp: otp.Otp,
- })
- assert.Nil(t, err)
- assert.NotEqual(t, verifyOtpRes.AccessToken, "", "access token should not be empty")
-
- // Clean up data for the email
- cleanData(email)
- }
-
- // Test case: Setup TOTP MFA for signup
- {
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDisableEmailVerification, false)
- signUpRes, err := resolvers.SignupResolver(ctx, model.SignUpInput{
- Email: refs.NewStringRef(email),
- Password: s.TestInfo.Password,
- ConfirmPassword: s.TestInfo.Password,
- })
- assert.Nil(t, err, "Expected no error but got: %v", err)
- assert.Equal(t, "Verification email has been sent. Please check your inbox", signUpRes.Message)
-
- // Retrieve user and update for TOTP setup
- user, err := db.Provider.GetUserByID(ctx, signUpRes.User.ID)
- assert.Nil(t, err, "Expected no error but got: %v", err)
- assert.NotNil(t, user)
-
- // Enable multi-factor authentication and update the user
- memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDisableTOTPLogin, false)
- user.IsMultiFactorAuthEnabled = refs.NewBoolRef(true)
- updatedUser, err := db.Provider.UpdateUser(ctx, user)
- assert.Nil(t, err, "Expected no error but got: %v", err)
- assert.Equal(t, true, *updatedUser.IsMultiFactorAuthEnabled)
-
- // Initialise totp authenticator store
- authenticators.InitTOTPStore()
-
- // Verify an email and get TOTP response
- verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeBasicAuthSignup)
- assert.Nil(t, err)
- assert.Equal(t, email, verificationRequest.Email)
- verifyRes, err := resolvers.VerifyEmailResolver(ctx, model.VerifyEmailInput{
- Token: verificationRequest.Token,
- })
- assert.Nil(t, err, "Expected no error but got: %v", err)
- assert.NotNil(t, &verifyRes)
- assert.Nil(t, verifyRes.AccessToken)
- assert.Equal(t, "Proceed to totp verification screen", verifyRes.Message)
- assert.NotEqual(t, *verifyRes.AuthenticatorScannerImage, "", "totp url should not be empty")
- assert.NotEqual(t, *verifyRes.AuthenticatorSecret, "", "totp secret should not be empty")
- assert.NotNil(t, verifyRes.AuthenticatorRecoveryCodes)
-
- // Get TOTP URL for validation
- pngBytes, err := base64.StdEncoding.DecodeString(*verifyRes.AuthenticatorScannerImage)
- assert.NoError(t, err)
- qrmatrix, err := qrcode.Decode(bytes.NewReader(pngBytes))
- assert.NoError(t, err)
- tf, label, err := twofactor.FromURL(qrmatrix.Content)
- data := strings.Split(label, ":")
- assert.NoError(t, err)
- assert.Equal(t, email, data[1])
- assert.NotNil(t, tf)
- code := tf.OTP()
- assert.NotEmpty(t, code)
-
- // Set mfa cookie session
- mfaSession := uuid.NewString()
- memorystore.Provider.SetMfaSession(signUpRes.User.ID, mfaSession, time.Now().Add(1*time.Minute).Unix())
- cookie := fmt.Sprintf("%s=%s;", constants.MfaCookieName+"_session", mfaSession)
- cookie = strings.TrimSuffix(cookie, ";")
- req.Header.Set("Cookie", cookie)
- valid, err := resolvers.VerifyOtpResolver(ctx, model.VerifyOTPRequest{
- Email: &email,
- IsTotp: refs.NewBoolRef(true),
- Otp: code,
- })
- accessToken := *valid.AccessToken
- assert.NoError(t, err)
- assert.NotNil(t, accessToken)
- assert.NotEmpty(t, valid.Message)
- assert.NotEmpty(t, accessToken)
- claims, err := token.ParseJWTToken(accessToken)
- assert.NoError(t, err)
- assert.NotEmpty(t, claims)
- signUpMethod := claims["login_method"]
- sessionKey := signUpRes.User.ID
- if signUpMethod != nil && signUpMethod != "" {
- sessionKey = signUpMethod.(string) + ":" + signUpRes.User.ID
- }
- sessionToken, err := memorystore.Provider.GetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+claims["nonce"].(string))
- assert.NoError(t, err)
- assert.NotEmpty(t, sessionToken)
- cookie = fmt.Sprintf("%s=%s;", constants.AppCookieName+"_session", sessionToken)
- cookie = strings.TrimSuffix(cookie, ";")
- req.Header.Set("Cookie", cookie)
-
- // Clean up data for the email
- cleanData(email)
- }
- })
-}
diff --git a/server/test/webhook_logs_test.go b/server/test/webhook_logs_test.go
deleted file mode 100644
index 25210a3af..000000000
--- a/server/test/webhook_logs_test.go
+++ /dev/null
@@ -1,52 +0,0 @@
-package test
-
-import (
- "fmt"
- "testing"
- "time"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/crypto"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/refs"
- "github.com/authorizerdev/authorizer/server/resolvers"
- "github.com/stretchr/testify/assert"
-)
-
-func webhookLogsTest(t *testing.T, s TestSetup) {
- time.Sleep(30 * time.Second) // add sleep for webhooklogs to get generated as they are async
- t.Helper()
- t.Run("should get webhook logs", func(t *testing.T) {
- req, ctx := createContext(s)
- adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
- assert.NoError(t, err)
- h, err := crypto.EncryptPassword(adminSecret)
- assert.NoError(t, err)
- req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
-
- webhookLogs, err := resolvers.WebhookLogsResolver(ctx, nil)
- assert.NoError(t, err)
- assert.Greater(t, len(webhookLogs.WebhookLogs), 1)
-
- webhooks, err := resolvers.WebhooksResolver(ctx, &model.PaginatedInput{
- Pagination: &model.PaginationInput{
- Limit: refs.NewInt64Ref(20),
- },
- })
- assert.NoError(t, err)
- assert.NotEmpty(t, webhooks)
- for _, w := range webhooks.Webhooks {
- t.Run(fmt.Sprintf("should get webhook for webhook_id:%s", w.ID), func(t *testing.T) {
- webhookLogs, err := resolvers.WebhookLogsResolver(ctx, &model.ListWebhookLogRequest{
- WebhookID: &w.ID,
- })
- assert.NoError(t, err)
- assert.GreaterOrEqual(t, len(webhookLogs.WebhookLogs), 1, refs.StringValue(w.EventName))
- for _, wl := range webhookLogs.WebhookLogs {
- assert.Equal(t, refs.StringValue(wl.WebhookID), w.ID)
- }
- })
- }
- })
-}
diff --git a/server/test/webhook_test.go b/server/test/webhook_test.go
deleted file mode 100644
index a556f9dd1..000000000
--- a/server/test/webhook_test.go
+++ /dev/null
@@ -1,44 +0,0 @@
-package test
-
-import (
- "fmt"
- "testing"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/crypto"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/refs"
- "github.com/authorizerdev/authorizer/server/resolvers"
- "github.com/stretchr/testify/assert"
-)
-
-func webhookTest(t *testing.T, s TestSetup) {
- t.Helper()
- t.Run("should get webhook", func(t *testing.T) {
- req, ctx := createContext(s)
- adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
- assert.NoError(t, err)
- h, err := crypto.EncryptPassword(adminSecret)
- assert.NoError(t, err)
- req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
-
- // get webhook by event name
- webhooks, err := db.Provider.GetWebhookByEventName(ctx, constants.UserCreatedWebhookEvent)
- assert.NoError(t, err)
- assert.NotNil(t, webhooks)
- assert.GreaterOrEqual(t, len(webhooks), 2)
- for _, webhook := range webhooks {
- res, err := resolvers.WebhookResolver(ctx, model.WebhookRequest{
- ID: webhook.ID,
- })
- assert.NoError(t, err)
- assert.Equal(t, res.ID, webhook.ID)
- assert.Equal(t, refs.StringValue(res.Endpoint), refs.StringValue(webhook.Endpoint))
- // assert.Equal(t, refs.StringValue(res.EventName), refs.StringValue(webhook.EventName))
- assert.Equal(t, refs.BoolValue(res.Enabled), refs.BoolValue(webhook.Enabled))
- assert.Len(t, res.Headers, len(webhook.Headers))
- }
- })
-}
diff --git a/server/test/webhooks_test.go b/server/test/webhooks_test.go
deleted file mode 100644
index 74cad7411..000000000
--- a/server/test/webhooks_test.go
+++ /dev/null
@@ -1,35 +0,0 @@
-package test
-
-import (
- "fmt"
- "testing"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/crypto"
- "github.com/authorizerdev/authorizer/server/graph/model"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/refs"
- "github.com/authorizerdev/authorizer/server/resolvers"
- "github.com/stretchr/testify/assert"
-)
-
-func webhooksTest(t *testing.T, s TestSetup) {
- t.Helper()
- t.Run("should get webhooks", func(t *testing.T) {
- req, ctx := createContext(s)
- adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
- assert.NoError(t, err)
- h, err := crypto.EncryptPassword(adminSecret)
- assert.NoError(t, err)
- req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
-
- webhooks, err := resolvers.WebhooksResolver(ctx, &model.PaginatedInput{
- Pagination: &model.PaginationInput{
- Limit: refs.NewInt64Ref(20),
- },
- })
- assert.NoError(t, err)
- assert.NotEmpty(t, webhooks)
- assert.GreaterOrEqual(t, len(webhooks.Webhooks), len(s.TestInfo.TestWebhookEventTypes)*2)
- })
-}
diff --git a/server/token/admin_token.go b/server/token/admin_token.go
deleted file mode 100644
index 9dcbeb317..000000000
--- a/server/token/admin_token.go
+++ /dev/null
@@ -1,59 +0,0 @@
-package token
-
-import (
- "fmt"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/cookie"
- "github.com/authorizerdev/authorizer/server/crypto"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/gin-gonic/gin"
- "golang.org/x/crypto/bcrypt"
-)
-
-// CreateAdminAuthToken creates the admin token based on secret key
-func CreateAdminAuthToken(tokenType string, c *gin.Context) (string, error) {
- adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
- if err != nil {
- return "", err
- }
- return crypto.EncryptPassword(adminSecret)
-}
-
-// GetAdminAuthToken helps in getting the admin token from the request cookie
-func GetAdminAuthToken(gc *gin.Context) (string, error) {
- token, err := cookie.GetAdminCookie(gc)
- if err != nil || token == "" {
- return "", fmt.Errorf("unauthorized")
- }
-
- adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
- if err != nil {
- return "", err
- }
- err = bcrypt.CompareHashAndPassword([]byte(token), []byte(adminSecret))
-
- if err != nil {
- return "", fmt.Errorf(`unauthorized`)
- }
-
- return token, nil
-}
-
-// IsSuperAdmin checks if user is super admin
-func IsSuperAdmin(gc *gin.Context) bool {
- token, err := GetAdminAuthToken(gc)
- if err != nil {
- secret := gc.Request.Header.Get("x-authorizer-admin-secret")
- if secret == "" {
- return false
- }
- adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
- if err != nil {
- return false
- }
- return secret == adminSecret
- }
-
- return token != ""
-}
diff --git a/server/token/jwt.go b/server/token/jwt.go
deleted file mode 100644
index 4e5f0ed93..000000000
--- a/server/token/jwt.go
+++ /dev/null
@@ -1,166 +0,0 @@
-package token
-
-import (
- "errors"
-
- "github.com/golang-jwt/jwt"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/crypto"
- "github.com/authorizerdev/authorizer/server/memorystore"
-)
-
-// SignJWTToken common util to sing jwt token
-func SignJWTToken(claims jwt.MapClaims) (string, error) {
- jwtType, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyJwtType)
- if err != nil {
- return "", err
- }
- signingMethod := jwt.GetSigningMethod(jwtType)
- if signingMethod == nil {
- return "", errors.New("unsupported signing method")
- }
- t := jwt.New(signingMethod)
- if t == nil {
- return "", errors.New("unsupported signing method")
- }
- t.Claims = claims
-
- switch signingMethod {
- case jwt.SigningMethodHS256, jwt.SigningMethodHS384, jwt.SigningMethodHS512:
- jwtSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyJwtSecret)
- if err != nil {
- return "", err
- }
- return t.SignedString([]byte(jwtSecret))
- case jwt.SigningMethodRS256, jwt.SigningMethodRS384, jwt.SigningMethodRS512:
- jwtPrivateKey, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyJwtPrivateKey)
- if err != nil {
- return "", err
- }
- key, err := crypto.ParseRsaPrivateKeyFromPemStr(jwtPrivateKey)
- if err != nil {
- return "", err
- }
- return t.SignedString(key)
- case jwt.SigningMethodES256, jwt.SigningMethodES384, jwt.SigningMethodES512:
- jwtPrivateKey, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyJwtPrivateKey)
- if err != nil {
- return "", err
- }
- key, err := crypto.ParseEcdsaPrivateKeyFromPemStr(jwtPrivateKey)
- if err != nil {
- return "", err
- }
-
- return t.SignedString(key)
- default:
- return "", errors.New("unsupported signing method")
- }
-}
-
-// ParseJWTToken common util to parse jwt token
-func ParseJWTToken(token string) (jwt.MapClaims, error) {
- jwtType, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyJwtType)
- if err != nil {
- return nil, err
- }
- signingMethod := jwt.GetSigningMethod(jwtType)
-
- var claims jwt.MapClaims
-
- switch signingMethod {
- case jwt.SigningMethodHS256, jwt.SigningMethodHS384, jwt.SigningMethodHS512:
- _, err = jwt.ParseWithClaims(token, &claims, func(token *jwt.Token) (interface{}, error) {
- jwtSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyJwtSecret)
- if err != nil {
- return nil, err
- }
- return []byte(jwtSecret), nil
- })
- case jwt.SigningMethodRS256, jwt.SigningMethodRS384, jwt.SigningMethodRS512:
- _, err = jwt.ParseWithClaims(token, &claims, func(token *jwt.Token) (interface{}, error) {
- jwtPublicKey, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyJwtPublicKey)
- if err != nil {
- return nil, err
- }
- key, err := crypto.ParseRsaPublicKeyFromPemStr(jwtPublicKey)
- if err != nil {
- return nil, err
- }
- return key, nil
- })
- case jwt.SigningMethodES256, jwt.SigningMethodES384, jwt.SigningMethodES512:
- _, err = jwt.ParseWithClaims(token, &claims, func(token *jwt.Token) (interface{}, error) {
- jwtPublicKey, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyJwtPublicKey)
- if err != nil {
- return nil, err
- }
- key, err := crypto.ParseEcdsaPublicKeyFromPemStr(jwtPublicKey)
- if err != nil {
- return nil, err
- }
- return key, nil
- })
- default:
- err = errors.New("unsupported signing method")
- }
- if err != nil {
- return claims, err
- }
-
- // claim parses exp & iat into float 64 with e^10,
- // but we expect it to be int64
- // hence we need to assert interface and convert to int64
- intExp := int64(claims["exp"].(float64))
- intIat := int64(claims["iat"].(float64))
- claims["exp"] = intExp
- claims["iat"] = intIat
-
- return claims, nil
-}
-
-// ValidateJWTClaims common util to validate claims
-func ValidateJWTClaims(claims jwt.MapClaims, hostname, nonce, subject string) (bool, error) {
- clientID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyClientID)
- if err != nil {
- return false, err
- }
- if claims["aud"] != clientID {
- return false, errors.New("invalid audience")
- }
-
- if claims["nonce"] != nonce {
- return false, errors.New("invalid nonce")
- }
-
- if claims["iss"] != hostname {
- return false, errors.New("invalid issuer")
- }
-
- if claims["sub"] != subject {
- return false, errors.New("invalid subject")
- }
-
- return true, nil
-}
-
-// ValidateJWTTokenWithoutNonce common util to validate claims without nonce
-func ValidateJWTTokenWithoutNonce(claims jwt.MapClaims, hostname, subject string) (bool, error) {
- clientID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyClientID)
- if err != nil {
- return false, err
- }
- if claims["aud"] != clientID {
- return false, errors.New("invalid audience")
- }
-
- if claims["iss"] != hostname {
- return false, errors.New("invalid issuer")
- }
-
- if claims["sub"] != subject {
- return false, errors.New("invalid subject")
- }
- return true, nil
-}
diff --git a/server/token/verification_token.go b/server/token/verification_token.go
deleted file mode 100644
index 75aef3063..000000000
--- a/server/token/verification_token.go
+++ /dev/null
@@ -1,29 +0,0 @@
-package token
-
-import (
- "time"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/golang-jwt/jwt"
-)
-
-// CreateVerificationToken creates a verification JWT token
-func CreateVerificationToken(email, tokenType, hostname, nonceHash, redirectURL string) (string, error) {
- clientID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyClientID)
- if err != nil {
- return "", err
- }
- claims := jwt.MapClaims{
- "iss": hostname,
- "aud": clientID,
- "sub": email,
- "exp": time.Now().Add(time.Minute * 30).Unix(),
- "iat": time.Now().Unix(),
- "token_type": tokenType,
- "nonce": nonceHash,
- "redirect_uri": redirectURL,
- }
-
- return SignJWTToken(claims)
-}
diff --git a/server/utils/webhook.go b/server/utils/webhook.go
deleted file mode 100644
index a97f286cc..000000000
--- a/server/utils/webhook.go
+++ /dev/null
@@ -1,117 +0,0 @@
-package utils
-
-import (
- "bytes"
- "context"
- "encoding/json"
- "io"
- "net/http"
- "time"
-
- "github.com/authorizerdev/authorizer/server/constants"
- "github.com/authorizerdev/authorizer/server/db"
- "github.com/authorizerdev/authorizer/server/db/models"
- "github.com/authorizerdev/authorizer/server/memorystore"
- "github.com/authorizerdev/authorizer/server/refs"
- log "github.com/sirupsen/logrus"
-)
-
-// RegisterEvent util to register event
-// TODO change user to user ref
-func RegisterEvent(ctx context.Context, eventName string, authRecipe string, user *models.User) error {
- webhooks, err := db.Provider.GetWebhookByEventName(ctx, eventName)
- if err != nil {
- log.Debug("error getting webhook: %v", err)
- return err
- }
- for _, webhook := range webhooks {
- if !refs.BoolValue(webhook.Enabled) {
- continue
- }
- userBytes, err := json.Marshal(user.AsAPIUser())
- if err != nil {
- log.Debug("error marshalling user obj: ", err)
- continue
- }
- userMap := map[string]interface{}{}
- err = json.Unmarshal(userBytes, &userMap)
- if err != nil {
- log.Debug("error un-marshalling user obj: ", err)
- continue
- }
-
- reqBody := map[string]interface{}{
- "webhook_id": webhook.ID,
- "event_name": eventName,
- "event_description": webhook.EventDescription,
- "user": userMap,
- }
-
- if eventName == constants.UserLoginWebhookEvent || eventName == constants.UserSignUpWebhookEvent {
- reqBody["auth_recipe"] = authRecipe
- }
-
- requestBody, err := json.Marshal(reqBody)
- if err != nil {
- log.Debug("error marshalling requestBody obj: ", err)
- continue
- }
-
- // dont trigger webhook call in case of test
- envKey, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyEnv)
- if err != nil {
- continue
- }
- if envKey == constants.TestEnv {
- _, err := db.Provider.AddWebhookLog(ctx, &models.WebhookLog{
- HttpStatus: 200,
- Request: string(requestBody),
- Response: string(`{"message": "test"}`),
- WebhookID: webhook.ID,
- })
- if err != nil {
- log.Debug("error saving webhook log:", err)
- }
- continue
- }
-
- requestBytesBuffer := bytes.NewBuffer(requestBody)
- req, err := http.NewRequest("POST", refs.StringValue(webhook.Endpoint), requestBytesBuffer)
- if err != nil {
- log.Debug("error creating webhook post request: ", err)
- continue
- }
- req.Header.Set("Content-Type", "application/json")
-
- for key, val := range webhook.Headers {
- req.Header.Set(key, val.(string))
- }
-
- client := &http.Client{Timeout: time.Second * 30}
- resp, err := client.Do(req)
- if err != nil {
- log.Debug("error making request: ", err)
- continue
- }
- defer resp.Body.Close()
-
- responseBytes, err := io.ReadAll(resp.Body)
- if err != nil {
- log.Debug("error reading response: ", err)
- continue
- }
-
- statusCode := int64(resp.StatusCode)
- _, err = db.Provider.AddWebhookLog(ctx, &models.WebhookLog{
- HttpStatus: statusCode,
- Request: string(requestBody),
- Response: string(responseBytes),
- WebhookID: webhook.ID,
- })
- if err != nil {
- log.Debug("failed to add webhook log: ", err)
- continue
- }
- }
- return nil
-}
diff --git a/app/.prettierrc.json b/web/app/.prettierrc.json
similarity index 100%
rename from app/.prettierrc.json
rename to web/app/.prettierrc.json
diff --git a/app/README.md b/web/app/README.md
similarity index 100%
rename from app/README.md
rename to web/app/README.md
diff --git a/app/favicon_io/android-chrome-192x192.png b/web/app/favicon_io/android-chrome-192x192.png
similarity index 100%
rename from app/favicon_io/android-chrome-192x192.png
rename to web/app/favicon_io/android-chrome-192x192.png
diff --git a/app/favicon_io/android-chrome-512x512.png b/web/app/favicon_io/android-chrome-512x512.png
similarity index 100%
rename from app/favicon_io/android-chrome-512x512.png
rename to web/app/favicon_io/android-chrome-512x512.png
diff --git a/app/favicon_io/apple-touch-icon.png b/web/app/favicon_io/apple-touch-icon.png
similarity index 100%
rename from app/favicon_io/apple-touch-icon.png
rename to web/app/favicon_io/apple-touch-icon.png
diff --git a/app/favicon_io/favicon-16x16.png b/web/app/favicon_io/favicon-16x16.png
similarity index 100%
rename from app/favicon_io/favicon-16x16.png
rename to web/app/favicon_io/favicon-16x16.png
diff --git a/app/favicon_io/favicon-32x32.png b/web/app/favicon_io/favicon-32x32.png
similarity index 100%
rename from app/favicon_io/favicon-32x32.png
rename to web/app/favicon_io/favicon-32x32.png
diff --git a/app/favicon_io/favicon.ico b/web/app/favicon_io/favicon.ico
similarity index 100%
rename from app/favicon_io/favicon.ico
rename to web/app/favicon_io/favicon.ico
diff --git a/web/app/package-lock.json b/web/app/package-lock.json
new file mode 100644
index 000000000..66b1784db
--- /dev/null
+++ b/web/app/package-lock.json
@@ -0,0 +1,3099 @@
+{
+ "name": "app",
+ "version": "1.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "app",
+ "version": "1.0.0",
+ "license": "ISC",
+ "dependencies": {
+ "@authorizerdev/authorizer-react": "^2.0.0-rc.2",
+ "react": "^18.3.1",
+ "react-dom": "^18.3.1",
+ "react-is": "^18.3.1",
+ "react-router-dom": "^6.28.0",
+ "styled-components": "^6.1.13"
+ },
+ "devDependencies": {
+ "@types/react": "^18.3.12",
+ "@types/react-dom": "^18.3.1",
+ "@types/react-router-dom": "^5.3.3",
+ "@types/styled-components": "^5.1.34",
+ "@vitejs/plugin-react": "^4.3.1",
+ "prettier": "^3.3.3",
+ "typescript": "^5.6.3",
+ "vite": "^7.3.0"
+ }
+ },
+ "node_modules/@authorizerdev/authorizer-js": {
+ "version": "3.0.0-rc.1",
+ "resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-3.0.0-rc.1.tgz",
+ "integrity": "sha512-tTY6NQJ7W00TjoJJSQXRqTi3mhz8z/epRH1lE0S9jM7EMxCQ4FCSbRLJ7nd2mxch3ORHRx9GIq8UkH+VHsCLxA==",
+ "license": "MIT",
+ "dependencies": {
+ "cross-fetch": "^3.1.5"
+ },
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/authorizerdev"
+ }
+ },
+ "node_modules/@authorizerdev/authorizer-react": {
+ "version": "2.0.0-rc.2",
+ "resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-2.0.0-rc.2.tgz",
+ "integrity": "sha512-Uwb2pzK7DevXebK7nbkezv/3QeMy2l2KoNGlEP7a9Y4Z5Gx+ZhhNGRqdx4w8UiEQdEkAieJkH3JnZxJMuusoNQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@authorizerdev/authorizer-js": "3.0.0-rc.1",
+ "@storybook/preset-scss": "^1.0.3",
+ "validator": "^13.11.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "react": ">=16"
+ }
+ },
+ "node_modules/@babel/code-frame": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz",
+ "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.27.1",
+ "js-tokens": "^4.0.0",
+ "picocolors": "^1.1.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/compat-data": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.5.tgz",
+ "integrity": "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/core": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz",
+ "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.27.1",
+ "@babel/generator": "^7.28.5",
+ "@babel/helper-compilation-targets": "^7.27.2",
+ "@babel/helper-module-transforms": "^7.28.3",
+ "@babel/helpers": "^7.28.4",
+ "@babel/parser": "^7.28.5",
+ "@babel/template": "^7.27.2",
+ "@babel/traverse": "^7.28.5",
+ "@babel/types": "^7.28.5",
+ "@jridgewell/remapping": "^2.3.5",
+ "convert-source-map": "^2.0.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.2",
+ "json5": "^2.2.3",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/babel"
+ }
+ },
+ "node_modules/@babel/generator": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz",
+ "integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.28.5",
+ "@babel/types": "^7.28.5",
+ "@jridgewell/gen-mapping": "^0.3.12",
+ "@jridgewell/trace-mapping": "^0.3.28",
+ "jsesc": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets": {
+ "version": "7.27.2",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz",
+ "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/compat-data": "^7.27.2",
+ "@babel/helper-validator-option": "^7.27.1",
+ "browserslist": "^4.24.0",
+ "lru-cache": "^5.1.1",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-globals": {
+ "version": "7.28.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz",
+ "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-imports": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz",
+ "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/traverse": "^7.27.1",
+ "@babel/types": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-transforms": {
+ "version": "7.28.3",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz",
+ "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.27.1",
+ "@babel/helper-validator-identifier": "^7.27.1",
+ "@babel/traverse": "^7.28.3"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-plugin-utils": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz",
+ "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-string-parser": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
+ "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz",
+ "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-option": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz",
+ "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helpers": {
+ "version": "7.28.4",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz",
+ "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/template": "^7.27.2",
+ "@babel/types": "^7.28.4"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/parser": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz",
+ "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.28.5"
+ },
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-react-jsx-self": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz",
+ "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-react-jsx-source": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz",
+ "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/template": {
+ "version": "7.27.2",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz",
+ "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.27.1",
+ "@babel/parser": "^7.27.2",
+ "@babel/types": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/traverse": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz",
+ "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.27.1",
+ "@babel/generator": "^7.28.5",
+ "@babel/helper-globals": "^7.28.0",
+ "@babel/parser": "^7.28.5",
+ "@babel/template": "^7.27.2",
+ "@babel/types": "^7.28.5",
+ "debug": "^4.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/types": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz",
+ "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-string-parser": "^7.27.1",
+ "@babel/helper-validator-identifier": "^7.28.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@emotion/is-prop-valid": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz",
+ "integrity": "sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==",
+ "license": "MIT",
+ "dependencies": {
+ "@emotion/memoize": "^0.8.1"
+ }
+ },
+ "node_modules/@emotion/memoize": {
+ "version": "0.8.1",
+ "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz",
+ "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==",
+ "license": "MIT"
+ },
+ "node_modules/@emotion/unitless": {
+ "version": "0.8.1",
+ "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz",
+ "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==",
+ "license": "MIT"
+ },
+ "node_modules/@esbuild/aix-ppc64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.2.tgz",
+ "integrity": "sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.2.tgz",
+ "integrity": "sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.2.tgz",
+ "integrity": "sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.2.tgz",
+ "integrity": "sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.2.tgz",
+ "integrity": "sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.2.tgz",
+ "integrity": "sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.2.tgz",
+ "integrity": "sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.2.tgz",
+ "integrity": "sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.2.tgz",
+ "integrity": "sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.2.tgz",
+ "integrity": "sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.2.tgz",
+ "integrity": "sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.2.tgz",
+ "integrity": "sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.2.tgz",
+ "integrity": "sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.2.tgz",
+ "integrity": "sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.2.tgz",
+ "integrity": "sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.2.tgz",
+ "integrity": "sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.2.tgz",
+ "integrity": "sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-arm64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.2.tgz",
+ "integrity": "sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.2.tgz",
+ "integrity": "sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-arm64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.2.tgz",
+ "integrity": "sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.2.tgz",
+ "integrity": "sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openharmony-arm64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.2.tgz",
+ "integrity": "sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.2.tgz",
+ "integrity": "sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.2.tgz",
+ "integrity": "sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.2.tgz",
+ "integrity": "sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.2.tgz",
+ "integrity": "sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.13",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
+ "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.0",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ }
+ },
+ "node_modules/@jridgewell/remapping": {
+ "version": "2.3.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz",
+ "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ }
+ },
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/source-map": {
+ "version": "0.3.11",
+ "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz",
+ "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==",
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.25"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.5.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
+ "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
+ "license": "MIT"
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.31",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
+ "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
+ }
+ },
+ "node_modules/@remix-run/router": {
+ "version": "1.23.1",
+ "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.23.1.tgz",
+ "integrity": "sha512-vDbaOzF7yT2Qs4vO6XV1MHcJv+3dgR1sT+l3B8xxOVhUC336prMvqrvsLL/9Dnw2xr6Qhz4J0dmS0llNAbnUmQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@rolldown/pluginutils": {
+ "version": "1.0.0-beta.27",
+ "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz",
+ "integrity": "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@rollup/rollup-android-arm-eabi": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.54.0.tgz",
+ "integrity": "sha512-OywsdRHrFvCdvsewAInDKCNyR3laPA2mc9bRYJ6LBp5IyvF3fvXbbNR0bSzHlZVFtn6E0xw2oZlyjg4rKCVcng==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-android-arm64": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.54.0.tgz",
+ "integrity": "sha512-Skx39Uv+u7H224Af+bDgNinitlmHyQX1K/atIA32JP3JQw6hVODX5tkbi2zof/E69M1qH2UoN3Xdxgs90mmNYw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-arm64": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.54.0.tgz",
+ "integrity": "sha512-k43D4qta/+6Fq+nCDhhv9yP2HdeKeP56QrUUTW7E6PhZP1US6NDqpJj4MY0jBHlJivVJD5P8NxrjuobZBJTCRw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-x64": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.54.0.tgz",
+ "integrity": "sha512-cOo7biqwkpawslEfox5Vs8/qj83M/aZCSSNIWpVzfU2CYHa2G3P1UN5WF01RdTHSgCkri7XOlTdtk17BezlV3A==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-arm64": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.54.0.tgz",
+ "integrity": "sha512-miSvuFkmvFbgJ1BevMa4CPCFt5MPGw094knM64W9I0giUIMMmRYcGW/JWZDriaw/k1kOBtsWh1z6nIFV1vPNtA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-x64": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.54.0.tgz",
+ "integrity": "sha512-KGXIs55+b/ZfZsq9aR026tmr/+7tq6VG6MsnrvF4H8VhwflTIuYh+LFUlIsRdQSgrgmtM3fVATzEAj4hBQlaqQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.54.0.tgz",
+ "integrity": "sha512-EHMUcDwhtdRGlXZsGSIuXSYwD5kOT9NVnx9sqzYiwAc91wfYOE1g1djOEDseZJKKqtHAHGwnGPQu3kytmfaXLQ==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-musleabihf": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.54.0.tgz",
+ "integrity": "sha512-+pBrqEjaakN2ySv5RVrj/qLytYhPKEUwk+e3SFU5jTLHIcAtqh2rLrd/OkbNuHJpsBgxsD8ccJt5ga/SeG0JmA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-gnu": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.54.0.tgz",
+ "integrity": "sha512-NSqc7rE9wuUaRBsBp5ckQ5CVz5aIRKCwsoa6WMF7G01sX3/qHUw/z4pv+D+ahL1EIKy6Enpcnz1RY8pf7bjwng==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-musl": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.54.0.tgz",
+ "integrity": "sha512-gr5vDbg3Bakga5kbdpqx81m2n9IX8M6gIMlQQIXiLTNeQW6CucvuInJ91EuCJ/JYvc+rcLLsDFcfAD1K7fMofg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-loong64-gnu": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.54.0.tgz",
+ "integrity": "sha512-gsrtB1NA3ZYj2vq0Rzkylo9ylCtW/PhpLEivlgWe0bpgtX5+9j9EZa0wtZiCjgu6zmSeZWyI/e2YRX1URozpIw==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-ppc64-gnu": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.54.0.tgz",
+ "integrity": "sha512-y3qNOfTBStmFNq+t4s7Tmc9hW2ENtPg8FeUD/VShI7rKxNW7O4fFeaYbMsd3tpFlIg1Q8IapFgy7Q9i2BqeBvA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-gnu": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.54.0.tgz",
+ "integrity": "sha512-89sepv7h2lIVPsFma8iwmccN7Yjjtgz0Rj/Ou6fEqg3HDhpCa+Et+YSufy27i6b0Wav69Qv4WBNl3Rs6pwhebQ==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-musl": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.54.0.tgz",
+ "integrity": "sha512-ZcU77ieh0M2Q8Ur7D5X7KvK+UxbXeDHwiOt/CPSBTI1fBmeDMivW0dPkdqkT4rOgDjrDDBUed9x4EgraIKoR2A==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-s390x-gnu": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.54.0.tgz",
+ "integrity": "sha512-2AdWy5RdDF5+4YfG/YesGDDtbyJlC9LHmL6rZw6FurBJ5n4vFGupsOBGfwMRjBYH7qRQowT8D/U4LoSvVwOhSQ==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-gnu": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.54.0.tgz",
+ "integrity": "sha512-WGt5J8Ij/rvyqpFexxk3ffKqqbLf9AqrTBbWDk7ApGUzaIs6V+s2s84kAxklFwmMF/vBNGrVdYgbblCOFFezMQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-musl": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.54.0.tgz",
+ "integrity": "sha512-JzQmb38ATzHjxlPHuTH6tE7ojnMKM2kYNzt44LO/jJi8BpceEC8QuXYA908n8r3CNuG/B3BV8VR3Hi1rYtmPiw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-openharmony-arm64": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.54.0.tgz",
+ "integrity": "sha512-huT3fd0iC7jigGh7n3q/+lfPcXxBi+om/Rs3yiFxjvSxbSB6aohDFXbWvlspaqjeOh+hx7DDHS+5Es5qRkWkZg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-arm64-msvc": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.54.0.tgz",
+ "integrity": "sha512-c2V0W1bsKIKfbLMBu/WGBz6Yci8nJ/ZJdheE0EwB73N3MvHYKiKGs3mVilX4Gs70eGeDaMqEob25Tw2Gb9Nqyw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-ia32-msvc": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.54.0.tgz",
+ "integrity": "sha512-woEHgqQqDCkAzrDhvDipnSirm5vxUXtSKDYTVpZG3nUdW/VVB5VdCYA2iReSj/u3yCZzXID4kuKG7OynPnB3WQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-gnu": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.54.0.tgz",
+ "integrity": "sha512-dzAc53LOuFvHwbCEOS0rPbXp6SIhAf2txMP5p6mGyOXXw5mWY8NGGbPMPrs4P1WItkfApDathBj/NzMLUZ9rtQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-msvc": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.54.0.tgz",
+ "integrity": "sha512-hYT5d3YNdSh3mbCU1gwQyPgQd3T2ne0A3KG8KSBdav5TiBg6eInVmV+TeR5uHufiIgSFg0XsOWGW5/RhNcSvPg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@storybook/preset-scss": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@storybook/preset-scss/-/preset-scss-1.0.3.tgz",
+ "integrity": "sha512-o9Iz6wxPeNENrQa2mKlsDKynBfqU2uWaRP80HeWp4TkGgf7/x3DVF2O7yi9N0x/PI1qzzTTpxlQ90D62XmpiTw==",
+ "license": "MIT",
+ "peerDependencies": {
+ "css-loader": "*",
+ "sass-loader": "*",
+ "style-loader": "*"
+ }
+ },
+ "node_modules/@types/babel__core": {
+ "version": "7.20.5",
+ "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
+ "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.20.7",
+ "@babel/types": "^7.20.7",
+ "@types/babel__generator": "*",
+ "@types/babel__template": "*",
+ "@types/babel__traverse": "*"
+ }
+ },
+ "node_modules/@types/babel__generator": {
+ "version": "7.27.0",
+ "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz",
+ "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "node_modules/@types/babel__template": {
+ "version": "7.4.4",
+ "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz",
+ "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.1.0",
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "node_modules/@types/babel__traverse": {
+ "version": "7.28.0",
+ "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz",
+ "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.28.2"
+ }
+ },
+ "node_modules/@types/eslint": {
+ "version": "9.6.1",
+ "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz",
+ "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "*",
+ "@types/json-schema": "*"
+ }
+ },
+ "node_modules/@types/eslint-scope": {
+ "version": "3.7.7",
+ "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz",
+ "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/eslint": "*",
+ "@types/estree": "*"
+ }
+ },
+ "node_modules/@types/estree": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
+ "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
+ "license": "MIT"
+ },
+ "node_modules/@types/history": {
+ "version": "4.7.11",
+ "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz",
+ "integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/hoist-non-react-statics": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz",
+ "integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==",
+ "dev": true,
+ "dependencies": {
+ "@types/react": "*",
+ "hoist-non-react-statics": "^3.3.0"
+ }
+ },
+ "node_modules/@types/json-schema": {
+ "version": "7.0.15",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
+ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
+ "license": "MIT"
+ },
+ "node_modules/@types/node": {
+ "version": "25.0.3",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-25.0.3.tgz",
+ "integrity": "sha512-W609buLVRVmeW693xKfzHeIV6nJGGz98uCPfeXI1ELMLXVeKYZ9m15fAMSaUPBHYLGFsVRcMmSCksQOrZV9BYA==",
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": "~7.16.0"
+ }
+ },
+ "node_modules/@types/prop-types": {
+ "version": "15.7.4",
+ "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.4.tgz",
+ "integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==",
+ "dev": true
+ },
+ "node_modules/@types/react": {
+ "version": "18.3.27",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.27.tgz",
+ "integrity": "sha512-cisd7gxkzjBKU2GgdYrTdtQx1SORymWyaAFhaxQPK9bYO9ot3Y5OikQRvY0VYQtvwjeQnizCINJAenh/V7MK2w==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@types/prop-types": "*",
+ "csstype": "^3.2.2"
+ }
+ },
+ "node_modules/@types/react-dom": {
+ "version": "18.3.7",
+ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz",
+ "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "^18.0.0"
+ }
+ },
+ "node_modules/@types/react-router": {
+ "version": "5.1.16",
+ "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.16.tgz",
+ "integrity": "sha512-8d7nR/fNSqlTFGHti0R3F9WwIertOaaA1UEB8/jr5l5mDMOs4CidEgvvYMw4ivqrBK+vtVLxyTj2P+Pr/dtgzg==",
+ "dev": true,
+ "dependencies": {
+ "@types/history": "*",
+ "@types/react": "*"
+ }
+ },
+ "node_modules/@types/react-router-dom": {
+ "version": "5.3.3",
+ "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.3.3.tgz",
+ "integrity": "sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/history": "^4.7.11",
+ "@types/react": "*",
+ "@types/react-router": "*"
+ }
+ },
+ "node_modules/@types/styled-components": {
+ "version": "5.1.36",
+ "resolved": "https://registry.npmjs.org/@types/styled-components/-/styled-components-5.1.36.tgz",
+ "integrity": "sha512-pGMRNY5G2rNDKEv2DOiFYa7Ft1r0jrhmgBwHhOMzPTgCjO76bCot0/4uEfqj7K0Jf1KdQmDtAuaDk9EAs9foSw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/hoist-non-react-statics": "*",
+ "@types/react": "*",
+ "csstype": "^3.2.2"
+ }
+ },
+ "node_modules/@types/stylis": {
+ "version": "4.2.5",
+ "resolved": "https://registry.npmjs.org/@types/stylis/-/stylis-4.2.5.tgz",
+ "integrity": "sha512-1Xve+NMN7FWjY14vLoY5tL3BVEQ/n42YLwaqJIPYhotZ9uBHt87VceMwWQpzmdEt2TNXIorIFG+YeCUUW7RInw==",
+ "license": "MIT"
+ },
+ "node_modules/@vitejs/plugin-react": {
+ "version": "4.7.0",
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.7.0.tgz",
+ "integrity": "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/core": "^7.28.0",
+ "@babel/plugin-transform-react-jsx-self": "^7.27.1",
+ "@babel/plugin-transform-react-jsx-source": "^7.27.1",
+ "@rolldown/pluginutils": "1.0.0-beta.27",
+ "@types/babel__core": "^7.20.5",
+ "react-refresh": "^0.17.0"
+ },
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "peerDependencies": {
+ "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0"
+ }
+ },
+ "node_modules/@webassemblyjs/ast": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz",
+ "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@webassemblyjs/helper-numbers": "1.13.2",
+ "@webassemblyjs/helper-wasm-bytecode": "1.13.2"
+ }
+ },
+ "node_modules/@webassemblyjs/floating-point-hex-parser": {
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz",
+ "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==",
+ "license": "MIT"
+ },
+ "node_modules/@webassemblyjs/helper-api-error": {
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz",
+ "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==",
+ "license": "MIT"
+ },
+ "node_modules/@webassemblyjs/helper-buffer": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz",
+ "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==",
+ "license": "MIT"
+ },
+ "node_modules/@webassemblyjs/helper-numbers": {
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz",
+ "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==",
+ "license": "MIT",
+ "dependencies": {
+ "@webassemblyjs/floating-point-hex-parser": "1.13.2",
+ "@webassemblyjs/helper-api-error": "1.13.2",
+ "@xtuc/long": "4.2.2"
+ }
+ },
+ "node_modules/@webassemblyjs/helper-wasm-bytecode": {
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz",
+ "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==",
+ "license": "MIT"
+ },
+ "node_modules/@webassemblyjs/helper-wasm-section": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz",
+ "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==",
+ "license": "MIT",
+ "dependencies": {
+ "@webassemblyjs/ast": "1.14.1",
+ "@webassemblyjs/helper-buffer": "1.14.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
+ "@webassemblyjs/wasm-gen": "1.14.1"
+ }
+ },
+ "node_modules/@webassemblyjs/ieee754": {
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz",
+ "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==",
+ "license": "MIT",
+ "dependencies": {
+ "@xtuc/ieee754": "^1.2.0"
+ }
+ },
+ "node_modules/@webassemblyjs/leb128": {
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz",
+ "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@xtuc/long": "4.2.2"
+ }
+ },
+ "node_modules/@webassemblyjs/utf8": {
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz",
+ "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==",
+ "license": "MIT"
+ },
+ "node_modules/@webassemblyjs/wasm-edit": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz",
+ "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@webassemblyjs/ast": "1.14.1",
+ "@webassemblyjs/helper-buffer": "1.14.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
+ "@webassemblyjs/helper-wasm-section": "1.14.1",
+ "@webassemblyjs/wasm-gen": "1.14.1",
+ "@webassemblyjs/wasm-opt": "1.14.1",
+ "@webassemblyjs/wasm-parser": "1.14.1",
+ "@webassemblyjs/wast-printer": "1.14.1"
+ }
+ },
+ "node_modules/@webassemblyjs/wasm-gen": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz",
+ "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==",
+ "license": "MIT",
+ "dependencies": {
+ "@webassemblyjs/ast": "1.14.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
+ "@webassemblyjs/ieee754": "1.13.2",
+ "@webassemblyjs/leb128": "1.13.2",
+ "@webassemblyjs/utf8": "1.13.2"
+ }
+ },
+ "node_modules/@webassemblyjs/wasm-opt": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz",
+ "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==",
+ "license": "MIT",
+ "dependencies": {
+ "@webassemblyjs/ast": "1.14.1",
+ "@webassemblyjs/helper-buffer": "1.14.1",
+ "@webassemblyjs/wasm-gen": "1.14.1",
+ "@webassemblyjs/wasm-parser": "1.14.1"
+ }
+ },
+ "node_modules/@webassemblyjs/wasm-parser": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz",
+ "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@webassemblyjs/ast": "1.14.1",
+ "@webassemblyjs/helper-api-error": "1.13.2",
+ "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
+ "@webassemblyjs/ieee754": "1.13.2",
+ "@webassemblyjs/leb128": "1.13.2",
+ "@webassemblyjs/utf8": "1.13.2"
+ }
+ },
+ "node_modules/@webassemblyjs/wast-printer": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz",
+ "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==",
+ "license": "MIT",
+ "dependencies": {
+ "@webassemblyjs/ast": "1.14.1",
+ "@xtuc/long": "4.2.2"
+ }
+ },
+ "node_modules/@xtuc/ieee754": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
+ "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@xtuc/long": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz",
+ "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
+ "license": "Apache-2.0"
+ },
+ "node_modules/acorn": {
+ "version": "8.15.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
+ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
+ "license": "MIT",
+ "peer": true,
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-import-phases": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz",
+ "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.13.0"
+ },
+ "peerDependencies": {
+ "acorn": "^8.14.0"
+ }
+ },
+ "node_modules/ajv": {
+ "version": "8.17.1",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
+ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3",
+ "fast-uri": "^3.0.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/ajv-formats": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz",
+ "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==",
+ "license": "MIT",
+ "dependencies": {
+ "ajv": "^8.0.0"
+ },
+ "peerDependencies": {
+ "ajv": "^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "ajv": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/ajv-keywords": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
+ "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3"
+ },
+ "peerDependencies": {
+ "ajv": "^8.8.2"
+ }
+ },
+ "node_modules/baseline-browser-mapping": {
+ "version": "2.9.11",
+ "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.11.tgz",
+ "integrity": "sha512-Sg0xJUNDU1sJNGdfGWhVHX0kkZ+HWcvmVymJbj6NSgZZmW/8S9Y2HQ5euytnIgakgxN6papOAWiwDo1ctFDcoQ==",
+ "license": "Apache-2.0",
+ "bin": {
+ "baseline-browser-mapping": "dist/cli.js"
+ }
+ },
+ "node_modules/browserslist": {
+ "version": "4.28.1",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz",
+ "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "baseline-browser-mapping": "^2.9.0",
+ "caniuse-lite": "^1.0.30001759",
+ "electron-to-chromium": "^1.5.263",
+ "node-releases": "^2.0.27",
+ "update-browserslist-db": "^1.2.0"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ }
+ },
+ "node_modules/buffer-from": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
+ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
+ "license": "MIT"
+ },
+ "node_modules/camelize": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz",
+ "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/caniuse-lite": {
+ "version": "1.0.30001762",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001762.tgz",
+ "integrity": "sha512-PxZwGNvH7Ak8WX5iXzoK1KPZttBXNPuaOvI2ZYU7NrlM+d9Ov+TUvlLOBNGzVXAntMSMMlJPd+jY6ovrVjSmUw==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "CC-BY-4.0"
+ },
+ "node_modules/chrome-trace-event": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz",
+ "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0"
+ }
+ },
+ "node_modules/commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+ "license": "MIT"
+ },
+ "node_modules/convert-source-map": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
+ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cross-fetch": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.2.0.tgz",
+ "integrity": "sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==",
+ "license": "MIT",
+ "dependencies": {
+ "node-fetch": "^2.7.0"
+ }
+ },
+ "node_modules/css-color-keywords": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz",
+ "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==",
+ "license": "ISC",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/css-loader": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-7.1.2.tgz",
+ "integrity": "sha512-6WvYYn7l/XEGN8Xu2vWFt9nVzrCn39vKyTEFf/ExEyoksJjjSZV/0/35XPlMbpnr6VGhZIUg5yJrL8tGfes/FA==",
+ "license": "MIT",
+ "dependencies": {
+ "icss-utils": "^5.1.0",
+ "postcss": "^8.4.33",
+ "postcss-modules-extract-imports": "^3.1.0",
+ "postcss-modules-local-by-default": "^4.0.5",
+ "postcss-modules-scope": "^3.2.0",
+ "postcss-modules-values": "^4.0.0",
+ "postcss-value-parser": "^4.2.0",
+ "semver": "^7.5.4"
+ },
+ "engines": {
+ "node": ">= 18.12.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependencies": {
+ "@rspack/core": "0.x || 1.x",
+ "webpack": "^5.27.0"
+ },
+ "peerDependenciesMeta": {
+ "@rspack/core": {
+ "optional": true
+ },
+ "webpack": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/css-loader/node_modules/semver": {
+ "version": "7.7.3",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
+ "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/css-to-react-native": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz",
+ "integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==",
+ "license": "MIT",
+ "dependencies": {
+ "camelize": "^1.0.0",
+ "css-color-keywords": "^1.0.0",
+ "postcss-value-parser": "^4.0.2"
+ }
+ },
+ "node_modules/cssesc": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
+ "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
+ "license": "MIT",
+ "bin": {
+ "cssesc": "bin/cssesc"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/csstype": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
+ "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/debug": {
+ "version": "4.4.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/electron-to-chromium": {
+ "version": "1.5.267",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz",
+ "integrity": "sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==",
+ "license": "ISC"
+ },
+ "node_modules/enhanced-resolve": {
+ "version": "5.18.4",
+ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.4.tgz",
+ "integrity": "sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==",
+ "license": "MIT",
+ "dependencies": {
+ "graceful-fs": "^4.2.4",
+ "tapable": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/es-module-lexer": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz",
+ "integrity": "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==",
+ "license": "MIT"
+ },
+ "node_modules/esbuild": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.2.tgz",
+ "integrity": "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "optionalDependencies": {
+ "@esbuild/aix-ppc64": "0.27.2",
+ "@esbuild/android-arm": "0.27.2",
+ "@esbuild/android-arm64": "0.27.2",
+ "@esbuild/android-x64": "0.27.2",
+ "@esbuild/darwin-arm64": "0.27.2",
+ "@esbuild/darwin-x64": "0.27.2",
+ "@esbuild/freebsd-arm64": "0.27.2",
+ "@esbuild/freebsd-x64": "0.27.2",
+ "@esbuild/linux-arm": "0.27.2",
+ "@esbuild/linux-arm64": "0.27.2",
+ "@esbuild/linux-ia32": "0.27.2",
+ "@esbuild/linux-loong64": "0.27.2",
+ "@esbuild/linux-mips64el": "0.27.2",
+ "@esbuild/linux-ppc64": "0.27.2",
+ "@esbuild/linux-riscv64": "0.27.2",
+ "@esbuild/linux-s390x": "0.27.2",
+ "@esbuild/linux-x64": "0.27.2",
+ "@esbuild/netbsd-arm64": "0.27.2",
+ "@esbuild/netbsd-x64": "0.27.2",
+ "@esbuild/openbsd-arm64": "0.27.2",
+ "@esbuild/openbsd-x64": "0.27.2",
+ "@esbuild/openharmony-arm64": "0.27.2",
+ "@esbuild/sunos-x64": "0.27.2",
+ "@esbuild/win32-arm64": "0.27.2",
+ "@esbuild/win32-ia32": "0.27.2",
+ "@esbuild/win32-x64": "0.27.2"
+ }
+ },
+ "node_modules/escalade": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
+ "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/eslint-scope": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
+ "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^4.1.1"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/esrecurse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+ "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/esrecurse/node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estraverse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+ "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/events": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
+ "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.x"
+ }
+ },
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+ "license": "MIT"
+ },
+ "node_modules/fast-uri": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz",
+ "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fastify"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/fastify"
+ }
+ ],
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/fdir": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
+ "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "peerDependencies": {
+ "picomatch": "^3 || ^4"
+ },
+ "peerDependenciesMeta": {
+ "picomatch": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/gensync": {
+ "version": "1.0.0-beta.2",
+ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
+ "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/glob-to-regexp": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
+ "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/graceful-fs": {
+ "version": "4.2.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+ "license": "ISC"
+ },
+ "node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/hoist-non-react-statics": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
+ "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
+ "dev": true,
+ "dependencies": {
+ "react-is": "^16.7.0"
+ }
+ },
+ "node_modules/hoist-non-react-statics/node_modules/react-is": {
+ "version": "16.13.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
+ "dev": true
+ },
+ "node_modules/icss-utils": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz",
+ "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==",
+ "license": "ISC",
+ "engines": {
+ "node": "^10 || ^12 || >= 14"
+ },
+ "peerDependencies": {
+ "postcss": "^8.1.0"
+ }
+ },
+ "node_modules/jest-worker": {
+ "version": "27.5.1",
+ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz",
+ "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*",
+ "merge-stream": "^2.0.0",
+ "supports-color": "^8.0.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ }
+ },
+ "node_modules/js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
+ },
+ "node_modules/jsesc": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
+ "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "jsesc": "bin/jsesc"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/json-parse-even-better-errors": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
+ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
+ "license": "MIT"
+ },
+ "node_modules/json-schema-traverse": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+ "license": "MIT"
+ },
+ "node_modules/json5": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "json5": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/loader-runner": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.1.tgz",
+ "integrity": "sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.11.5"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ }
+ },
+ "node_modules/loose-envify": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
+ "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
+ "dependencies": {
+ "js-tokens": "^3.0.0 || ^4.0.0"
+ },
+ "bin": {
+ "loose-envify": "cli.js"
+ }
+ },
+ "node_modules/lru-cache": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+ "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^3.0.2"
+ }
+ },
+ "node_modules/merge-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
+ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+ "license": "MIT"
+ },
+ "node_modules/mime-db": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mime-types": {
+ "version": "2.1.35",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/nanoid": {
+ "version": "3.3.11",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
+ "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/neo-async": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
+ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
+ "license": "MIT"
+ },
+ "node_modules/node-fetch": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
+ "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
+ "license": "MIT",
+ "dependencies": {
+ "whatwg-url": "^5.0.0"
+ },
+ "engines": {
+ "node": "4.x || >=6.0.0"
+ },
+ "peerDependencies": {
+ "encoding": "^0.1.0"
+ },
+ "peerDependenciesMeta": {
+ "encoding": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/node-releases": {
+ "version": "2.0.27",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz",
+ "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==",
+ "license": "MIT"
+ },
+ "node_modules/picocolors": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+ "license": "ISC"
+ },
+ "node_modules/picomatch": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
+ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/postcss": {
+ "version": "8.4.49",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz",
+ "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "nanoid": "^3.3.7",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.1"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/postcss-modules-extract-imports": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz",
+ "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==",
+ "license": "ISC",
+ "engines": {
+ "node": "^10 || ^12 || >= 14"
+ },
+ "peerDependencies": {
+ "postcss": "^8.1.0"
+ }
+ },
+ "node_modules/postcss-modules-local-by-default": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.2.0.tgz",
+ "integrity": "sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw==",
+ "license": "MIT",
+ "dependencies": {
+ "icss-utils": "^5.0.0",
+ "postcss-selector-parser": "^7.0.0",
+ "postcss-value-parser": "^4.1.0"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >= 14"
+ },
+ "peerDependencies": {
+ "postcss": "^8.1.0"
+ }
+ },
+ "node_modules/postcss-modules-scope": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz",
+ "integrity": "sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==",
+ "license": "ISC",
+ "dependencies": {
+ "postcss-selector-parser": "^7.0.0"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >= 14"
+ },
+ "peerDependencies": {
+ "postcss": "^8.1.0"
+ }
+ },
+ "node_modules/postcss-modules-values": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz",
+ "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==",
+ "license": "ISC",
+ "dependencies": {
+ "icss-utils": "^5.0.0"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >= 14"
+ },
+ "peerDependencies": {
+ "postcss": "^8.1.0"
+ }
+ },
+ "node_modules/postcss-selector-parser": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz",
+ "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==",
+ "license": "MIT",
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/postcss-value-parser": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
+ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
+ "license": "MIT"
+ },
+ "node_modules/prettier": {
+ "version": "3.7.4",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.7.4.tgz",
+ "integrity": "sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "prettier": "bin/prettier.cjs"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/prettier/prettier?sponsor=1"
+ }
+ },
+ "node_modules/randombytes": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
+ "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "^5.1.0"
+ }
+ },
+ "node_modules/react": {
+ "version": "18.3.1",
+ "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
+ "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/react-dom": {
+ "version": "18.3.1",
+ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
+ "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "loose-envify": "^1.1.0",
+ "scheduler": "^0.23.2"
+ },
+ "peerDependencies": {
+ "react": "^18.3.1"
+ }
+ },
+ "node_modules/react-is": {
+ "version": "18.3.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
+ "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
+ "license": "MIT"
+ },
+ "node_modules/react-refresh": {
+ "version": "0.17.0",
+ "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz",
+ "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/react-router": {
+ "version": "6.30.2",
+ "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.30.2.tgz",
+ "integrity": "sha512-H2Bm38Zu1bm8KUE5NVWRMzuIyAV8p/JrOaBJAwVmp37AXG72+CZJlEBw6pdn9i5TBgLMhNDgijS4ZlblpHyWTA==",
+ "license": "MIT",
+ "dependencies": {
+ "@remix-run/router": "1.23.1"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.8"
+ }
+ },
+ "node_modules/react-router-dom": {
+ "version": "6.30.2",
+ "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.30.2.tgz",
+ "integrity": "sha512-l2OwHn3UUnEVUqc6/1VMmR1cvZryZ3j3NzapC2eUXO1dB0sYp5mvwdjiXhpUbRb21eFow3qSxpP8Yv6oAU824Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@remix-run/router": "1.23.1",
+ "react-router": "6.30.2"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.8",
+ "react-dom": ">=16.8"
+ }
+ },
+ "node_modules/require-from-string": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
+ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/rollup": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.54.0.tgz",
+ "integrity": "sha512-3nk8Y3a9Ea8szgKhinMlGMhGMw89mqule3KWczxhIzqudyHdCIOHw8WJlj/r329fACjKLEh13ZSk7oE22kyeIw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "1.0.8"
+ },
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=18.0.0",
+ "npm": ">=8.0.0"
+ },
+ "optionalDependencies": {
+ "@rollup/rollup-android-arm-eabi": "4.54.0",
+ "@rollup/rollup-android-arm64": "4.54.0",
+ "@rollup/rollup-darwin-arm64": "4.54.0",
+ "@rollup/rollup-darwin-x64": "4.54.0",
+ "@rollup/rollup-freebsd-arm64": "4.54.0",
+ "@rollup/rollup-freebsd-x64": "4.54.0",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.54.0",
+ "@rollup/rollup-linux-arm-musleabihf": "4.54.0",
+ "@rollup/rollup-linux-arm64-gnu": "4.54.0",
+ "@rollup/rollup-linux-arm64-musl": "4.54.0",
+ "@rollup/rollup-linux-loong64-gnu": "4.54.0",
+ "@rollup/rollup-linux-ppc64-gnu": "4.54.0",
+ "@rollup/rollup-linux-riscv64-gnu": "4.54.0",
+ "@rollup/rollup-linux-riscv64-musl": "4.54.0",
+ "@rollup/rollup-linux-s390x-gnu": "4.54.0",
+ "@rollup/rollup-linux-x64-gnu": "4.54.0",
+ "@rollup/rollup-linux-x64-musl": "4.54.0",
+ "@rollup/rollup-openharmony-arm64": "4.54.0",
+ "@rollup/rollup-win32-arm64-msvc": "4.54.0",
+ "@rollup/rollup-win32-ia32-msvc": "4.54.0",
+ "@rollup/rollup-win32-x64-gnu": "4.54.0",
+ "@rollup/rollup-win32-x64-msvc": "4.54.0",
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/sass-loader": {
+ "version": "16.0.6",
+ "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-16.0.6.tgz",
+ "integrity": "sha512-sglGzId5gmlfxNs4gK2U3h7HlVRfx278YK6Ono5lwzuvi1jxig80YiuHkaDBVsYIKFhx8wN7XSCI0M2IDS/3qA==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "neo-async": "^2.6.2"
+ },
+ "engines": {
+ "node": ">= 18.12.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependencies": {
+ "@rspack/core": "0.x || 1.x",
+ "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0",
+ "sass": "^1.3.0",
+ "sass-embedded": "*",
+ "webpack": "^5.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@rspack/core": {
+ "optional": true
+ },
+ "node-sass": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ },
+ "sass-embedded": {
+ "optional": true
+ },
+ "webpack": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/scheduler": {
+ "version": "0.23.2",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
+ "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",
+ "license": "MIT",
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ }
+ },
+ "node_modules/schema-utils": {
+ "version": "4.3.3",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz",
+ "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/json-schema": "^7.0.9",
+ "ajv": "^8.9.0",
+ "ajv-formats": "^2.1.1",
+ "ajv-keywords": "^5.1.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ }
+ },
+ "node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/serialize-javascript": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz",
+ "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "randombytes": "^2.1.0"
+ }
+ },
+ "node_modules/shallowequal": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz",
+ "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ=="
+ },
+ "node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/source-map-js": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/source-map-support": {
+ "version": "0.5.21",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
+ "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
+ "license": "MIT",
+ "dependencies": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
+ }
+ },
+ "node_modules/style-loader": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-4.0.0.tgz",
+ "integrity": "sha512-1V4WqhhZZgjVAVJyt7TdDPZoPBPNHbekX4fWnCJL1yQukhCeZhJySUL+gL9y6sNdN95uEOS83Y55SqHcP7MzLA==",
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">= 18.12.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependencies": {
+ "webpack": "^5.27.0"
+ }
+ },
+ "node_modules/styled-components": {
+ "version": "6.1.19",
+ "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.19.tgz",
+ "integrity": "sha512-1v/e3Dl1BknC37cXMhwGomhO8AkYmN41CqyX9xhUDxry1ns3BFQy2lLDRQXJRdVVWB9OHemv/53xaStimvWyuA==",
+ "license": "MIT",
+ "dependencies": {
+ "@emotion/is-prop-valid": "1.2.2",
+ "@emotion/unitless": "0.8.1",
+ "@types/stylis": "4.2.5",
+ "css-to-react-native": "3.2.0",
+ "csstype": "3.1.3",
+ "postcss": "8.4.49",
+ "shallowequal": "1.1.0",
+ "stylis": "4.3.2",
+ "tslib": "2.6.2"
+ },
+ "engines": {
+ "node": ">= 16"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/styled-components"
+ },
+ "peerDependencies": {
+ "react": ">= 16.8.0",
+ "react-dom": ">= 16.8.0"
+ }
+ },
+ "node_modules/styled-components/node_modules/csstype": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
+ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
+ "license": "MIT"
+ },
+ "node_modules/stylis": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.2.tgz",
+ "integrity": "sha512-bhtUjWd/z6ltJiQwg0dUfxEJ+W+jdqQd8TbWLWyeIJHlnsqmGLRFFd8e5mA0AZi/zx90smXRlN66YMTcaSFifg==",
+ "license": "MIT"
+ },
+ "node_modules/supports-color": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/supports-color?sponsor=1"
+ }
+ },
+ "node_modules/tapable": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz",
+ "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ }
+ },
+ "node_modules/terser": {
+ "version": "5.44.1",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.44.1.tgz",
+ "integrity": "sha512-t/R3R/n0MSwnnazuPpPNVO60LX0SKL45pyl9YlvxIdkH0Of7D5qM2EVe+yASRIlY5pZ73nclYJfNANGWPwFDZw==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "@jridgewell/source-map": "^0.3.3",
+ "acorn": "^8.15.0",
+ "commander": "^2.20.0",
+ "source-map-support": "~0.5.20"
+ },
+ "bin": {
+ "terser": "bin/terser"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/terser-webpack-plugin": {
+ "version": "5.3.16",
+ "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.16.tgz",
+ "integrity": "sha512-h9oBFCWrq78NyWWVcSwZarJkZ01c2AyGrzs1crmHZO3QUg9D61Wu4NPjBy69n7JqylFF5y+CsUZYmYEIZ3mR+Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/trace-mapping": "^0.3.25",
+ "jest-worker": "^27.4.5",
+ "schema-utils": "^4.3.0",
+ "serialize-javascript": "^6.0.2",
+ "terser": "^5.31.1"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependencies": {
+ "webpack": "^5.1.0"
+ },
+ "peerDependenciesMeta": {
+ "@swc/core": {
+ "optional": true
+ },
+ "esbuild": {
+ "optional": true
+ },
+ "uglify-js": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/tinyglobby": {
+ "version": "0.2.15",
+ "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
+ "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fdir": "^6.5.0",
+ "picomatch": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/SuperchupuDev"
+ }
+ },
+ "node_modules/tr46": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
+ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
+ "license": "MIT"
+ },
+ "node_modules/tslib": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
+ "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==",
+ "license": "0BSD"
+ },
+ "node_modules/typescript": {
+ "version": "5.9.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
+ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
+ },
+ "node_modules/undici-types": {
+ "version": "7.16.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz",
+ "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==",
+ "license": "MIT"
+ },
+ "node_modules/update-browserslist-db": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz",
+ "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "escalade": "^3.2.0",
+ "picocolors": "^1.1.1"
+ },
+ "bin": {
+ "update-browserslist-db": "cli.js"
+ },
+ "peerDependencies": {
+ "browserslist": ">= 4.21.0"
+ }
+ },
+ "node_modules/util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
+ "license": "MIT"
+ },
+ "node_modules/validator": {
+ "version": "13.15.26",
+ "resolved": "https://registry.npmjs.org/validator/-/validator-13.15.26.tgz",
+ "integrity": "sha512-spH26xU080ydGggxRyR1Yhcbgx+j3y5jbNXk/8L+iRvdIEQ4uTRH2Sgf2dokud6Q4oAtsbNvJ1Ft+9xmm6IZcA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/vite": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.0.tgz",
+ "integrity": "sha512-dZwN5L1VlUBewiP6H9s2+B3e3Jg96D0vzN+Ry73sOefebhYr9f94wwkMNN/9ouoU8pV1BqA1d1zGk8928cx0rg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "esbuild": "^0.27.0",
+ "fdir": "^6.5.0",
+ "picomatch": "^4.0.3",
+ "postcss": "^8.5.6",
+ "rollup": "^4.43.0",
+ "tinyglobby": "^0.2.15"
+ },
+ "bin": {
+ "vite": "bin/vite.js"
+ },
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ },
+ "funding": {
+ "url": "https://github.com/vitejs/vite?sponsor=1"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.3"
+ },
+ "peerDependencies": {
+ "@types/node": "^20.19.0 || >=22.12.0",
+ "jiti": ">=1.21.0",
+ "less": "^4.0.0",
+ "lightningcss": "^1.21.0",
+ "sass": "^1.70.0",
+ "sass-embedded": "^1.70.0",
+ "stylus": ">=0.54.8",
+ "sugarss": "^5.0.0",
+ "terser": "^5.16.0",
+ "tsx": "^4.8.1",
+ "yaml": "^2.4.2"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "jiti": {
+ "optional": true
+ },
+ "less": {
+ "optional": true
+ },
+ "lightningcss": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ },
+ "sass-embedded": {
+ "optional": true
+ },
+ "stylus": {
+ "optional": true
+ },
+ "sugarss": {
+ "optional": true
+ },
+ "terser": {
+ "optional": true
+ },
+ "tsx": {
+ "optional": true
+ },
+ "yaml": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vite/node_modules/postcss": {
+ "version": "8.5.6",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
+ "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "nanoid": "^3.3.11",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.1"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/watchpack": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.0.tgz",
+ "integrity": "sha512-e6vZvY6xboSwLz2GD36c16+O/2Z6fKvIf4pOXptw2rY9MVwE/TXc6RGqxD3I3x0a28lwBY7DE+76uTPSsBrrCA==",
+ "license": "MIT",
+ "dependencies": {
+ "glob-to-regexp": "^0.4.1",
+ "graceful-fs": "^4.1.2"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/webidl-conversions": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/webpack": {
+ "version": "5.104.1",
+ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.104.1.tgz",
+ "integrity": "sha512-Qphch25abbMNtekmEGJmeRUhLDbe+QfiWTiqpKYkpCOWY64v9eyl+KRRLmqOFA2AvKPpc9DC6+u2n76tQLBoaA==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@types/eslint-scope": "^3.7.7",
+ "@types/estree": "^1.0.8",
+ "@types/json-schema": "^7.0.15",
+ "@webassemblyjs/ast": "^1.14.1",
+ "@webassemblyjs/wasm-edit": "^1.14.1",
+ "@webassemblyjs/wasm-parser": "^1.14.1",
+ "acorn": "^8.15.0",
+ "acorn-import-phases": "^1.0.3",
+ "browserslist": "^4.28.1",
+ "chrome-trace-event": "^1.0.2",
+ "enhanced-resolve": "^5.17.4",
+ "es-module-lexer": "^2.0.0",
+ "eslint-scope": "5.1.1",
+ "events": "^3.2.0",
+ "glob-to-regexp": "^0.4.1",
+ "graceful-fs": "^4.2.11",
+ "json-parse-even-better-errors": "^2.3.1",
+ "loader-runner": "^4.3.1",
+ "mime-types": "^2.1.27",
+ "neo-async": "^2.6.2",
+ "schema-utils": "^4.3.3",
+ "tapable": "^2.3.0",
+ "terser-webpack-plugin": "^5.3.16",
+ "watchpack": "^2.4.4",
+ "webpack-sources": "^3.3.3"
+ },
+ "bin": {
+ "webpack": "bin/webpack.js"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependenciesMeta": {
+ "webpack-cli": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/webpack-sources": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.3.tgz",
+ "integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/whatwg-url": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
+ "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
+ "license": "MIT",
+ "dependencies": {
+ "tr46": "~0.0.3",
+ "webidl-conversions": "^3.0.0"
+ }
+ },
+ "node_modules/yallist": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+ "dev": true,
+ "license": "ISC"
+ }
+ }
+}
diff --git a/web/app/package.json b/web/app/package.json
new file mode 100644
index 000000000..58a5a4270
--- /dev/null
+++ b/web/app/package.json
@@ -0,0 +1,33 @@
+{
+ "name": "app",
+ "version": "1.0.0",
+ "description": "",
+ "type": "module",
+ "scripts": {
+ "dev": "vite build --watch",
+ "build": "vite build",
+ "preview": "vite preview",
+ "format": "prettier --write 'src/**/*.(ts|tsx|js|jsx)'"
+ },
+ "keywords": [],
+ "author": "Lakhan Samani",
+ "license": "ISC",
+ "dependencies": {
+ "@authorizerdev/authorizer-react": "^2.0.0-rc.2",
+ "react": "^18.3.1",
+ "react-dom": "^18.3.1",
+ "react-is": "^18.3.1",
+ "react-router-dom": "^6.28.0",
+ "styled-components": "^6.1.13"
+ },
+ "devDependencies": {
+ "@types/react": "^18.3.12",
+ "@types/react-dom": "^18.3.1",
+ "@types/react-router-dom": "^5.3.3",
+ "@types/styled-components": "^5.1.34",
+ "@vitejs/plugin-react": "^4.3.1",
+ "prettier": "^3.3.3",
+ "typescript": "^5.6.3",
+ "vite": "^7.3.0"
+ }
+}
diff --git a/app/src/App.tsx b/web/app/src/App.tsx
similarity index 98%
rename from app/src/App.tsx
rename to web/app/src/App.tsx
index 9b4f8b547..281f6f247 100644
--- a/app/src/App.tsx
+++ b/web/app/src/App.tsx
@@ -1,4 +1,3 @@
-import React from 'react';
import { BrowserRouter } from 'react-router-dom';
import { AuthorizerProvider } from '@authorizerdev/authorizer-react';
import Root from './Root';
diff --git a/app/src/Root.tsx b/web/app/src/Root.tsx
similarity index 70%
rename from app/src/Root.tsx
rename to web/app/src/Root.tsx
index 11e42546a..56a04c98a 100644
--- a/app/src/Root.tsx
+++ b/web/app/src/Root.tsx
@@ -1,29 +1,14 @@
-import React, { useEffect, lazy, Suspense } from 'react';
-import { Switch, Route } from 'react-router-dom';
+import { useEffect, lazy, Suspense } from 'react';
+import { Routes, Route } from 'react-router-dom';
import { useAuthorizer } from '@authorizerdev/authorizer-react';
-import styled, { ThemeProvider } from 'styled-components';
import SetupPassword from './pages/setup-password';
import { hasWindow, createRandomString } from './utils/common';
-import { theme } from './theme';
const ResetPassword = lazy(() => import('./pages/rest-password'));
const Login = lazy(() => import('./pages/login'));
const Dashboard = lazy(() => import('./pages/dashboard'));
const SignUp = lazy(() => import('./pages/signup'));
-const Wrapper = styled.div`
- font-family: ${(props) => props.theme.fonts.fontStack};
- color: ${(props) => props.theme.colors.textColor};
- font-size: ${(props) => props.theme.fonts.mediumText};
- box-sizing: border-box;
-
- *,
- *:before,
- *:after {
- box-sizing: inherit;
- }
-`;
-
export default function Root({
globalState,
}: {
@@ -97,35 +82,21 @@ export default function Root({
if (token) {
return (
>}>
-
-
-
-
-
+
+ } />
+
);
}
return (
>}>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+ } />
+ } />
+ } />
+ } />
+
);
}
diff --git a/app/src/index.css b/web/app/src/index.css
similarity index 65%
rename from app/src/index.css
rename to web/app/src/index.css
index c86863c54..b43f92ee1 100644
--- a/app/src/index.css
+++ b/web/app/src/index.css
@@ -1,8 +1,8 @@
body {
margin: 10;
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
- 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
- sans-serif;
+ font-family:
+ -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu',
+ 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
color: #374151;
@@ -16,7 +16,7 @@ body {
}
.container {
- box-sizing: content-box;
+ box-sizing: border-box;
border: 1px solid #d1d5db;
padding: 25px 20px;
border-radius: 5px;
diff --git a/web/app/src/index.tsx b/web/app/src/index.tsx
new file mode 100644
index 000000000..6561a41be
--- /dev/null
+++ b/web/app/src/index.tsx
@@ -0,0 +1,14 @@
+import React from 'react';
+import ReactDOM from 'react-dom/client';
+import App from './App';
+import './index.css';
+import '@authorizerdev/authorizer-react/styles.css';
+
+const root = ReactDOM.createRoot(
+ document.getElementById('root') as HTMLElement,
+);
+root.render(
+
+
+ ,
+);
diff --git a/app/src/pages/dashboard.tsx b/web/app/src/pages/dashboard.tsx
similarity index 100%
rename from app/src/pages/dashboard.tsx
rename to web/app/src/pages/dashboard.tsx
diff --git a/app/src/pages/login.tsx b/web/app/src/pages/login.tsx
similarity index 100%
rename from app/src/pages/login.tsx
rename to web/app/src/pages/login.tsx
diff --git a/app/src/pages/rest-password.tsx b/web/app/src/pages/rest-password.tsx
similarity index 100%
rename from app/src/pages/rest-password.tsx
rename to web/app/src/pages/rest-password.tsx
diff --git a/app/src/pages/setup-password.tsx b/web/app/src/pages/setup-password.tsx
similarity index 100%
rename from app/src/pages/setup-password.tsx
rename to web/app/src/pages/setup-password.tsx
diff --git a/app/src/pages/signup.tsx b/web/app/src/pages/signup.tsx
similarity index 100%
rename from app/src/pages/signup.tsx
rename to web/app/src/pages/signup.tsx
diff --git a/web/app/src/styled.d.ts b/web/app/src/styled.d.ts
new file mode 100644
index 000000000..1daffa540
--- /dev/null
+++ b/web/app/src/styled.d.ts
@@ -0,0 +1,26 @@
+import 'styled-components';
+
+declare module 'styled-components' {
+ export interface DefaultTheme {
+ colors: {
+ primary: string;
+ primaryDisabled: string;
+ gray: string;
+ danger: string;
+ success: string;
+ textColor: string;
+ };
+ fonts: {
+ fontStack: string;
+ largeText: string;
+ mediumText: string;
+ smallText: string;
+ tinyText: string;
+ };
+ radius: {
+ card: string;
+ button: string;
+ input: string;
+ };
+ }
+}
diff --git a/app/src/theme.ts b/web/app/src/theme.ts
similarity index 100%
rename from app/src/theme.ts
rename to web/app/src/theme.ts
diff --git a/app/src/utils/common.ts b/web/app/src/utils/common.ts
similarity index 100%
rename from app/src/utils/common.ts
rename to web/app/src/utils/common.ts
diff --git a/dashboard/tsconfig.json b/web/app/tsconfig.json
similarity index 77%
rename from dashboard/tsconfig.json
rename to web/app/tsconfig.json
index ad505d2ed..d6d92a54e 100644
--- a/dashboard/tsconfig.json
+++ b/web/app/tsconfig.json
@@ -1,15 +1,21 @@
{
+ "include": ["src/**/*"],
+ "exclude": ["node_modules", "build", "dist"],
"compilerOptions": {
/* Visit https://aka.ms/tsconfig.json to read more about this file */
/* Basic Options */
// "incremental": true, /* Enable incremental compilation */
- "target": "es6" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', 'ES2021', or 'ESNEXT'. */,
- "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */,
- // "lib": ["es2018", "dom"], /* Specify library files to be included in the compilation. */
- // "allowJs": true, /* Allow javascript files to be compiled. */
+ "target": "ES2020" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', 'ES2021', or 'ESNEXT'. */,
+ "module": "ESNext" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */,
+ "lib": [
+ "ES2020",
+ "DOM",
+ "DOM.Iterable"
+ ] /* Specify library files to be included in the compilation. */,
+ "allowJs": true /* Allow javascript files to be compiled. */,
// "checkJs": true, /* Report errors in .js files. */
- "jsx": "react" /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */,
+ "jsx": "react-jsx" /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */,
// "declaration": true, /* Generates corresponding '.d.ts' file. */
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
// "sourceMap": true, /* Generates corresponding '.map' file. */
@@ -19,10 +25,10 @@
// "composite": true, /* Enable project compilation */
// "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
// "removeComments": true, /* Do not emit comments to output. */
- // "noEmit": true, /* Do not emit outputs. */
+ "noEmit": true /* Do not emit outputs. */,
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
- // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
+ "isolatedModules": true /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */,
/* Strict Type-Checking Options */
"strict": true /* Enable all strict type-checking options. */,
@@ -44,13 +50,15 @@
// "noPropertyAccessFromIndexSignature": true, /* Require undeclared properties from index signatures to use element accesses. */
/* Module Resolution Options */
- // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
- // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
- // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
+ "moduleResolution": "bundler" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */,
+ "baseUrl": "." /* Base directory to resolve non-absolute module names. */,
+ "paths": {
+ "@/*": ["./src/*"]
+ } /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */,
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
// "typeRoots": [], /* List of folders to include type definitions from. */
// "types": [], /* Type declaration files to be included in compilation. */
- // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
+ "allowSyntheticDefaultImports": true /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */,
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
@@ -67,7 +75,6 @@
/* Advanced Options */
"skipLibCheck": true /* Skip type checking of declaration files. */,
- "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */,
- "lib": ["esnext", "dom"]
+ "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
}
}
diff --git a/web/app/vite.config.ts b/web/app/vite.config.ts
new file mode 100644
index 000000000..1aa676c97
--- /dev/null
+++ b/web/app/vite.config.ts
@@ -0,0 +1,28 @@
+import { defineConfig } from 'vite';
+import react from '@vitejs/plugin-react';
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [react()],
+ build: {
+ outDir: 'build',
+ emptyOutDir: true,
+ rollupOptions: {
+ input: {
+ main: 'src/index.tsx',
+ },
+ output: {
+ entryFileNames: 'index.js',
+ chunkFileNames: 'chunk-[name]-[hash].js',
+ assetFileNames: (assetInfo) => {
+ // Name all CSS files as index.css (since cssCodeSplit is false, there's only one)
+ if (assetInfo.name && assetInfo.name.includes('.css')) {
+ return 'index.css';
+ }
+ return 'assets/[name]-[hash][extname]';
+ },
+ },
+ },
+ cssCodeSplit: false, // Ensure CSS is in a single file
+ },
+});
diff --git a/dashboard/.prettierrc.json b/web/dashboard/.prettierrc.json
similarity index 100%
rename from dashboard/.prettierrc.json
rename to web/dashboard/.prettierrc.json
diff --git a/dashboard/README.md b/web/dashboard/README.md
similarity index 100%
rename from dashboard/README.md
rename to web/dashboard/README.md
diff --git a/dashboard/favicon_io/android-chrome-192x192.png b/web/dashboard/favicon_io/android-chrome-192x192.png
similarity index 100%
rename from dashboard/favicon_io/android-chrome-192x192.png
rename to web/dashboard/favicon_io/android-chrome-192x192.png
diff --git a/dashboard/favicon_io/android-chrome-512x512.png b/web/dashboard/favicon_io/android-chrome-512x512.png
similarity index 100%
rename from dashboard/favicon_io/android-chrome-512x512.png
rename to web/dashboard/favicon_io/android-chrome-512x512.png
diff --git a/dashboard/favicon_io/apple-touch-icon.png b/web/dashboard/favicon_io/apple-touch-icon.png
similarity index 100%
rename from dashboard/favicon_io/apple-touch-icon.png
rename to web/dashboard/favicon_io/apple-touch-icon.png
diff --git a/dashboard/favicon_io/favicon-16x16.png b/web/dashboard/favicon_io/favicon-16x16.png
similarity index 100%
rename from dashboard/favicon_io/favicon-16x16.png
rename to web/dashboard/favicon_io/favicon-16x16.png
diff --git a/dashboard/favicon_io/favicon-32x32.png b/web/dashboard/favicon_io/favicon-32x32.png
similarity index 100%
rename from dashboard/favicon_io/favicon-32x32.png
rename to web/dashboard/favicon_io/favicon-32x32.png
diff --git a/dashboard/favicon_io/favicon.ico b/web/dashboard/favicon_io/favicon.ico
similarity index 100%
rename from dashboard/favicon_io/favicon.ico
rename to web/dashboard/favicon_io/favicon.ico
diff --git a/web/dashboard/package-lock.json b/web/dashboard/package-lock.json
new file mode 100644
index 000000000..a4308d66d
--- /dev/null
+++ b/web/dashboard/package-lock.json
@@ -0,0 +1,3055 @@
+{
+ "name": "dashboard",
+ "version": "1.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "dashboard",
+ "version": "1.0.0",
+ "license": "ISC",
+ "dependencies": {
+ "@chakra-ui/icons": "^2.1.2",
+ "@chakra-ui/react": "^2.9.2",
+ "@emotion/react": "^11.13.5",
+ "@emotion/styled": "^11.13.5",
+ "@urql/core": "^4.2.2",
+ "dayjs": "^1.11.13",
+ "focus-visible": "^5.2.1",
+ "framer-motion": "^11.11.17",
+ "graphql": "^16.9.0",
+ "lodash": "^4.17.21",
+ "react": "^18.3.1",
+ "react-dom": "^18.3.1",
+ "react-draft-wysiwyg": "^1.15.0",
+ "react-dropzone": "^14.3.8",
+ "react-email-editor": "^1.7.11",
+ "react-icons": "^5.5.0",
+ "react-router-dom": "^7.0.2",
+ "urql": "^4.2.2"
+ },
+ "devDependencies": {
+ "@types/lodash": "^4.17.7",
+ "@types/react": "^18.3.12",
+ "@types/react-dom": "^18.3.1",
+ "@types/react-email-editor": "^1.7.0",
+ "@types/react-router-dom": "^5.3.3",
+ "@vitejs/plugin-react": "^4.3.1",
+ "prettier": "^3.3.3",
+ "typescript": "^5.6.3",
+ "vite": "^7.3.0"
+ }
+ },
+ "node_modules/@0no-co/graphql.web": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@0no-co/graphql.web/-/graphql.web-1.1.2.tgz",
+ "integrity": "sha512-N2NGsU5FLBhT8NZ+3l2YrzZSHITjNXNuDhC4iDiikv0IujaJ0Xc6xIxQZ/Ek3Cb+rgPjnLHYyJm11tInuJn+cw==",
+ "peerDependencies": {
+ "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0"
+ },
+ "peerDependenciesMeta": {
+ "graphql": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@babel/code-frame": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz",
+ "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==",
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.27.1",
+ "js-tokens": "^4.0.0",
+ "picocolors": "^1.1.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/compat-data": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.5.tgz",
+ "integrity": "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/core": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz",
+ "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.27.1",
+ "@babel/generator": "^7.28.5",
+ "@babel/helper-compilation-targets": "^7.27.2",
+ "@babel/helper-module-transforms": "^7.28.3",
+ "@babel/helpers": "^7.28.4",
+ "@babel/parser": "^7.28.5",
+ "@babel/template": "^7.27.2",
+ "@babel/traverse": "^7.28.5",
+ "@babel/types": "^7.28.5",
+ "@jridgewell/remapping": "^2.3.5",
+ "convert-source-map": "^2.0.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.2",
+ "json5": "^2.2.3",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/babel"
+ }
+ },
+ "node_modules/@babel/core/node_modules/convert-source-map": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
+ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@babel/generator": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz",
+ "integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.28.5",
+ "@babel/types": "^7.28.5",
+ "@jridgewell/gen-mapping": "^0.3.12",
+ "@jridgewell/trace-mapping": "^0.3.28",
+ "jsesc": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets": {
+ "version": "7.27.2",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz",
+ "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/compat-data": "^7.27.2",
+ "@babel/helper-validator-option": "^7.27.1",
+ "browserslist": "^4.24.0",
+ "lru-cache": "^5.1.1",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-globals": {
+ "version": "7.28.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz",
+ "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-imports": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz",
+ "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==",
+ "dependencies": {
+ "@babel/traverse": "^7.27.1",
+ "@babel/types": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-transforms": {
+ "version": "7.28.3",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz",
+ "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.27.1",
+ "@babel/helper-validator-identifier": "^7.27.1",
+ "@babel/traverse": "^7.28.3"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-plugin-utils": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz",
+ "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-string-parser": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
+ "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz",
+ "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-option": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz",
+ "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helpers": {
+ "version": "7.28.4",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz",
+ "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/template": "^7.27.2",
+ "@babel/types": "^7.28.4"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/parser": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz",
+ "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.28.5"
+ },
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-react-jsx-self": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz",
+ "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-react-jsx-source": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz",
+ "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/runtime": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.1.tgz",
+ "integrity": "sha512-1x3D2xEk2fRo3PAhwQwu5UubzgiVWSXTBfWpVd2Mx2AzRqJuDJCsgaDVZ7HB5iGzDW1Hl1sWN2mFyKjmR9uAog==",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/template": {
+ "version": "7.27.2",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz",
+ "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==",
+ "dependencies": {
+ "@babel/code-frame": "^7.27.1",
+ "@babel/parser": "^7.27.2",
+ "@babel/types": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/traverse": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz",
+ "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.27.1",
+ "@babel/generator": "^7.28.5",
+ "@babel/helper-globals": "^7.28.0",
+ "@babel/parser": "^7.28.5",
+ "@babel/template": "^7.27.2",
+ "@babel/types": "^7.28.5",
+ "debug": "^4.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/types": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz",
+ "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-string-parser": "^7.27.1",
+ "@babel/helper-validator-identifier": "^7.28.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@chakra-ui/anatomy": {
+ "version": "2.3.6",
+ "resolved": "https://registry.npmjs.org/@chakra-ui/anatomy/-/anatomy-2.3.6.tgz",
+ "integrity": "sha512-TjmjyQouIZzha/l8JxdBZN1pKZTj7sLpJ0YkFnQFyqHcbfWggW9jKWzY1E0VBnhtFz/xF3KC6UAVuZVSJx+y0g=="
+ },
+ "node_modules/@chakra-ui/hooks": {
+ "version": "2.4.4",
+ "resolved": "https://registry.npmjs.org/@chakra-ui/hooks/-/hooks-2.4.4.tgz",
+ "integrity": "sha512-+gMwLIkabtddIL/GICU7JmnYtvfONP+fNiTfdYLV9/I1eyCz8igKgLmFJOGM6F+BpUev6hh+/+DX5ezGQ9VTbQ==",
+ "dependencies": {
+ "@chakra-ui/utils": "2.2.4",
+ "@zag-js/element-size": "0.31.1",
+ "copy-to-clipboard": "3.3.3",
+ "framesync": "6.1.2"
+ },
+ "peerDependencies": {
+ "react": ">=18"
+ }
+ },
+ "node_modules/@chakra-ui/icons": {
+ "version": "2.2.4",
+ "resolved": "https://registry.npmjs.org/@chakra-ui/icons/-/icons-2.2.4.tgz",
+ "integrity": "sha512-l5QdBgwrAg3Sc2BRqtNkJpfuLw/pWRDwwT58J6c4PqQT6wzXxyNa8Q0PForu1ltB5qEiFb1kxr/F/HO1EwNa6g==",
+ "peerDependencies": {
+ "@chakra-ui/react": ">=2.0.0",
+ "react": ">=18"
+ }
+ },
+ "node_modules/@chakra-ui/react": {
+ "version": "2.10.7",
+ "resolved": "https://registry.npmjs.org/@chakra-ui/react/-/react-2.10.7.tgz",
+ "integrity": "sha512-GX1dCmnvrxxyZEofDX9GMAtRakZJKnUqFM9k8qhaycPaeyfkiTNNTjhPNX917hgVx1yhC3kcJOs5IeC7yW56/g==",
+ "peer": true,
+ "dependencies": {
+ "@chakra-ui/hooks": "2.4.4",
+ "@chakra-ui/styled-system": "2.12.2",
+ "@chakra-ui/theme": "3.4.8",
+ "@chakra-ui/utils": "2.2.4",
+ "@popperjs/core": "^2.11.8",
+ "@zag-js/focus-visible": "^0.31.1",
+ "aria-hidden": "^1.2.3",
+ "react-fast-compare": "3.2.2",
+ "react-focus-lock": "^2.9.6",
+ "react-remove-scroll": "^2.5.7"
+ },
+ "peerDependencies": {
+ "@emotion/react": ">=11",
+ "@emotion/styled": ">=11",
+ "framer-motion": ">=4.0.0",
+ "react": ">=18",
+ "react-dom": ">=18"
+ }
+ },
+ "node_modules/@chakra-ui/styled-system": {
+ "version": "2.12.2",
+ "resolved": "https://registry.npmjs.org/@chakra-ui/styled-system/-/styled-system-2.12.2.tgz",
+ "integrity": "sha512-BlQ7i3+GYC0S0c72B+paa0sYo+QeNSMfz6fwQRFsc8A5Aax9i9lSdRL+vwJVC+k6r/0HWfRwk016R2RD2ihEwQ==",
+ "peer": true,
+ "dependencies": {
+ "@chakra-ui/utils": "2.2.4",
+ "csstype": "^3.1.2"
+ }
+ },
+ "node_modules/@chakra-ui/theme": {
+ "version": "3.4.8",
+ "resolved": "https://registry.npmjs.org/@chakra-ui/theme/-/theme-3.4.8.tgz",
+ "integrity": "sha512-ZLMP2Gek38ZTIlj+sMZLsd1TW27yVdmUKMfBmjsr1psAeOa5bDBLKDszICjhEqk7gAbiWB7jr1/HzBXid4kduQ==",
+ "dependencies": {
+ "@chakra-ui/anatomy": "2.3.6",
+ "@chakra-ui/theme-tools": "2.2.8",
+ "@chakra-ui/utils": "2.2.4"
+ },
+ "peerDependencies": {
+ "@chakra-ui/styled-system": ">=2.8.0"
+ }
+ },
+ "node_modules/@chakra-ui/theme-tools": {
+ "version": "2.2.8",
+ "resolved": "https://registry.npmjs.org/@chakra-ui/theme-tools/-/theme-tools-2.2.8.tgz",
+ "integrity": "sha512-X2i2qgkG+k3DQfh/adn3zzM4Ty8QrGobVPjMl9rMrEYq3ac+pur6KVdVHy/SwwoPvB6S4i84uq7y35+KbJan9g==",
+ "dependencies": {
+ "@chakra-ui/anatomy": "2.3.6",
+ "@chakra-ui/utils": "2.2.4",
+ "color2k": "^2.0.2"
+ },
+ "peerDependencies": {
+ "@chakra-ui/styled-system": ">=2.0.0"
+ }
+ },
+ "node_modules/@chakra-ui/utils": {
+ "version": "2.2.4",
+ "resolved": "https://registry.npmjs.org/@chakra-ui/utils/-/utils-2.2.4.tgz",
+ "integrity": "sha512-nRpR9SnX7aLcJx7lKu8kgQWxdJso1oR/78HcBI+mzidvWdTykbTGdm5Q2R7S0PVH1IFBzBTgi6TiAjHvu96auA==",
+ "dependencies": {
+ "@types/lodash.mergewith": "4.6.9",
+ "lodash.mergewith": "4.6.2"
+ },
+ "peerDependencies": {
+ "react": ">=16.8.0"
+ }
+ },
+ "node_modules/@emotion/babel-plugin": {
+ "version": "11.13.5",
+ "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.13.5.tgz",
+ "integrity": "sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ==",
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.16.7",
+ "@babel/runtime": "^7.18.3",
+ "@emotion/hash": "^0.9.2",
+ "@emotion/memoize": "^0.9.0",
+ "@emotion/serialize": "^1.3.3",
+ "babel-plugin-macros": "^3.1.0",
+ "convert-source-map": "^1.5.0",
+ "escape-string-regexp": "^4.0.0",
+ "find-root": "^1.1.0",
+ "source-map": "^0.5.7",
+ "stylis": "4.2.0"
+ }
+ },
+ "node_modules/@emotion/cache": {
+ "version": "11.14.0",
+ "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.14.0.tgz",
+ "integrity": "sha512-L/B1lc/TViYk4DcpGxtAVbx0ZyiKM5ktoIyafGkH6zg/tj+mA+NE//aPYKG0k8kCHSHVJrpLpcAlOBEXQ3SavA==",
+ "dependencies": {
+ "@emotion/memoize": "^0.9.0",
+ "@emotion/sheet": "^1.4.0",
+ "@emotion/utils": "^1.4.2",
+ "@emotion/weak-memoize": "^0.4.0",
+ "stylis": "4.2.0"
+ }
+ },
+ "node_modules/@emotion/hash": {
+ "version": "0.9.2",
+ "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz",
+ "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g=="
+ },
+ "node_modules/@emotion/is-prop-valid": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.3.1.tgz",
+ "integrity": "sha512-/ACwoqx7XQi9knQs/G0qKvv5teDMhD7bXYns9N/wM8ah8iNb8jZ2uNO0YOgiq2o2poIvVtJS2YALasQuMSQ7Kw==",
+ "dependencies": {
+ "@emotion/memoize": "^0.9.0"
+ }
+ },
+ "node_modules/@emotion/memoize": {
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz",
+ "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ=="
+ },
+ "node_modules/@emotion/react": {
+ "version": "11.14.0",
+ "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.14.0.tgz",
+ "integrity": "sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==",
+ "peer": true,
+ "dependencies": {
+ "@babel/runtime": "^7.18.3",
+ "@emotion/babel-plugin": "^11.13.5",
+ "@emotion/cache": "^11.14.0",
+ "@emotion/serialize": "^1.3.3",
+ "@emotion/use-insertion-effect-with-fallbacks": "^1.2.0",
+ "@emotion/utils": "^1.4.2",
+ "@emotion/weak-memoize": "^0.4.0",
+ "hoist-non-react-statics": "^3.3.1"
+ },
+ "peerDependencies": {
+ "react": ">=16.8.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@emotion/serialize": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.3.tgz",
+ "integrity": "sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA==",
+ "dependencies": {
+ "@emotion/hash": "^0.9.2",
+ "@emotion/memoize": "^0.9.0",
+ "@emotion/unitless": "^0.10.0",
+ "@emotion/utils": "^1.4.2",
+ "csstype": "^3.0.2"
+ }
+ },
+ "node_modules/@emotion/sheet": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz",
+ "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg=="
+ },
+ "node_modules/@emotion/styled": {
+ "version": "11.14.0",
+ "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.14.0.tgz",
+ "integrity": "sha512-XxfOnXFffatap2IyCeJyNov3kiDQWoR08gPUQxvbL7fxKryGBKUZUkG6Hz48DZwVrJSVh9sJboyV1Ds4OW6SgA==",
+ "peer": true,
+ "dependencies": {
+ "@babel/runtime": "^7.18.3",
+ "@emotion/babel-plugin": "^11.13.5",
+ "@emotion/is-prop-valid": "^1.3.0",
+ "@emotion/serialize": "^1.3.3",
+ "@emotion/use-insertion-effect-with-fallbacks": "^1.2.0",
+ "@emotion/utils": "^1.4.2"
+ },
+ "peerDependencies": {
+ "@emotion/react": "^11.0.0-rc.0",
+ "react": ">=16.8.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@emotion/unitless": {
+ "version": "0.10.0",
+ "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz",
+ "integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg=="
+ },
+ "node_modules/@emotion/use-insertion-effect-with-fallbacks": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.2.0.tgz",
+ "integrity": "sha512-yJMtVdH59sxi/aVJBpk9FQq+OR8ll5GT8oWd57UpeaKEVGab41JWaCFA7FRLoMLloOZF/c/wsPoe+bfGmRKgDg==",
+ "peerDependencies": {
+ "react": ">=16.8.0"
+ }
+ },
+ "node_modules/@emotion/utils": {
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.2.tgz",
+ "integrity": "sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA=="
+ },
+ "node_modules/@emotion/weak-memoize": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz",
+ "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg=="
+ },
+ "node_modules/@esbuild/aix-ppc64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.2.tgz",
+ "integrity": "sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.2.tgz",
+ "integrity": "sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.2.tgz",
+ "integrity": "sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.2.tgz",
+ "integrity": "sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.2.tgz",
+ "integrity": "sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.2.tgz",
+ "integrity": "sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.2.tgz",
+ "integrity": "sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.2.tgz",
+ "integrity": "sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.2.tgz",
+ "integrity": "sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.2.tgz",
+ "integrity": "sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.2.tgz",
+ "integrity": "sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.2.tgz",
+ "integrity": "sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.2.tgz",
+ "integrity": "sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.2.tgz",
+ "integrity": "sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.2.tgz",
+ "integrity": "sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.2.tgz",
+ "integrity": "sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.2.tgz",
+ "integrity": "sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-arm64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.2.tgz",
+ "integrity": "sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.2.tgz",
+ "integrity": "sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-arm64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.2.tgz",
+ "integrity": "sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.2.tgz",
+ "integrity": "sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openharmony-arm64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.2.tgz",
+ "integrity": "sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.2.tgz",
+ "integrity": "sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.2.tgz",
+ "integrity": "sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.2.tgz",
+ "integrity": "sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.2.tgz",
+ "integrity": "sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.13",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
+ "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.0",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ }
+ },
+ "node_modules/@jridgewell/remapping": {
+ "version": "2.3.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz",
+ "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ }
+ },
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.5.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
+ "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
+ "license": "MIT"
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.31",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
+ "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
+ }
+ },
+ "node_modules/@popperjs/core": {
+ "version": "2.11.8",
+ "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
+ "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/popperjs"
+ }
+ },
+ "node_modules/@rolldown/pluginutils": {
+ "version": "1.0.0-beta.27",
+ "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz",
+ "integrity": "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@rollup/rollup-android-arm-eabi": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.54.0.tgz",
+ "integrity": "sha512-OywsdRHrFvCdvsewAInDKCNyR3laPA2mc9bRYJ6LBp5IyvF3fvXbbNR0bSzHlZVFtn6E0xw2oZlyjg4rKCVcng==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-android-arm64": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.54.0.tgz",
+ "integrity": "sha512-Skx39Uv+u7H224Af+bDgNinitlmHyQX1K/atIA32JP3JQw6hVODX5tkbi2zof/E69M1qH2UoN3Xdxgs90mmNYw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-arm64": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.54.0.tgz",
+ "integrity": "sha512-k43D4qta/+6Fq+nCDhhv9yP2HdeKeP56QrUUTW7E6PhZP1US6NDqpJj4MY0jBHlJivVJD5P8NxrjuobZBJTCRw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-x64": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.54.0.tgz",
+ "integrity": "sha512-cOo7biqwkpawslEfox5Vs8/qj83M/aZCSSNIWpVzfU2CYHa2G3P1UN5WF01RdTHSgCkri7XOlTdtk17BezlV3A==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-arm64": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.54.0.tgz",
+ "integrity": "sha512-miSvuFkmvFbgJ1BevMa4CPCFt5MPGw094knM64W9I0giUIMMmRYcGW/JWZDriaw/k1kOBtsWh1z6nIFV1vPNtA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-x64": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.54.0.tgz",
+ "integrity": "sha512-KGXIs55+b/ZfZsq9aR026tmr/+7tq6VG6MsnrvF4H8VhwflTIuYh+LFUlIsRdQSgrgmtM3fVATzEAj4hBQlaqQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.54.0.tgz",
+ "integrity": "sha512-EHMUcDwhtdRGlXZsGSIuXSYwD5kOT9NVnx9sqzYiwAc91wfYOE1g1djOEDseZJKKqtHAHGwnGPQu3kytmfaXLQ==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-musleabihf": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.54.0.tgz",
+ "integrity": "sha512-+pBrqEjaakN2ySv5RVrj/qLytYhPKEUwk+e3SFU5jTLHIcAtqh2rLrd/OkbNuHJpsBgxsD8ccJt5ga/SeG0JmA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-gnu": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.54.0.tgz",
+ "integrity": "sha512-NSqc7rE9wuUaRBsBp5ckQ5CVz5aIRKCwsoa6WMF7G01sX3/qHUw/z4pv+D+ahL1EIKy6Enpcnz1RY8pf7bjwng==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-musl": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.54.0.tgz",
+ "integrity": "sha512-gr5vDbg3Bakga5kbdpqx81m2n9IX8M6gIMlQQIXiLTNeQW6CucvuInJ91EuCJ/JYvc+rcLLsDFcfAD1K7fMofg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-loong64-gnu": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.54.0.tgz",
+ "integrity": "sha512-gsrtB1NA3ZYj2vq0Rzkylo9ylCtW/PhpLEivlgWe0bpgtX5+9j9EZa0wtZiCjgu6zmSeZWyI/e2YRX1URozpIw==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-ppc64-gnu": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.54.0.tgz",
+ "integrity": "sha512-y3qNOfTBStmFNq+t4s7Tmc9hW2ENtPg8FeUD/VShI7rKxNW7O4fFeaYbMsd3tpFlIg1Q8IapFgy7Q9i2BqeBvA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-gnu": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.54.0.tgz",
+ "integrity": "sha512-89sepv7h2lIVPsFma8iwmccN7Yjjtgz0Rj/Ou6fEqg3HDhpCa+Et+YSufy27i6b0Wav69Qv4WBNl3Rs6pwhebQ==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-musl": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.54.0.tgz",
+ "integrity": "sha512-ZcU77ieh0M2Q8Ur7D5X7KvK+UxbXeDHwiOt/CPSBTI1fBmeDMivW0dPkdqkT4rOgDjrDDBUed9x4EgraIKoR2A==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-s390x-gnu": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.54.0.tgz",
+ "integrity": "sha512-2AdWy5RdDF5+4YfG/YesGDDtbyJlC9LHmL6rZw6FurBJ5n4vFGupsOBGfwMRjBYH7qRQowT8D/U4LoSvVwOhSQ==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-gnu": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.54.0.tgz",
+ "integrity": "sha512-WGt5J8Ij/rvyqpFexxk3ffKqqbLf9AqrTBbWDk7ApGUzaIs6V+s2s84kAxklFwmMF/vBNGrVdYgbblCOFFezMQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-musl": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.54.0.tgz",
+ "integrity": "sha512-JzQmb38ATzHjxlPHuTH6tE7ojnMKM2kYNzt44LO/jJi8BpceEC8QuXYA908n8r3CNuG/B3BV8VR3Hi1rYtmPiw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-openharmony-arm64": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.54.0.tgz",
+ "integrity": "sha512-huT3fd0iC7jigGh7n3q/+lfPcXxBi+om/Rs3yiFxjvSxbSB6aohDFXbWvlspaqjeOh+hx7DDHS+5Es5qRkWkZg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-arm64-msvc": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.54.0.tgz",
+ "integrity": "sha512-c2V0W1bsKIKfbLMBu/WGBz6Yci8nJ/ZJdheE0EwB73N3MvHYKiKGs3mVilX4Gs70eGeDaMqEob25Tw2Gb9Nqyw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-ia32-msvc": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.54.0.tgz",
+ "integrity": "sha512-woEHgqQqDCkAzrDhvDipnSirm5vxUXtSKDYTVpZG3nUdW/VVB5VdCYA2iReSj/u3yCZzXID4kuKG7OynPnB3WQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-gnu": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.54.0.tgz",
+ "integrity": "sha512-dzAc53LOuFvHwbCEOS0rPbXp6SIhAf2txMP5p6mGyOXXw5mWY8NGGbPMPrs4P1WItkfApDathBj/NzMLUZ9rtQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-msvc": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.54.0.tgz",
+ "integrity": "sha512-hYT5d3YNdSh3mbCU1gwQyPgQd3T2ne0A3KG8KSBdav5TiBg6eInVmV+TeR5uHufiIgSFg0XsOWGW5/RhNcSvPg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@types/babel__core": {
+ "version": "7.20.5",
+ "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
+ "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.20.7",
+ "@babel/types": "^7.20.7",
+ "@types/babel__generator": "*",
+ "@types/babel__template": "*",
+ "@types/babel__traverse": "*"
+ }
+ },
+ "node_modules/@types/babel__generator": {
+ "version": "7.27.0",
+ "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz",
+ "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "node_modules/@types/babel__template": {
+ "version": "7.4.4",
+ "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz",
+ "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.1.0",
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "node_modules/@types/babel__traverse": {
+ "version": "7.28.0",
+ "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz",
+ "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.28.2"
+ }
+ },
+ "node_modules/@types/estree": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
+ "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/history": {
+ "version": "4.7.11",
+ "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz",
+ "integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==",
+ "dev": true
+ },
+ "node_modules/@types/lodash": {
+ "version": "4.17.16",
+ "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.16.tgz",
+ "integrity": "sha512-HX7Em5NYQAXKW+1T+FiuG27NGwzJfCX3s1GjOa7ujxZa52kjJLOr4FUxT+giF6Tgxv1e+/czV/iTtBw27WTU9g=="
+ },
+ "node_modules/@types/lodash.mergewith": {
+ "version": "4.6.9",
+ "resolved": "https://registry.npmjs.org/@types/lodash.mergewith/-/lodash.mergewith-4.6.9.tgz",
+ "integrity": "sha512-fgkoCAOF47K7sxrQ7Mlud2TH023itugZs2bUg8h/KzT+BnZNrR2jAOmaokbLunHNnobXVWOezAeNn/lZqwxkcw==",
+ "dependencies": {
+ "@types/lodash": "*"
+ }
+ },
+ "node_modules/@types/parse-json": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
+ "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA=="
+ },
+ "node_modules/@types/prop-types": {
+ "version": "15.7.15",
+ "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz",
+ "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==",
+ "devOptional": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/react": {
+ "version": "18.3.27",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.27.tgz",
+ "integrity": "sha512-cisd7gxkzjBKU2GgdYrTdtQx1SORymWyaAFhaxQPK9bYO9ot3Y5OikQRvY0VYQtvwjeQnizCINJAenh/V7MK2w==",
+ "devOptional": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@types/prop-types": "*",
+ "csstype": "^3.2.2"
+ }
+ },
+ "node_modules/@types/react-dom": {
+ "version": "18.3.7",
+ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz",
+ "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "^18.0.0"
+ }
+ },
+ "node_modules/@types/react-email-editor": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/@types/react-email-editor/-/react-email-editor-1.7.0.tgz",
+ "integrity": "sha512-27b9gZr9h5yYWISkQVqKV8LQoW4njDjGceIYfYlUHkd7IeAG9bmdusRE4MN0IqlRQR6kyq5qIksEAXtPl1gMEw==",
+ "deprecated": "This is a stub types definition. react-email-editor provides its own type definitions, so you do not need this installed.",
+ "dev": true,
+ "dependencies": {
+ "react-email-editor": "*"
+ }
+ },
+ "node_modules/@types/react-router": {
+ "version": "5.1.17",
+ "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.17.tgz",
+ "integrity": "sha512-RNSXOyb3VyRs/EOGmjBhhGKTbnN6fHWvy5FNLzWfOWOGjgVUKqJZXfpKzLmgoU8h6Hj8mpALj/mbXQASOb92wQ==",
+ "dev": true,
+ "dependencies": {
+ "@types/history": "*",
+ "@types/react": "*"
+ }
+ },
+ "node_modules/@types/react-router-dom": {
+ "version": "5.3.3",
+ "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.3.3.tgz",
+ "integrity": "sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==",
+ "dev": true,
+ "dependencies": {
+ "@types/history": "^4.7.11",
+ "@types/react": "*",
+ "@types/react-router": "*"
+ }
+ },
+ "node_modules/@urql/core": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/@urql/core/-/core-4.3.0.tgz",
+ "integrity": "sha512-wT+FeL8DG4x5o6RfHEnONNFVDM3616ouzATMYUClB6CB+iIu2mwfBKd7xSUxYOZmwtxna5/hDRQdMl3nbQZlnw==",
+ "license": "MIT",
+ "dependencies": {
+ "@0no-co/graphql.web": "^1.0.1",
+ "wonka": "^6.3.2"
+ }
+ },
+ "node_modules/@vitejs/plugin-react": {
+ "version": "4.7.0",
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.7.0.tgz",
+ "integrity": "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/core": "^7.28.0",
+ "@babel/plugin-transform-react-jsx-self": "^7.27.1",
+ "@babel/plugin-transform-react-jsx-source": "^7.27.1",
+ "@rolldown/pluginutils": "1.0.0-beta.27",
+ "@types/babel__core": "^7.20.5",
+ "react-refresh": "^0.17.0"
+ },
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "peerDependencies": {
+ "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0"
+ }
+ },
+ "node_modules/@zag-js/dom-query": {
+ "version": "0.31.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/dom-query/-/dom-query-0.31.1.tgz",
+ "integrity": "sha512-oiuohEXAXhBxpzzNm9k2VHGEOLC1SXlXSbRPcfBZ9so5NRQUA++zCE7cyQJqGLTZR0t3itFLlZqDbYEXRrefwg=="
+ },
+ "node_modules/@zag-js/element-size": {
+ "version": "0.31.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/element-size/-/element-size-0.31.1.tgz",
+ "integrity": "sha512-4T3yvn5NqqAjhlP326Fv+w9RqMIBbNN9H72g5q2ohwzhSgSfZzrKtjL4rs9axY/cw9UfMfXjRjEE98e5CMq7WQ=="
+ },
+ "node_modules/@zag-js/focus-visible": {
+ "version": "0.31.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/focus-visible/-/focus-visible-0.31.1.tgz",
+ "integrity": "sha512-dbLksz7FEwyFoANbpIlNnd3bVm0clQSUsnP8yUVQucStZPsuWjCrhL2jlAbGNrTrahX96ntUMXHb/sM68TibFg==",
+ "dependencies": {
+ "@zag-js/dom-query": "0.31.1"
+ }
+ },
+ "node_modules/aria-hidden": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.4.tgz",
+ "integrity": "sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==",
+ "dependencies": {
+ "tslib": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/asap": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
+ "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA=="
+ },
+ "node_modules/attr-accept": {
+ "version": "2.2.5",
+ "resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-2.2.5.tgz",
+ "integrity": "sha512-0bDNnY/u6pPwHDMoF0FieU354oBi0a8rD9FcsLwzcGWbc8KS8KPIi7y+s13OlVY+gMWc/9xEMUgNE6Qm8ZllYQ==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/babel-plugin-macros": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz",
+ "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==",
+ "dependencies": {
+ "@babel/runtime": "^7.12.5",
+ "cosmiconfig": "^7.0.0",
+ "resolve": "^1.19.0"
+ },
+ "engines": {
+ "node": ">=10",
+ "npm": ">=6"
+ }
+ },
+ "node_modules/baseline-browser-mapping": {
+ "version": "2.9.11",
+ "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.11.tgz",
+ "integrity": "sha512-Sg0xJUNDU1sJNGdfGWhVHX0kkZ+HWcvmVymJbj6NSgZZmW/8S9Y2HQ5euytnIgakgxN6papOAWiwDo1ctFDcoQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "baseline-browser-mapping": "dist/cli.js"
+ }
+ },
+ "node_modules/browserslist": {
+ "version": "4.28.1",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz",
+ "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "baseline-browser-mapping": "^2.9.0",
+ "caniuse-lite": "^1.0.30001759",
+ "electron-to-chromium": "^1.5.263",
+ "node-releases": "^2.0.27",
+ "update-browserslist-db": "^1.2.0"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ }
+ },
+ "node_modules/callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/caniuse-lite": {
+ "version": "1.0.30001762",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001762.tgz",
+ "integrity": "sha512-PxZwGNvH7Ak8WX5iXzoK1KPZttBXNPuaOvI2ZYU7NrlM+d9Ov+TUvlLOBNGzVXAntMSMMlJPd+jY6ovrVjSmUw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "CC-BY-4.0"
+ },
+ "node_modules/classnames": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz",
+ "integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA=="
+ },
+ "node_modules/color2k": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/color2k/-/color2k-2.0.3.tgz",
+ "integrity": "sha512-zW190nQTIoXcGCaU08DvVNFTmQhUpnJfVuAKfWqUQkflXKpaDdpaYoM0iluLS9lgJNHyBF58KKA2FBEwkD7wog=="
+ },
+ "node_modules/convert-source-map": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz",
+ "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==",
+ "dependencies": {
+ "safe-buffer": "~5.1.1"
+ }
+ },
+ "node_modules/cookie": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz",
+ "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/copy-to-clipboard": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz",
+ "integrity": "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==",
+ "dependencies": {
+ "toggle-selection": "^1.0.6"
+ }
+ },
+ "node_modules/core-js": {
+ "version": "3.33.2",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.33.2.tgz",
+ "integrity": "sha512-XeBzWI6QL3nJQiHmdzbAOiMYqjrb7hwU7A39Qhvd/POSa/t9E1AeZyEZx3fNvp/vtM8zXwhoL0FsiS0hD0pruQ==",
+ "hasInstallScript": true,
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/core-js"
+ }
+ },
+ "node_modules/cosmiconfig": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz",
+ "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==",
+ "dependencies": {
+ "@types/parse-json": "^4.0.0",
+ "import-fresh": "^3.2.1",
+ "parse-json": "^5.0.0",
+ "path-type": "^4.0.0",
+ "yaml": "^1.10.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/cosmiconfig/node_modules/yaml": {
+ "version": "1.10.2",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
+ "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
+ "license": "ISC",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/cross-fetch": {
+ "version": "3.1.8",
+ "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz",
+ "integrity": "sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==",
+ "dependencies": {
+ "node-fetch": "^2.6.12"
+ }
+ },
+ "node_modules/csstype": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
+ "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
+ "license": "MIT"
+ },
+ "node_modules/dayjs": {
+ "version": "1.11.13",
+ "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz",
+ "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg=="
+ },
+ "node_modules/debug": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
+ "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/detect-node-es": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz",
+ "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ=="
+ },
+ "node_modules/draft-js": {
+ "version": "0.11.7",
+ "resolved": "https://registry.npmjs.org/draft-js/-/draft-js-0.11.7.tgz",
+ "integrity": "sha512-ne7yFfN4sEL82QPQEn80xnADR8/Q6ALVworbC5UOSzOvjffmYfFsr3xSZtxbIirti14R7Y33EZC5rivpLgIbsg==",
+ "peer": true,
+ "dependencies": {
+ "fbjs": "^2.0.0",
+ "immutable": "~3.7.4",
+ "object-assign": "^4.1.1"
+ },
+ "peerDependencies": {
+ "react": ">=0.14.0",
+ "react-dom": ">=0.14.0"
+ }
+ },
+ "node_modules/draft-js/node_modules/immutable": {
+ "version": "3.7.6",
+ "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.7.6.tgz",
+ "integrity": "sha512-AizQPcaofEtO11RZhPPHBOJRdo/20MKQF9mBLnVkBoyHi1/zXK8fzVdnEpSV9gxqtnh6Qomfp3F0xT5qP/vThw==",
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/draftjs-utils": {
+ "version": "0.10.2",
+ "resolved": "https://registry.npmjs.org/draftjs-utils/-/draftjs-utils-0.10.2.tgz",
+ "integrity": "sha512-EstHqr3R3JVcilJrBaO/A+01GvwwKmC7e4TCjC7S94ZeMh4IVmf60OuQXtHHpwItK8C2JCi3iljgN5KHkJboUg==",
+ "peerDependencies": {
+ "draft-js": "^0.11.x",
+ "immutable": "3.x.x || 4.x.x"
+ }
+ },
+ "node_modules/electron-to-chromium": {
+ "version": "1.5.267",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz",
+ "integrity": "sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/error-ex": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
+ "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+ "dependencies": {
+ "is-arrayish": "^0.2.1"
+ }
+ },
+ "node_modules/esbuild": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.2.tgz",
+ "integrity": "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "optionalDependencies": {
+ "@esbuild/aix-ppc64": "0.27.2",
+ "@esbuild/android-arm": "0.27.2",
+ "@esbuild/android-arm64": "0.27.2",
+ "@esbuild/android-x64": "0.27.2",
+ "@esbuild/darwin-arm64": "0.27.2",
+ "@esbuild/darwin-x64": "0.27.2",
+ "@esbuild/freebsd-arm64": "0.27.2",
+ "@esbuild/freebsd-x64": "0.27.2",
+ "@esbuild/linux-arm": "0.27.2",
+ "@esbuild/linux-arm64": "0.27.2",
+ "@esbuild/linux-ia32": "0.27.2",
+ "@esbuild/linux-loong64": "0.27.2",
+ "@esbuild/linux-mips64el": "0.27.2",
+ "@esbuild/linux-ppc64": "0.27.2",
+ "@esbuild/linux-riscv64": "0.27.2",
+ "@esbuild/linux-s390x": "0.27.2",
+ "@esbuild/linux-x64": "0.27.2",
+ "@esbuild/netbsd-arm64": "0.27.2",
+ "@esbuild/netbsd-x64": "0.27.2",
+ "@esbuild/openbsd-arm64": "0.27.2",
+ "@esbuild/openbsd-x64": "0.27.2",
+ "@esbuild/openharmony-arm64": "0.27.2",
+ "@esbuild/sunos-x64": "0.27.2",
+ "@esbuild/win32-arm64": "0.27.2",
+ "@esbuild/win32-ia32": "0.27.2",
+ "@esbuild/win32-x64": "0.27.2"
+ }
+ },
+ "node_modules/escalade": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
+ "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/fbjs": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-2.0.0.tgz",
+ "integrity": "sha512-8XA8ny9ifxrAWlyhAbexXcs3rRMtxWcs3M0lctLfB49jRDHiaxj+Mo0XxbwE7nKZYzgCFoq64FS+WFd4IycPPQ==",
+ "dependencies": {
+ "core-js": "^3.6.4",
+ "cross-fetch": "^3.0.4",
+ "fbjs-css-vars": "^1.0.0",
+ "loose-envify": "^1.0.0",
+ "object-assign": "^4.1.0",
+ "promise": "^7.1.1",
+ "setimmediate": "^1.0.5",
+ "ua-parser-js": "^0.7.18"
+ }
+ },
+ "node_modules/fbjs-css-vars": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz",
+ "integrity": "sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ=="
+ },
+ "node_modules/fdir": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
+ "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "peerDependencies": {
+ "picomatch": "^3 || ^4"
+ },
+ "peerDependenciesMeta": {
+ "picomatch": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/file-selector": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/file-selector/-/file-selector-2.1.2.tgz",
+ "integrity": "sha512-QgXo+mXTe8ljeqUFaX3QVHc5osSItJ/Km+xpocx0aSqWGMSCf6qYs/VnzZgS864Pjn5iceMRFigeAV7AfTlaig==",
+ "dependencies": {
+ "tslib": "^2.7.0"
+ },
+ "engines": {
+ "node": ">= 12"
+ }
+ },
+ "node_modules/find-root": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz",
+ "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng=="
+ },
+ "node_modules/focus-lock": {
+ "version": "1.3.6",
+ "resolved": "https://registry.npmjs.org/focus-lock/-/focus-lock-1.3.6.tgz",
+ "integrity": "sha512-Ik/6OCk9RQQ0T5Xw+hKNLWrjSMtv51dD4GRmJjbD5a58TIEpI5a5iXagKVl3Z5UuyslMCA8Xwnu76jQob62Yhg==",
+ "dependencies": {
+ "tslib": "^2.0.3"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/focus-visible": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/focus-visible/-/focus-visible-5.2.1.tgz",
+ "integrity": "sha512-8Bx950VD1bWTQJEH/AM6SpEk+SU55aVnp4Ujhuuxy3eMEBCRwBnTBnVXr9YAPvZL3/CNjCa8u4IWfNmEO53whA=="
+ },
+ "node_modules/framer-motion": {
+ "version": "11.18.2",
+ "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.18.2.tgz",
+ "integrity": "sha512-5F5Och7wrvtLVElIpclDT0CBzMVg3dL22B64aZwHtsIY8RB4mXICLrkajK4G9R+ieSAGcgrLeae2SeUTg2pr6w==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "motion-dom": "^11.18.1",
+ "motion-utils": "^11.18.1",
+ "tslib": "^2.4.0"
+ },
+ "peerDependencies": {
+ "@emotion/is-prop-valid": "*",
+ "react": "^18.0.0 || ^19.0.0",
+ "react-dom": "^18.0.0 || ^19.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@emotion/is-prop-valid": {
+ "optional": true
+ },
+ "react": {
+ "optional": true
+ },
+ "react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/framesync": {
+ "version": "6.1.2",
+ "resolved": "https://registry.npmjs.org/framesync/-/framesync-6.1.2.tgz",
+ "integrity": "sha512-jBTqhX6KaQVDyus8muwZbBeGGP0XgujBRbQ7gM7BRdS3CadCZIHiawyzYLnafYcvZIh5j8WE7cxZKFn7dXhu9g==",
+ "dependencies": {
+ "tslib": "2.4.0"
+ }
+ },
+ "node_modules/framesync/node_modules/tslib": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
+ "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/gensync": {
+ "version": "1.0.0-beta.2",
+ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
+ "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/get-nonce": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz",
+ "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/graphql": {
+ "version": "16.11.0",
+ "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.11.0.tgz",
+ "integrity": "sha512-mS1lbMsxgQj6hge1XZ6p7GPhbrtFwUFYi3wRzXAC/FmYnyXMTvvI3td3rjmQ2u8ewXueaSvRPWaEcgVVOT9Jnw==",
+ "peer": true,
+ "engines": {
+ "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0"
+ }
+ },
+ "node_modules/hasown": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/hoist-non-react-statics": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
+ "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
+ "dependencies": {
+ "react-is": "^16.7.0"
+ }
+ },
+ "node_modules/html-to-draftjs": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/html-to-draftjs/-/html-to-draftjs-1.5.0.tgz",
+ "integrity": "sha512-kggLXBNciKDwKf+KYsuE+V5gw4dZ7nHyGMX9m0wy7urzWjKGWyNFetmArRLvRV0VrxKN70WylFsJvMTJx02OBQ==",
+ "peerDependencies": {
+ "draft-js": "^0.10.x || ^0.11.x",
+ "immutable": "3.x.x || 4.x.x"
+ }
+ },
+ "node_modules/immutable": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.4.tgz",
+ "integrity": "sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==",
+ "peer": true
+ },
+ "node_modules/import-fresh": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
+ "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
+ "dependencies": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-arrayish": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg=="
+ },
+ "node_modules/is-core-module": {
+ "version": "2.16.1",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
+ "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
+ "dependencies": {
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
+ },
+ "node_modules/jsesc": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
+ "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
+ "bin": {
+ "jsesc": "bin/jsesc"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/json-parse-even-better-errors": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
+ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w=="
+ },
+ "node_modules/json5": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "json5": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/lines-and-columns": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
+ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="
+ },
+ "node_modules/linkify-it": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz",
+ "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==",
+ "dependencies": {
+ "uc.micro": "^1.0.1"
+ }
+ },
+ "node_modules/lodash": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
+ },
+ "node_modules/lodash.mergewith": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz",
+ "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ=="
+ },
+ "node_modules/loose-envify": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
+ "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
+ "dependencies": {
+ "js-tokens": "^3.0.0 || ^4.0.0"
+ },
+ "bin": {
+ "loose-envify": "cli.js"
+ }
+ },
+ "node_modules/lru-cache": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+ "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^3.0.2"
+ }
+ },
+ "node_modules/motion-dom": {
+ "version": "11.18.1",
+ "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-11.18.1.tgz",
+ "integrity": "sha512-g76KvA001z+atjfxczdRtw/RXOM3OMSdd1f4DL77qCTF/+avrRJiawSG4yDibEQ215sr9kpinSlX2pCTJ9zbhw==",
+ "license": "MIT",
+ "dependencies": {
+ "motion-utils": "^11.18.1"
+ }
+ },
+ "node_modules/motion-utils": {
+ "version": "11.18.1",
+ "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-11.18.1.tgz",
+ "integrity": "sha512-49Kt+HKjtbJKLtgO/LKj9Ld+6vw9BjH5d9sc40R/kVyH8GLAXgT42M2NnuPcJNuA3s9ZfZBUcwIgpmZWGEE+hA==",
+ "license": "MIT"
+ },
+ "node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
+ },
+ "node_modules/nanoid": {
+ "version": "3.3.11",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
+ "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/node-fetch": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
+ "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
+ "dependencies": {
+ "whatwg-url": "^5.0.0"
+ },
+ "engines": {
+ "node": "4.x || >=6.0.0"
+ },
+ "peerDependencies": {
+ "encoding": "^0.1.0"
+ },
+ "peerDependenciesMeta": {
+ "encoding": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/node-releases": {
+ "version": "2.0.27",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz",
+ "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/parent-module": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+ "dependencies": {
+ "callsites": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/parse-json": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
+ "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
+ "dependencies": {
+ "@babel/code-frame": "^7.0.0",
+ "error-ex": "^1.3.1",
+ "json-parse-even-better-errors": "^2.3.0",
+ "lines-and-columns": "^1.1.6"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
+ },
+ "node_modules/path-type": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/picocolors": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="
+ },
+ "node_modules/picomatch": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
+ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/postcss": {
+ "version": "8.5.6",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
+ "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "nanoid": "^3.3.11",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.1"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/prettier": {
+ "version": "3.5.3",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.3.tgz",
+ "integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==",
+ "dev": true,
+ "bin": {
+ "prettier": "bin/prettier.cjs"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/prettier/prettier?sponsor=1"
+ }
+ },
+ "node_modules/promise": {
+ "version": "7.3.1",
+ "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
+ "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
+ "dependencies": {
+ "asap": "~2.0.3"
+ }
+ },
+ "node_modules/prop-types": {
+ "version": "15.8.1",
+ "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
+ "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
+ "dependencies": {
+ "loose-envify": "^1.4.0",
+ "object-assign": "^4.1.1",
+ "react-is": "^16.13.1"
+ }
+ },
+ "node_modules/react": {
+ "version": "18.3.1",
+ "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
+ "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
+ "peer": true,
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/react-clientside-effect": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/react-clientside-effect/-/react-clientside-effect-1.2.7.tgz",
+ "integrity": "sha512-gce9m0Pk/xYYMEojRI9bgvqQAkl6hm7ozQvqWPyQx+kULiatdHgkNM1QG4DQRx5N9BAzWSCJmt9mMV8/KsdgVg==",
+ "dependencies": {
+ "@babel/runtime": "^7.12.13"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
+ }
+ },
+ "node_modules/react-dom": {
+ "version": "18.3.1",
+ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
+ "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
+ "peer": true,
+ "dependencies": {
+ "loose-envify": "^1.1.0",
+ "scheduler": "^0.23.2"
+ },
+ "peerDependencies": {
+ "react": "^18.3.1"
+ }
+ },
+ "node_modules/react-draft-wysiwyg": {
+ "version": "1.15.0",
+ "resolved": "https://registry.npmjs.org/react-draft-wysiwyg/-/react-draft-wysiwyg-1.15.0.tgz",
+ "integrity": "sha512-p1cYZcWc6/ALFBVksbFoCM3b29fGQDlZLIMrXng0TU/UElxIOF2/AWWo4L5auIYVhmqKTZ0NkNjnXOzGGuxyeA==",
+ "dependencies": {
+ "classnames": "^2.2.6",
+ "draftjs-utils": "^0.10.2",
+ "html-to-draftjs": "^1.5.0",
+ "linkify-it": "^2.2.0",
+ "prop-types": "^15.7.2"
+ },
+ "peerDependencies": {
+ "draft-js": "^0.10.x || ^0.11.x",
+ "immutable": "3.x.x || 4.x.x",
+ "react": "0.13.x || 0.14.x || ^15.0.0-0 || 15.x.x || ^16.0.0-0 || ^16.x.x || ^17.x.x || ^18.x.x",
+ "react-dom": "0.13.x || 0.14.x || ^15.0.0-0 || 15.x.x || ^16.0.0-0 || ^16.x.x || ^17.x.x || ^18.x.x"
+ }
+ },
+ "node_modules/react-dropzone": {
+ "version": "14.3.8",
+ "resolved": "https://registry.npmjs.org/react-dropzone/-/react-dropzone-14.3.8.tgz",
+ "integrity": "sha512-sBgODnq+lcA4P296DY4wacOZz3JFpD99fp+hb//iBO2HHnyeZU3FwWyXJ6salNpqQdsZrgMrotuko/BdJMV8Ug==",
+ "dependencies": {
+ "attr-accept": "^2.2.4",
+ "file-selector": "^2.1.0",
+ "prop-types": "^15.8.1"
+ },
+ "engines": {
+ "node": ">= 10.13"
+ },
+ "peerDependencies": {
+ "react": ">= 16.8 || 18.0.0"
+ }
+ },
+ "node_modules/react-email-editor": {
+ "version": "1.7.11",
+ "resolved": "https://registry.npmjs.org/react-email-editor/-/react-email-editor-1.7.11.tgz",
+ "integrity": "sha512-AyoKKtMEPhKdqUxFX1hyJMvEO+E5fzk88uNVGHhK1ymhLpcghYLkz1+pXKLcByjR6LHkfEbrCmoYFG8zyripug==",
+ "dependencies": {
+ "unlayer-types": "latest"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "react": ">=15"
+ }
+ },
+ "node_modules/react-fast-compare": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz",
+ "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ=="
+ },
+ "node_modules/react-focus-lock": {
+ "version": "2.13.6",
+ "resolved": "https://registry.npmjs.org/react-focus-lock/-/react-focus-lock-2.13.6.tgz",
+ "integrity": "sha512-ehylFFWyYtBKXjAO9+3v8d0i+cnc1trGS0vlTGhzFW1vbFXVUTmR8s2tt/ZQG8x5hElg6rhENlLG1H3EZK0Llg==",
+ "dependencies": {
+ "@babel/runtime": "^7.0.0",
+ "focus-lock": "^1.3.6",
+ "prop-types": "^15.6.2",
+ "react-clientside-effect": "^1.2.7",
+ "use-callback-ref": "^1.3.3",
+ "use-sidecar": "^1.1.3"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/react-icons": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.5.0.tgz",
+ "integrity": "sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==",
+ "peerDependencies": {
+ "react": "*"
+ }
+ },
+ "node_modules/react-is": {
+ "version": "16.13.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
+ },
+ "node_modules/react-refresh": {
+ "version": "0.17.0",
+ "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz",
+ "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/react-remove-scroll": {
+ "version": "2.6.3",
+ "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.6.3.tgz",
+ "integrity": "sha512-pnAi91oOk8g8ABQKGF5/M9qxmmOPxaAnopyTHYfqYEwJhyFrbbBtHuSgtKEoH0jpcxx5o3hXqH1mNd9/Oi+8iQ==",
+ "dependencies": {
+ "react-remove-scroll-bar": "^2.3.7",
+ "react-style-singleton": "^2.2.3",
+ "tslib": "^2.1.0",
+ "use-callback-ref": "^1.3.3",
+ "use-sidecar": "^1.1.3"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/react-remove-scroll-bar": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz",
+ "integrity": "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==",
+ "dependencies": {
+ "react-style-singleton": "^2.2.2",
+ "tslib": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/react-router": {
+ "version": "7.6.0",
+ "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.6.0.tgz",
+ "integrity": "sha512-GGufuHIVCJDbnIAXP3P9Sxzq3UUsddG3rrI3ut1q6m0FI6vxVBF3JoPQ38+W/blslLH4a5Yutp8drkEpXoddGQ==",
+ "dependencies": {
+ "cookie": "^1.0.1",
+ "set-cookie-parser": "^2.6.0"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=18",
+ "react-dom": ">=18"
+ },
+ "peerDependenciesMeta": {
+ "react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/react-router-dom": {
+ "version": "7.6.0",
+ "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.6.0.tgz",
+ "integrity": "sha512-DYgm6RDEuKdopSyGOWZGtDfSm7Aofb8CCzgkliTjtu/eDuB0gcsv6qdFhhi8HdtmA+KHkt5MfZ5K2PdzjugYsA==",
+ "dependencies": {
+ "react-router": "7.6.0"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=18",
+ "react-dom": ">=18"
+ }
+ },
+ "node_modules/react-style-singleton": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz",
+ "integrity": "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==",
+ "dependencies": {
+ "get-nonce": "^1.0.0",
+ "tslib": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/resolve": {
+ "version": "1.22.10",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
+ "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==",
+ "dependencies": {
+ "is-core-module": "^2.16.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/resolve-from": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/rollup": {
+ "version": "4.54.0",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.54.0.tgz",
+ "integrity": "sha512-3nk8Y3a9Ea8szgKhinMlGMhGMw89mqule3KWczxhIzqudyHdCIOHw8WJlj/r329fACjKLEh13ZSk7oE22kyeIw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "1.0.8"
+ },
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=18.0.0",
+ "npm": ">=8.0.0"
+ },
+ "optionalDependencies": {
+ "@rollup/rollup-android-arm-eabi": "4.54.0",
+ "@rollup/rollup-android-arm64": "4.54.0",
+ "@rollup/rollup-darwin-arm64": "4.54.0",
+ "@rollup/rollup-darwin-x64": "4.54.0",
+ "@rollup/rollup-freebsd-arm64": "4.54.0",
+ "@rollup/rollup-freebsd-x64": "4.54.0",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.54.0",
+ "@rollup/rollup-linux-arm-musleabihf": "4.54.0",
+ "@rollup/rollup-linux-arm64-gnu": "4.54.0",
+ "@rollup/rollup-linux-arm64-musl": "4.54.0",
+ "@rollup/rollup-linux-loong64-gnu": "4.54.0",
+ "@rollup/rollup-linux-ppc64-gnu": "4.54.0",
+ "@rollup/rollup-linux-riscv64-gnu": "4.54.0",
+ "@rollup/rollup-linux-riscv64-musl": "4.54.0",
+ "@rollup/rollup-linux-s390x-gnu": "4.54.0",
+ "@rollup/rollup-linux-x64-gnu": "4.54.0",
+ "@rollup/rollup-linux-x64-musl": "4.54.0",
+ "@rollup/rollup-openharmony-arm64": "4.54.0",
+ "@rollup/rollup-win32-arm64-msvc": "4.54.0",
+ "@rollup/rollup-win32-ia32-msvc": "4.54.0",
+ "@rollup/rollup-win32-x64-gnu": "4.54.0",
+ "@rollup/rollup-win32-x64-msvc": "4.54.0",
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+ },
+ "node_modules/scheduler": {
+ "version": "0.23.2",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
+ "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ }
+ },
+ "node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/set-cookie-parser": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz",
+ "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ=="
+ },
+ "node_modules/setimmediate": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
+ "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA=="
+ },
+ "node_modules/source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/source-map-js": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/stylis": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz",
+ "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw=="
+ },
+ "node_modules/supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/tinyglobby": {
+ "version": "0.2.15",
+ "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
+ "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fdir": "^6.5.0",
+ "picomatch": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/SuperchupuDev"
+ }
+ },
+ "node_modules/toggle-selection": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz",
+ "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ=="
+ },
+ "node_modules/tr46": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
+ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
+ },
+ "node_modules/tslib": {
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
+ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="
+ },
+ "node_modules/typescript": {
+ "version": "5.8.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
+ "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
+ "dev": true,
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
+ },
+ "node_modules/ua-parser-js": {
+ "version": "0.7.40",
+ "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.40.tgz",
+ "integrity": "sha512-us1E3K+3jJppDBa3Tl0L3MOJiGhe1C6P0+nIvQAFYbxlMAx0h81eOwLmU57xgqToduDDPx3y5QsdjPfDu+FgOQ==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/ua-parser-js"
+ },
+ {
+ "type": "paypal",
+ "url": "https://paypal.me/faisalman"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/faisalman"
+ }
+ ],
+ "bin": {
+ "ua-parser-js": "script/cli.js"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/uc.micro": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
+ "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA=="
+ },
+ "node_modules/unlayer-types": {
+ "version": "1.259.0",
+ "resolved": "https://registry.npmjs.org/unlayer-types/-/unlayer-types-1.259.0.tgz",
+ "integrity": "sha512-u5XYqhyOXESMQcgaS3SgzQgpoJOGIHU8wu0KPkMtVRfeuvcJOinomy6reqxN03tlsSt/u33OGY5z3ijFWVTlXA=="
+ },
+ "node_modules/update-browserslist-db": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz",
+ "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "escalade": "^3.2.0",
+ "picocolors": "^1.1.1"
+ },
+ "bin": {
+ "update-browserslist-db": "cli.js"
+ },
+ "peerDependencies": {
+ "browserslist": ">= 4.21.0"
+ }
+ },
+ "node_modules/urql": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/urql/-/urql-4.2.2.tgz",
+ "integrity": "sha512-3GgqNa6iF7bC4hY/ImJKN4REQILcSU9VKcKL8gfELZM8mM5BnLH1BsCc8kBdnVGD1LIFOs4W3O2idNHhON1r0w==",
+ "dependencies": {
+ "@urql/core": "^5.1.1",
+ "wonka": "^6.3.2"
+ },
+ "peerDependencies": {
+ "@urql/core": "^5.0.0",
+ "react": ">= 16.8.0"
+ }
+ },
+ "node_modules/urql/node_modules/@urql/core": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@urql/core/-/core-5.2.0.tgz",
+ "integrity": "sha512-/n0ieD0mvvDnVAXEQgX/7qJiVcvYvNkOHeBvkwtylfjydar123caCXcl58PXFY11oU1oquJocVXHxLAbtv4x1A==",
+ "license": "MIT",
+ "dependencies": {
+ "@0no-co/graphql.web": "^1.0.13",
+ "wonka": "^6.3.2"
+ }
+ },
+ "node_modules/use-callback-ref": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz",
+ "integrity": "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==",
+ "dependencies": {
+ "tslib": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/use-sidecar": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz",
+ "integrity": "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==",
+ "dependencies": {
+ "detect-node-es": "^1.1.0",
+ "tslib": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vite": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.0.tgz",
+ "integrity": "sha512-dZwN5L1VlUBewiP6H9s2+B3e3Jg96D0vzN+Ry73sOefebhYr9f94wwkMNN/9ouoU8pV1BqA1d1zGk8928cx0rg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "esbuild": "^0.27.0",
+ "fdir": "^6.5.0",
+ "picomatch": "^4.0.3",
+ "postcss": "^8.5.6",
+ "rollup": "^4.43.0",
+ "tinyglobby": "^0.2.15"
+ },
+ "bin": {
+ "vite": "bin/vite.js"
+ },
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ },
+ "funding": {
+ "url": "https://github.com/vitejs/vite?sponsor=1"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.3"
+ },
+ "peerDependencies": {
+ "@types/node": "^20.19.0 || >=22.12.0",
+ "jiti": ">=1.21.0",
+ "less": "^4.0.0",
+ "lightningcss": "^1.21.0",
+ "sass": "^1.70.0",
+ "sass-embedded": "^1.70.0",
+ "stylus": ">=0.54.8",
+ "sugarss": "^5.0.0",
+ "terser": "^5.16.0",
+ "tsx": "^4.8.1",
+ "yaml": "^2.4.2"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "jiti": {
+ "optional": true
+ },
+ "less": {
+ "optional": true
+ },
+ "lightningcss": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ },
+ "sass-embedded": {
+ "optional": true
+ },
+ "stylus": {
+ "optional": true
+ },
+ "sugarss": {
+ "optional": true
+ },
+ "terser": {
+ "optional": true
+ },
+ "tsx": {
+ "optional": true
+ },
+ "yaml": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/webidl-conversions": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
+ },
+ "node_modules/whatwg-url": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
+ "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
+ "dependencies": {
+ "tr46": "~0.0.3",
+ "webidl-conversions": "^3.0.0"
+ }
+ },
+ "node_modules/wonka": {
+ "version": "6.3.5",
+ "resolved": "https://registry.npmjs.org/wonka/-/wonka-6.3.5.tgz",
+ "integrity": "sha512-SSil+ecw6B4/Dm7Pf2sAshKQ5hWFvfyGlfPbEd6A14dOH6VDjrmbY86u6nZvy9omGwwIPFR8V41+of1EezgoUw=="
+ },
+ "node_modules/yallist": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+ "dev": true,
+ "license": "ISC"
+ }
+ }
+}
diff --git a/web/dashboard/package.json b/web/dashboard/package.json
new file mode 100644
index 000000000..3b6e7ca8c
--- /dev/null
+++ b/web/dashboard/package.json
@@ -0,0 +1,46 @@
+{
+ "name": "dashboard",
+ "version": "1.0.0",
+ "description": "",
+ "type": "module",
+ "scripts": {
+ "dev": "vite build --watch",
+ "build": "vite build",
+ "preview": "vite preview",
+ "format": "prettier --write --use-tabs 'src/**/*.(ts|tsx|js|jsx)'"
+ },
+ "keywords": [],
+ "author": "Lakhan Samani",
+ "license": "ISC",
+ "dependencies": {
+ "@chakra-ui/icons": "^2.1.2",
+ "@chakra-ui/react": "^2.9.2",
+ "@emotion/react": "^11.13.5",
+ "@emotion/styled": "^11.13.5",
+ "@urql/core": "^4.2.2",
+ "dayjs": "^1.11.13",
+ "focus-visible": "^5.2.1",
+ "framer-motion": "^11.11.17",
+ "graphql": "^16.9.0",
+ "lodash": "^4.17.21",
+ "react": "^18.3.1",
+ "react-dom": "^18.3.1",
+ "react-draft-wysiwyg": "^1.15.0",
+ "react-dropzone": "^14.3.8",
+ "react-email-editor": "^1.7.11",
+ "react-icons": "^5.5.0",
+ "react-router-dom": "^7.0.2",
+ "urql": "^4.2.2"
+ },
+ "devDependencies": {
+ "@types/lodash": "^4.17.7",
+ "@types/react": "^18.3.12",
+ "@types/react-dom": "^18.3.1",
+ "@types/react-email-editor": "^1.7.0",
+ "@types/react-router-dom": "^5.3.3",
+ "@vitejs/plugin-react": "^4.3.1",
+ "prettier": "^3.3.3",
+ "typescript": "^5.6.3",
+ "vite": "^7.3.0"
+ }
+}
diff --git a/dashboard/public/roblox.png b/web/dashboard/public/roblox.png
similarity index 100%
rename from dashboard/public/roblox.png
rename to web/dashboard/public/roblox.png
diff --git a/dashboard/public/sample.csv b/web/dashboard/public/sample.csv
similarity index 100%
rename from dashboard/public/sample.csv
rename to web/dashboard/public/sample.csv
diff --git a/dashboard/src/App.tsx b/web/dashboard/src/App.tsx
similarity index 91%
rename from dashboard/src/App.tsx
rename to web/dashboard/src/App.tsx
index f7a4afe99..ea1d0c85b 100644
--- a/dashboard/src/App.tsx
+++ b/web/dashboard/src/App.tsx
@@ -3,6 +3,7 @@ import { Fragment } from 'react';
import { ChakraProvider, extendTheme } from '@chakra-ui/react';
import { BrowserRouter } from 'react-router-dom';
import { createClient, Provider } from 'urql';
+import { cacheExchange, fetchExchange } from '@urql/core';
import { AppRoutes } from './routes';
import { AuthContextProvider } from './contexts/AuthContext';
@@ -17,6 +18,7 @@ const queryClient = createClient({
};
},
requestPolicy: 'network-only',
+ exchanges: [cacheExchange, fetchExchange],
});
const theme = extendTheme({
diff --git a/dashboard/src/components/DeleteEmailTemplateModal.tsx b/web/dashboard/src/components/DeleteEmailTemplateModal.tsx
similarity index 100%
rename from dashboard/src/components/DeleteEmailTemplateModal.tsx
rename to web/dashboard/src/components/DeleteEmailTemplateModal.tsx
diff --git a/dashboard/src/components/DeleteUserModal.tsx b/web/dashboard/src/components/DeleteUserModal.tsx
similarity index 100%
rename from dashboard/src/components/DeleteUserModal.tsx
rename to web/dashboard/src/components/DeleteUserModal.tsx
diff --git a/dashboard/src/components/DeleteWebhookModal.tsx b/web/dashboard/src/components/DeleteWebhookModal.tsx
similarity index 100%
rename from dashboard/src/components/DeleteWebhookModal.tsx
rename to web/dashboard/src/components/DeleteWebhookModal.tsx
diff --git a/dashboard/src/components/EditUserModal.tsx b/web/dashboard/src/components/EditUserModal.tsx
similarity index 100%
rename from dashboard/src/components/EditUserModal.tsx
rename to web/dashboard/src/components/EditUserModal.tsx
diff --git a/dashboard/src/components/EnvComponents/AccessToken.tsx b/web/dashboard/src/components/EnvComponents/AccessToken.tsx
similarity index 100%
rename from dashboard/src/components/EnvComponents/AccessToken.tsx
rename to web/dashboard/src/components/EnvComponents/AccessToken.tsx
diff --git a/dashboard/src/components/EnvComponents/DatabaseCredentials.tsx b/web/dashboard/src/components/EnvComponents/DatabaseCredentials.tsx
similarity index 100%
rename from dashboard/src/components/EnvComponents/DatabaseCredentials.tsx
rename to web/dashboard/src/components/EnvComponents/DatabaseCredentials.tsx
diff --git a/dashboard/src/components/EnvComponents/DomainWhitelisting.tsx b/web/dashboard/src/components/EnvComponents/DomainWhitelisting.tsx
similarity index 100%
rename from dashboard/src/components/EnvComponents/DomainWhitelisting.tsx
rename to web/dashboard/src/components/EnvComponents/DomainWhitelisting.tsx
diff --git a/dashboard/src/components/EnvComponents/EmailConfiguration.tsx b/web/dashboard/src/components/EnvComponents/EmailConfiguration.tsx
similarity index 100%
rename from dashboard/src/components/EnvComponents/EmailConfiguration.tsx
rename to web/dashboard/src/components/EnvComponents/EmailConfiguration.tsx
diff --git a/dashboard/src/components/EnvComponents/Features.tsx b/web/dashboard/src/components/EnvComponents/Features.tsx
similarity index 100%
rename from dashboard/src/components/EnvComponents/Features.tsx
rename to web/dashboard/src/components/EnvComponents/Features.tsx
diff --git a/dashboard/src/components/EnvComponents/JWTConfiguration.tsx b/web/dashboard/src/components/EnvComponents/JWTConfiguration.tsx
similarity index 100%
rename from dashboard/src/components/EnvComponents/JWTConfiguration.tsx
rename to web/dashboard/src/components/EnvComponents/JWTConfiguration.tsx
diff --git a/dashboard/src/components/EnvComponents/OAuthConfig.tsx b/web/dashboard/src/components/EnvComponents/OAuthConfig.tsx
similarity index 100%
rename from dashboard/src/components/EnvComponents/OAuthConfig.tsx
rename to web/dashboard/src/components/EnvComponents/OAuthConfig.tsx
diff --git a/dashboard/src/components/EnvComponents/OrganizationInfo.tsx b/web/dashboard/src/components/EnvComponents/OrganizationInfo.tsx
similarity index 100%
rename from dashboard/src/components/EnvComponents/OrganizationInfo.tsx
rename to web/dashboard/src/components/EnvComponents/OrganizationInfo.tsx
diff --git a/dashboard/src/components/EnvComponents/Roles.tsx b/web/dashboard/src/components/EnvComponents/Roles.tsx
similarity index 100%
rename from dashboard/src/components/EnvComponents/Roles.tsx
rename to web/dashboard/src/components/EnvComponents/Roles.tsx
diff --git a/dashboard/src/components/EnvComponents/SecurityAdminSecret.tsx b/web/dashboard/src/components/EnvComponents/SecurityAdminSecret.tsx
similarity index 100%
rename from dashboard/src/components/EnvComponents/SecurityAdminSecret.tsx
rename to web/dashboard/src/components/EnvComponents/SecurityAdminSecret.tsx
diff --git a/dashboard/src/components/EnvComponents/SessionStorage.tsx b/web/dashboard/src/components/EnvComponents/SessionStorage.tsx
similarity index 100%
rename from dashboard/src/components/EnvComponents/SessionStorage.tsx
rename to web/dashboard/src/components/EnvComponents/SessionStorage.tsx
diff --git a/dashboard/src/components/GenerateKeysModal.tsx b/web/dashboard/src/components/GenerateKeysModal.tsx
similarity index 100%
rename from dashboard/src/components/GenerateKeysModal.tsx
rename to web/dashboard/src/components/GenerateKeysModal.tsx
diff --git a/dashboard/src/components/InputField.tsx b/web/dashboard/src/components/InputField.tsx
similarity index 100%
rename from dashboard/src/components/InputField.tsx
rename to web/dashboard/src/components/InputField.tsx
diff --git a/dashboard/src/components/InviteMembersModal.tsx b/web/dashboard/src/components/InviteMembersModal.tsx
similarity index 100%
rename from dashboard/src/components/InviteMembersModal.tsx
rename to web/dashboard/src/components/InviteMembersModal.tsx
diff --git a/dashboard/src/components/Menu.tsx b/web/dashboard/src/components/Menu.tsx
similarity index 72%
rename from dashboard/src/components/Menu.tsx
rename to web/dashboard/src/components/Menu.tsx
index 09775c397..e860b5dab 100644
--- a/dashboard/src/components/Menu.tsx
+++ b/web/dashboard/src/components/Menu.tsx
@@ -6,7 +6,6 @@ import {
Flex,
Image,
HStack,
- VStack,
Icon,
useColorModeValue,
Link,
@@ -22,26 +21,18 @@ import {
AccordionPanel,
AccordionItem,
useMediaQuery,
+ Button,
} from '@chakra-ui/react';
import {
- FiUser,
FiCode,
- FiSettings,
FiMenu,
FiUsers,
FiChevronDown,
FiLink,
FiFileText,
+ FiPower,
} from 'react-icons/fi';
-import { BiCustomize } from 'react-icons/bi';
-import { AiOutlineKey } from 'react-icons/ai';
-import { SiOpenaccess, SiJsonwebtokens } from 'react-icons/si';
-import { MdSecurity } from 'react-icons/md';
-import { RiDatabase2Line } from 'react-icons/ri';
-import { BsCheck2Circle } from 'react-icons/bs';
-import { HiOutlineMail, HiOutlineOfficeBuilding } from 'react-icons/hi';
import { IconType } from 'react-icons';
-import { ReactText } from 'react';
import { useMutation, useQuery } from 'urql';
import { NavLink, useNavigate, useLocation } from 'react-router-dom';
import { useAuthContext } from '../contexts/AuthContext';
@@ -61,58 +52,7 @@ interface LinkItemProps {
subRoutes?: SubRoutes[];
}
const LinkItems: Array = [
- {
- name: 'Environment ',
- icon: FiSettings,
- route: '/',
- subRoutes: [
- {
- name: 'OAuth Config',
- icon: AiOutlineKey,
- route: '/oauth-setting',
- },
-
- { name: 'Roles', icon: FiUser, route: '/roles' },
- {
- name: 'JWT Secrets',
- icon: SiJsonwebtokens,
- route: '/jwt-config',
- },
- {
- name: 'Session Storage',
- icon: RiDatabase2Line,
- route: '/session-storage',
- },
- {
- name: 'Email Configurations',
- icon: HiOutlineMail,
- route: '/email-config',
- },
- {
- name: 'Domain White Listing',
- icon: BsCheck2Circle,
- route: '/whitelist-variables',
- },
- {
- name: 'Organization Info',
- icon: HiOutlineOfficeBuilding,
- route: '/organization-info',
- },
- { name: 'Access Token', icon: SiOpenaccess, route: '/access-token' },
- {
- name: 'Features',
- icon: BiCustomize,
- route: '/features',
- },
- { name: 'Database', icon: RiDatabase2Line, route: '/db-cred' },
- {
- name: ' Security',
- icon: MdSecurity,
- route: '/admin-secret',
- },
- ],
- },
- { name: 'Users', icon: FiUsers, route: '/users' },
+ { name: 'Users', icon: FiUsers, route: '/' },
{ name: 'Webhooks', icon: FiLink, route: '/webhooks' },
{ name: 'Email Templates', icon: FiFileText, route: '/email-templates' },
];
@@ -254,8 +194,9 @@ export const Sidebar = ({ onClose, ...rest }: SidebarProps) => {
interface NavItemProps extends FlexProps {
icon: IconType;
- children: ReactText | JSX.Element | JSX.Element[];
+ children: ReactNode;
}
+
export const NavItem = ({ icon, children, ...rest }: NavItemProps) => {
return (
{
-
+
diff --git a/dashboard/src/components/UpdateEmailTemplateModal.tsx b/web/dashboard/src/components/UpdateEmailTemplateModal.tsx
similarity index 100%
rename from dashboard/src/components/UpdateEmailTemplateModal.tsx
rename to web/dashboard/src/components/UpdateEmailTemplateModal.tsx
diff --git a/dashboard/src/components/UpdateWebhookModal.tsx b/web/dashboard/src/components/UpdateWebhookModal.tsx
similarity index 100%
rename from dashboard/src/components/UpdateWebhookModal.tsx
rename to web/dashboard/src/components/UpdateWebhookModal.tsx
diff --git a/dashboard/src/components/ViewWebhookLogsModal.tsx b/web/dashboard/src/components/ViewWebhookLogsModal.tsx
similarity index 100%
rename from dashboard/src/components/ViewWebhookLogsModal.tsx
rename to web/dashboard/src/components/ViewWebhookLogsModal.tsx
diff --git a/dashboard/src/constants.ts b/web/dashboard/src/constants.ts
similarity index 100%
rename from dashboard/src/constants.ts
rename to web/dashboard/src/constants.ts
diff --git a/dashboard/src/contexts/AuthContext.tsx b/web/dashboard/src/contexts/AuthContext.tsx
similarity index 100%
rename from dashboard/src/contexts/AuthContext.tsx
rename to web/dashboard/src/contexts/AuthContext.tsx
diff --git a/dashboard/src/graphql/mutation/index.ts b/web/dashboard/src/graphql/mutation/index.ts
similarity index 94%
rename from dashboard/src/graphql/mutation/index.ts
rename to web/dashboard/src/graphql/mutation/index.ts
index 47e9acf0f..22c95077d 100644
--- a/dashboard/src/graphql/mutation/index.ts
+++ b/web/dashboard/src/graphql/mutation/index.ts
@@ -22,14 +22,6 @@ export const AdminLogout = `
}
`;
-export const UpdateEnvVariables = `
- mutation updateEnvVariables($params: UpdateEnvInput!) {
- _update_env(params: $params) {
- message
- }
- }
-`;
-
export const UpdateUser = `
mutation updateUser($params: UpdateUserInput!) {
_update_user(params: $params) {
diff --git a/dashboard/src/graphql/queries/index.ts b/web/dashboard/src/graphql/queries/index.ts
similarity index 54%
rename from dashboard/src/graphql/queries/index.ts
rename to web/dashboard/src/graphql/queries/index.ts
index 4953fd1c0..3b1e70d4d 100644
--- a/dashboard/src/graphql/queries/index.ts
+++ b/web/dashboard/src/graphql/queries/index.ts
@@ -15,78 +15,6 @@ export const AdminSessionQuery = `
}
`;
-export const EnvVariablesQuery = `
- query {
- _env{
- CLIENT_ID
- CLIENT_SECRET
- GOOGLE_CLIENT_ID
- GOOGLE_CLIENT_SECRET
- GITHUB_CLIENT_ID
- GITHUB_CLIENT_SECRET
- FACEBOOK_CLIENT_ID
- FACEBOOK_CLIENT_SECRET
- LINKEDIN_CLIENT_ID
- LINKEDIN_CLIENT_SECRET
- APPLE_CLIENT_ID
- APPLE_CLIENT_SECRET
- DISCORD_CLIENT_ID
- DISCORD_CLIENT_SECRET
- TWITTER_CLIENT_ID
- TWITTER_CLIENT_SECRET
- MICROSOFT_CLIENT_ID
- MICROSOFT_CLIENT_SECRET
- MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID
- TWITCH_CLIENT_ID
- TWITCH_CLIENT_SECRET
- ROBLOX_CLIENT_ID
- ROBLOX_CLIENT_SECRET
- DEFAULT_ROLES
- PROTECTED_ROLES
- ROLES
- JWT_TYPE
- JWT_SECRET
- JWT_ROLE_CLAIM
- JWT_PRIVATE_KEY
- JWT_PUBLIC_KEY
- REDIS_URL
- SMTP_HOST
- SMTP_PORT
- SMTP_USERNAME
- SMTP_PASSWORD
- SMTP_LOCAL_NAME
- SENDER_EMAIL
- SENDER_NAME
- ALLOWED_ORIGINS
- ORGANIZATION_NAME
- ORGANIZATION_LOGO
- ADMIN_SECRET
- APP_COOKIE_SECURE
- ADMIN_COOKIE_SECURE
- DISABLE_LOGIN_PAGE
- DISABLE_MAGIC_LINK_LOGIN
- DISABLE_EMAIL_VERIFICATION
- DISABLE_BASIC_AUTHENTICATION
- DISABLE_MOBILE_BASIC_AUTHENTICATION
- DISABLE_SIGN_UP
- DISABLE_STRONG_PASSWORD
- DISABLE_REDIS_FOR_ENV
- CUSTOM_ACCESS_TOKEN_SCRIPT
- DATABASE_NAME
- DATABASE_TYPE
- DATABASE_URL
- ACCESS_TOKEN_EXPIRY_TIME
- DISABLE_MULTI_FACTOR_AUTHENTICATION
- ENFORCE_MULTI_FACTOR_AUTHENTICATION
- DEFAULT_AUTHORIZE_RESPONSE_TYPE
- DEFAULT_AUTHORIZE_RESPONSE_MODE
- DISABLE_PLAYGROUND
- DISABLE_TOTP_LOGIN
- DISABLE_MAIL_OTP_LOGIN
- }
- }
-`;
-
export const UserDetailsQuery = `
query($params: PaginatedInput) {
_users(params: $params) {
diff --git a/web/dashboard/src/index.tsx b/web/dashboard/src/index.tsx
new file mode 100644
index 000000000..5c1a28dc0
--- /dev/null
+++ b/web/dashboard/src/index.tsx
@@ -0,0 +1,8 @@
+import React from 'react';
+import ReactDOM from 'react-dom/client';
+import App from './App';
+
+const root = ReactDOM.createRoot(
+ document.getElementById('root') as HTMLElement,
+);
+root.render();
diff --git a/dashboard/src/layouts/AuthLayout.tsx b/web/dashboard/src/layouts/AuthLayout.tsx
similarity index 100%
rename from dashboard/src/layouts/AuthLayout.tsx
rename to web/dashboard/src/layouts/AuthLayout.tsx
diff --git a/dashboard/src/layouts/DashboardLayout.tsx b/web/dashboard/src/layouts/DashboardLayout.tsx
similarity index 100%
rename from dashboard/src/layouts/DashboardLayout.tsx
rename to web/dashboard/src/layouts/DashboardLayout.tsx
diff --git a/dashboard/src/pages/Auth.tsx b/web/dashboard/src/pages/Auth.tsx
similarity index 84%
rename from dashboard/src/pages/Auth.tsx
rename to web/dashboard/src/pages/Auth.tsx
index f8ace42c5..eae88646c 100644
--- a/dashboard/src/pages/Auth.tsx
+++ b/web/dashboard/src/pages/Auth.tsx
@@ -109,18 +109,6 @@ export default function Auth() {
>
{isLogin ? 'Login' : 'Sign up'}
- {isLogin ? (
-
- Note: In case if you have forgot your admin secret, you can
- reset it by updating ADMIN_SECRET environment
- variable. For more information, please refer to the{' '}
- documentation.
-
- ) : (
-
- Note: Configure the password to start using your dashboard.
-
- )}
diff --git a/dashboard/src/pages/EmailTemplates.tsx b/web/dashboard/src/pages/EmailTemplates.tsx
similarity index 100%
rename from dashboard/src/pages/EmailTemplates.tsx
rename to web/dashboard/src/pages/EmailTemplates.tsx
diff --git a/dashboard/src/pages/Home.tsx b/web/dashboard/src/pages/Home.tsx
similarity index 100%
rename from dashboard/src/pages/Home.tsx
rename to web/dashboard/src/pages/Home.tsx
diff --git a/dashboard/src/pages/Users.tsx b/web/dashboard/src/pages/Users.tsx
similarity index 99%
rename from dashboard/src/pages/Users.tsx
rename to web/dashboard/src/pages/Users.tsx
index 64002dec3..a33ad8412 100644
--- a/dashboard/src/pages/Users.tsx
+++ b/web/dashboard/src/pages/Users.tsx
@@ -64,6 +64,7 @@ interface userDataTypes {
gender: string;
birthdate: string;
phone_number: string;
+ phone_number_verified: boolean;
picture: string;
signup_methods: string;
roles: [string];
@@ -145,7 +146,7 @@ export default function Users() {
};
const checkEmailVerification = async () => {
setLoading(true);
- const { data } = await client.query(EmailVerificationQuery).toPromise();
+ const { data } = await client.query(EmailVerificationQuery, {}).toPromise();
if (data?._env) {
const { DISABLE_EMAIL_VERIFICATION } = data._env;
setDisableInviteMembers(DISABLE_EMAIL_VERIFICATION);
diff --git a/dashboard/src/pages/Webhooks.tsx b/web/dashboard/src/pages/Webhooks.tsx
similarity index 100%
rename from dashboard/src/pages/Webhooks.tsx
rename to web/dashboard/src/pages/Webhooks.tsx
diff --git a/dashboard/src/routes/index.tsx b/web/dashboard/src/routes/index.tsx
similarity index 88%
rename from dashboard/src/routes/index.tsx
rename to web/dashboard/src/routes/index.tsx
index 544c17268..c8ac37aef 100644
--- a/dashboard/src/routes/index.tsx
+++ b/web/dashboard/src/routes/index.tsx
@@ -6,7 +6,6 @@ import { DashboardLayout } from '../layouts/DashboardLayout';
import EmailTemplates from '../pages/EmailTemplates';
const Auth = lazy(() => import('../pages/Auth'));
-const Environment = lazy(() => import('../pages/Environment'));
const Home = lazy(() => import('../pages/Home'));
const Users = lazy(() => import('../pages/Users'));
const Webhooks = lazy(() => import('../pages/Webhooks'));
@@ -26,11 +25,11 @@ export const AppRoutes = () => {
}
>
- }>
+ {/* }>
} />
} />
-
- } />
+ */}
+ } />
} />
} />
} />
diff --git a/dashboard/src/utils/index.ts b/web/dashboard/src/utils/index.ts
similarity index 100%
rename from dashboard/src/utils/index.ts
rename to web/dashboard/src/utils/index.ts
diff --git a/dashboard/src/utils/parseCSV.ts b/web/dashboard/src/utils/parseCSV.ts
similarity index 100%
rename from dashboard/src/utils/parseCSV.ts
rename to web/dashboard/src/utils/parseCSV.ts
diff --git a/web/dashboard/tsconfig.json b/web/dashboard/tsconfig.json
new file mode 100644
index 000000000..73810f7ba
--- /dev/null
+++ b/web/dashboard/tsconfig.json
@@ -0,0 +1,80 @@
+{
+ "include": ["src/**/*"],
+ "exclude": ["node_modules", "build", "dist"],
+ "compilerOptions": {
+ /* Visit https://aka.ms/tsconfig.json to read more about this file */
+
+ /* Basic Options */
+ // "incremental": true, /* Enable incremental compilation */
+ "target": "ES2020" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', 'ES2021', or 'ESNEXT'. */,
+ "module": "ESNext" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */,
+ "lib": [
+ "ES2020",
+ "DOM",
+ "DOM.Iterable"
+ ] /* Specify library files to be included in the compilation. */,
+ "allowJs": true /* Allow javascript files to be compiled. */,
+ // "checkJs": true, /* Report errors in .js files. */
+ "jsx": "react-jsx" /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */,
+ // "declaration": true, /* Generates corresponding '.d.ts' file. */
+ // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
+ // "sourceMap": true, /* Generates corresponding '.map' file. */
+ // "outFile": "./", /* Concatenate and emit output to single file. */
+ // "outDir": "./", /* Redirect output structure to the directory. */
+ "rootDir": "src" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */,
+ // "composite": true, /* Enable project compilation */
+ // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
+ // "removeComments": true, /* Do not emit comments to output. */
+ "noEmit": true /* Do not emit outputs. */,
+ // "importHelpers": true, /* Import emit helpers from 'tslib'. */
+ // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
+ "isolatedModules": true /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */,
+
+ /* Strict Type-Checking Options */
+ "strict": true /* Enable all strict type-checking options. */,
+ // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
+ // "strictNullChecks": true, /* Enable strict null checks. */
+ // "strictFunctionTypes": true, /* Enable strict checking of function types. */
+ // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
+ // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
+ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
+ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
+
+ /* Additional Checks */
+ // "noUnusedLocals": true, /* Report errors on unused locals. */
+ // "noUnusedParameters": true, /* Report errors on unused parameters. */
+ // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
+ // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
+ // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */
+ // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an 'override' modifier. */
+ // "noPropertyAccessFromIndexSignature": true, /* Require undeclared properties from index signatures to use element accesses. */
+
+ /* Module Resolution Options */
+ "moduleResolution": "bundler" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */,
+ "baseUrl": "." /* Base directory to resolve non-absolute module names. */,
+ "paths": {
+ "@/*": ["./src/*"]
+ } /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */,
+ // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
+ // "typeRoots": [], /* List of folders to include type definitions from. */
+ "types": [] /* Type declaration files to be included in compilation. */,
+ "allowSyntheticDefaultImports": true /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */,
+ "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,
+ // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
+ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
+
+ /* Source Map Options */
+ // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
+ // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
+ // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
+ // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
+
+ /* Experimental Options */
+ // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
+ // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
+
+ /* Advanced Options */
+ "skipLibCheck": true /* Skip type checking of declaration files. */,
+ "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
+ }
+}
diff --git a/web/dashboard/vite.config.ts b/web/dashboard/vite.config.ts
new file mode 100644
index 000000000..9a0d4e2f9
--- /dev/null
+++ b/web/dashboard/vite.config.ts
@@ -0,0 +1,25 @@
+import { defineConfig, type PluginOption } from 'vite';
+import react from '@vitejs/plugin-react';
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [react()] as PluginOption[],
+ build: {
+ outDir: 'build',
+ emptyOutDir: true,
+ rollupOptions: {
+ input: {
+ main: 'src/index.tsx',
+ },
+ output: {
+ entryFileNames: 'index.js',
+ chunkFileNames: 'chunk-[name]-[hash].js',
+ assetFileNames: (assetInfo) => {
+ return 'assets/[name]-[hash][extname]';
+ },
+ },
+ },
+ },
+ base: '/dashboard/',
+ publicDir: 'public',
+});
diff --git a/templates/app.tmpl b/web/templates/app.tmpl
similarity index 94%
rename from templates/app.tmpl
rename to web/templates/app.tmpl
index bd15a4ef1..8ddd4bf2b 100644
--- a/templates/app.tmpl
+++ b/web/templates/app.tmpl
@@ -11,7 +11,7 @@
Document
diff --git a/templates/authorize_form_post.tmpl b/web/templates/authorize_form_post.tmpl
similarity index 100%
rename from templates/authorize_form_post.tmpl
rename to web/templates/authorize_form_post.tmpl
diff --git a/templates/authorize_web_message.tmpl b/web/templates/authorize_web_message.tmpl
similarity index 100%
rename from templates/authorize_web_message.tmpl
rename to web/templates/authorize_web_message.tmpl
diff --git a/templates/dashboard.tmpl b/web/templates/dashboard.tmpl
similarity index 99%
rename from templates/dashboard.tmpl
rename to web/templates/dashboard.tmpl
index 8710a3567..a3e4ab4a2 100644
--- a/templates/dashboard.tmpl
+++ b/web/templates/dashboard.tmpl
@@ -8,9 +8,8 @@
- Document