fix: openid flow
This commit is contained in:
parent
4775641431
commit
49556b1709
|
@ -2,5 +2,5 @@
|
||||||
"tabWidth": 2,
|
"tabWidth": 2,
|
||||||
"singleQuote": true,
|
"singleQuote": true,
|
||||||
"trailingComma": "all",
|
"trailingComma": "all",
|
||||||
"useTabs": false
|
"useTabs": true
|
||||||
}
|
}
|
||||||
|
|
30
app/package-lock.json
generated
30
app/package-lock.json
generated
|
@ -9,7 +9,7 @@
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@authorizerdev/authorizer-react": "^1.1.2",
|
"@authorizerdev/authorizer-react": "^1.1.3-beta.1",
|
||||||
"@types/react": "^17.0.15",
|
"@types/react": "^17.0.15",
|
||||||
"@types/react-dom": "^17.0.9",
|
"@types/react-dom": "^17.0.9",
|
||||||
"esbuild": "^0.12.17",
|
"esbuild": "^0.12.17",
|
||||||
|
@ -27,9 +27,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@authorizerdev/authorizer-js": {
|
"node_modules/@authorizerdev/authorizer-js": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.2-beta.1",
|
||||||
"resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-1.1.2-beta.1.tgz",
|
||||||
"integrity": "sha512-MdEw1SjhIm7pXq20AscHSbnAta2PC3w7GNBY52/OzmlBXUGH3ooUQX/aszbYOse3FlhapcrGrRvg4sNM7faGAg==",
|
"integrity": "sha512-u+O2iB3tqF1HtdJ6LfBXL9iMycqlCCL3othBQkqitGP1ldhASWLJ2pcXZAcHgyoeczKdj2XKZKdIcWB3GYR0IQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"cross-fetch": "^3.1.5"
|
"cross-fetch": "^3.1.5"
|
||||||
},
|
},
|
||||||
|
@ -38,11 +38,11 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@authorizerdev/authorizer-react": {
|
"node_modules/@authorizerdev/authorizer-react": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.3-beta.1",
|
||||||
"resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-1.1.3-beta.1.tgz",
|
||||||
"integrity": "sha512-uBmuKnOVX8gp8CEUuGJuz04ep+8qMEzJXWd5leEGKYMIgolHpu/lOinnMUXhjh8YL3pA4+EhvB+hQXxUX+rRHQ==",
|
"integrity": "sha512-+ZsOBp6XjZVnDyeJCXgaqZ8xzFO7ygpHB6v2cblCKIA3wX5pg/Dsg1oumHGrSHIEK8No/GOtCjSx4Rv6/CweBQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@authorizerdev/authorizer-js": "^1.1.0",
|
"@authorizerdev/authorizer-js": "^1.1.2-beta.1",
|
||||||
"final-form": "^4.20.2",
|
"final-form": "^4.20.2",
|
||||||
"react-final-form": "^6.5.3",
|
"react-final-form": "^6.5.3",
|
||||||
"styled-components": "^5.3.0"
|
"styled-components": "^5.3.0"
|
||||||
|
@ -876,19 +876,19 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@authorizerdev/authorizer-js": {
|
"@authorizerdev/authorizer-js": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.2-beta.1",
|
||||||
"resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-1.1.2-beta.1.tgz",
|
||||||
"integrity": "sha512-MdEw1SjhIm7pXq20AscHSbnAta2PC3w7GNBY52/OzmlBXUGH3ooUQX/aszbYOse3FlhapcrGrRvg4sNM7faGAg==",
|
"integrity": "sha512-u+O2iB3tqF1HtdJ6LfBXL9iMycqlCCL3othBQkqitGP1ldhASWLJ2pcXZAcHgyoeczKdj2XKZKdIcWB3GYR0IQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"cross-fetch": "^3.1.5"
|
"cross-fetch": "^3.1.5"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@authorizerdev/authorizer-react": {
|
"@authorizerdev/authorizer-react": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.3-beta.1",
|
||||||
"resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-1.1.3-beta.1.tgz",
|
||||||
"integrity": "sha512-uBmuKnOVX8gp8CEUuGJuz04ep+8qMEzJXWd5leEGKYMIgolHpu/lOinnMUXhjh8YL3pA4+EhvB+hQXxUX+rRHQ==",
|
"integrity": "sha512-+ZsOBp6XjZVnDyeJCXgaqZ8xzFO7ygpHB6v2cblCKIA3wX5pg/Dsg1oumHGrSHIEK8No/GOtCjSx4Rv6/CweBQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@authorizerdev/authorizer-js": "^1.1.0",
|
"@authorizerdev/authorizer-js": "^1.1.2-beta.1",
|
||||||
"final-form": "^4.20.2",
|
"final-form": "^4.20.2",
|
||||||
"react-final-form": "^6.5.3",
|
"react-final-form": "^6.5.3",
|
||||||
"styled-components": "^5.3.0"
|
"styled-components": "^5.3.0"
|
||||||
|
|
|
@ -6,13 +6,13 @@
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "rm -rf build && NODE_ENV=production node ./esbuild.config.js",
|
"build": "rm -rf build && NODE_ENV=production node ./esbuild.config.js",
|
||||||
"start": "NODE_ENV=development node ./esbuild.config.js",
|
"start": "NODE_ENV=development node ./esbuild.config.js",
|
||||||
"format": "prettier --write --use-tabs 'src/**/*.(ts|tsx|js|jsx)'"
|
"format": "prettier --write 'src/**/*.(ts|tsx|js|jsx)'"
|
||||||
},
|
},
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
"author": "Lakhan Samani",
|
"author": "Lakhan Samani",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@authorizerdev/authorizer-react": "^1.1.2",
|
"@authorizerdev/authorizer-react": "^1.1.3-beta.1",
|
||||||
"@types/react": "^17.0.15",
|
"@types/react": "^17.0.15",
|
||||||
"@types/react-dom": "^17.0.9",
|
"@types/react-dom": "^17.0.9",
|
||||||
"esbuild": "^0.12.17",
|
"esbuild": "^0.12.17",
|
||||||
|
|
|
@ -38,8 +38,8 @@ export default function Root({
|
||||||
const scope = searchParams.get('scope')
|
const scope = searchParams.get('scope')
|
||||||
? searchParams.get('scope')?.toString().split(' ')
|
? searchParams.get('scope')?.toString().split(' ')
|
||||||
: ['openid', 'profile', 'email'];
|
: ['openid', 'profile', 'email'];
|
||||||
const code = searchParams.get('code') || ''
|
const code = searchParams.get('code') || '';
|
||||||
const nonce = searchParams.get('nonce') || ''
|
const nonce = searchParams.get('nonce') || '';
|
||||||
|
|
||||||
const urlProps: Record<string, any> = {
|
const urlProps: Record<string, any> = {
|
||||||
state,
|
state,
|
||||||
|
@ -57,16 +57,17 @@ export default function Root({
|
||||||
urlProps.redirect_uri = urlProps.redirectURL;
|
urlProps.redirect_uri = urlProps.redirectURL;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
console.log(config);
|
||||||
if (token) {
|
if (token) {
|
||||||
let redirectURL = config.redirectURL || '/app';
|
let redirectURL = config.redirectURL || '/app';
|
||||||
let params = `access_token=${token.access_token}&id_token=${token.id_token}&expires_in=${token.expires_in}&state=${globalState.state}`;
|
let params = `access_token=${token.access_token}&id_token=${token.id_token}&expires_in=${token.expires_in}&state=${globalState.state}`;
|
||||||
|
|
||||||
if (code !== '') {
|
if (code !== '') {
|
||||||
params += `&code=${code}`
|
params += `&code=${code}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nonce !== '') {
|
if (nonce !== '') {
|
||||||
params += `&nonce=${nonce}`
|
params += `&nonce=${nonce}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (token.refresh_token) {
|
if (token.refresh_token) {
|
||||||
|
@ -86,7 +87,7 @@ export default function Root({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return () => {};
|
return () => {};
|
||||||
}, [token]);
|
}, [token, config]);
|
||||||
|
|
||||||
if (loading) {
|
if (loading) {
|
||||||
return <h1>Loading...</h1>;
|
return <h1>Loading...</h1>;
|
||||||
|
|
|
@ -2,5 +2,5 @@
|
||||||
"tabWidth": 2,
|
"tabWidth": 2,
|
||||||
"singleQuote": true,
|
"singleQuote": true,
|
||||||
"trailingComma": "all",
|
"trailingComma": "all",
|
||||||
"useTabs": false
|
"useTabs": true
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,9 +7,8 @@ require (
|
||||||
github.com/arangodb/go-driver v1.2.1
|
github.com/arangodb/go-driver v1.2.1
|
||||||
github.com/aws/aws-sdk-go v1.44.109
|
github.com/aws/aws-sdk-go v1.44.109
|
||||||
github.com/coreos/go-oidc/v3 v3.1.0
|
github.com/coreos/go-oidc/v3 v3.1.0
|
||||||
github.com/denisenkom/go-mssqldb v0.11.0 // indirect
|
|
||||||
github.com/gin-gonic/gin v1.8.1
|
github.com/gin-gonic/gin v1.8.1
|
||||||
github.com/glebarez/sqlite v1.5.0 // indirect
|
github.com/glebarez/sqlite v1.5.0
|
||||||
github.com/go-playground/validator/v10 v10.11.1 // indirect
|
github.com/go-playground/validator/v10 v10.11.1 // indirect
|
||||||
github.com/go-redis/redis/v8 v8.11.0
|
github.com/go-redis/redis/v8 v8.11.0
|
||||||
github.com/goccy/go-json v0.9.11 // indirect
|
github.com/goccy/go-json v0.9.11 // indirect
|
||||||
|
@ -19,7 +18,6 @@ require (
|
||||||
github.com/google/uuid v1.3.0
|
github.com/google/uuid v1.3.0
|
||||||
github.com/guregu/dynamo v1.16.0
|
github.com/guregu/dynamo v1.16.0
|
||||||
github.com/joho/godotenv v1.3.0
|
github.com/joho/godotenv v1.3.0
|
||||||
github.com/mitchellh/gox v1.0.1 // indirect
|
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||||
github.com/pelletier/go-toml/v2 v2.0.5 // indirect
|
github.com/pelletier/go-toml/v2 v2.0.5 // indirect
|
||||||
github.com/robertkrimen/otto v0.0.0-20211024170158-b87d35c0b86f
|
github.com/robertkrimen/otto v0.0.0-20211024170158-b87d35c0b86f
|
||||||
|
|
|
@ -85,8 +85,6 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
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/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/dchest/uniuri v0.0.0-20160212164326-8902c56451e9/go.mod h1:GgB8SF9nRG+GqaDtLcwJZsQFhcogVCJ79j4EdT0c2V4=
|
github.com/dchest/uniuri v0.0.0-20160212164326-8902c56451e9/go.mod h1:GgB8SF9nRG+GqaDtLcwJZsQFhcogVCJ79j4EdT0c2V4=
|
||||||
github.com/denisenkom/go-mssqldb v0.11.0 h1:9rHa233rhdOyrz2GcP9NM+gi2psgJZ4GWDpL/7ND8HI=
|
|
||||||
github.com/denisenkom/go-mssqldb v0.11.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
|
||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
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/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 h1:fRzb/w+pyskVMQ+UbP35JkH8yB7MYb4q/qhBarqZE6g=
|
||||||
|
@ -141,7 +139,6 @@ github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzq
|
||||||
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
|
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 v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
|
||||||
github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
|
github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
|
||||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY=
|
|
||||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
||||||
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA=
|
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA=
|
||||||
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
||||||
|
@ -213,8 +210,6 @@ github.com/guregu/dynamo v1.16.0 h1:gmI8oi1VHwYQtq7+RPBeOiSssVLgxH/Az2t+NtDtL2c=
|
||||||
github.com/guregu/dynamo v1.16.0/go.mod h1:W2Gqcf3MtkrS+Q6fHPGAmRtT0Dyq+TGrqfqrUC9+R/c=
|
github.com/guregu/dynamo v1.16.0/go.mod h1:W2Gqcf3MtkrS+Q6fHPGAmRtT0Dyq+TGrqfqrUC9+R/c=
|
||||||
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8=
|
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8=
|
||||||
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4=
|
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4=
|
||||||
github.com/hashicorp/go-version v1.0.0 h1:21MVWPKDphxa7ineQQTrCU5brh7OuVVAzGOCnnCPtE8=
|
|
||||||
github.com/hashicorp/go-version v1.0.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
|
||||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
|
github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
|
||||||
|
@ -232,8 +227,6 @@ github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsU
|
||||||
github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o=
|
github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o=
|
||||||
github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY=
|
github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY=
|
||||||
github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI=
|
github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI=
|
||||||
github.com/jackc/pgconn v1.10.1 h1:DzdIHIjG1AxGwoEEqS+mGsURyjt4enSmqzACXvVzOT8=
|
|
||||||
github.com/jackc/pgconn v1.10.1/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI=
|
|
||||||
github.com/jackc/pgconn v1.13.0 h1:3L1XMNV2Zvca/8BYhzcRFS70Lr0WlDg16Di6SFGAbys=
|
github.com/jackc/pgconn v1.13.0 h1:3L1XMNV2Zvca/8BYhzcRFS70Lr0WlDg16Di6SFGAbys=
|
||||||
github.com/jackc/pgconn v1.13.0/go.mod h1:AnowpAqO4CMIIJNZl2VJp+KrkAZciAkhEl0W0JIobpI=
|
github.com/jackc/pgconn v1.13.0/go.mod h1:AnowpAqO4CMIIJNZl2VJp+KrkAZciAkhEl0W0JIobpI=
|
||||||
github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE=
|
github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE=
|
||||||
|
@ -252,8 +245,6 @@ github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvW
|
||||||
github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
|
github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
|
||||||
github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
|
github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
|
||||||
github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
|
github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
|
||||||
github.com/jackc/pgproto3/v2 v2.2.0 h1:r7JypeP2D3onoQTCxWdTpCtJ4D+qpKr0TxvoyMhZ5ns=
|
|
||||||
github.com/jackc/pgproto3/v2 v2.2.0/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
|
|
||||||
github.com/jackc/pgproto3/v2 v2.3.1 h1:nwj7qwf0S+Q7ISFfBndqeLwSwxs+4DPsbRFjECT1Y4Y=
|
github.com/jackc/pgproto3/v2 v2.3.1 h1:nwj7qwf0S+Q7ISFfBndqeLwSwxs+4DPsbRFjECT1Y4Y=
|
||||||
github.com/jackc/pgproto3/v2 v2.3.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
|
github.com/jackc/pgproto3/v2 v2.3.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
|
||||||
github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b h1:C8S2+VttkHFdOOCXJe+YGfa4vHYwlt4Zx+IVXQ97jYg=
|
github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b h1:C8S2+VttkHFdOOCXJe+YGfa4vHYwlt4Zx+IVXQ97jYg=
|
||||||
|
@ -262,28 +253,20 @@ github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01C
|
||||||
github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc=
|
github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc=
|
||||||
github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw=
|
github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw=
|
||||||
github.com/jackc/pgtype v1.8.1-0.20210724151600-32e20a603178/go.mod h1:C516IlIV9NKqfsMCXTdChteoXmwgUceqaLfjg2e3NlM=
|
github.com/jackc/pgtype v1.8.1-0.20210724151600-32e20a603178/go.mod h1:C516IlIV9NKqfsMCXTdChteoXmwgUceqaLfjg2e3NlM=
|
||||||
github.com/jackc/pgtype v1.9.0 h1:/SH1RxEtltvJgsDqp3TbiTFApD3mey3iygpuEGeuBXk=
|
|
||||||
github.com/jackc/pgtype v1.9.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4=
|
|
||||||
github.com/jackc/pgtype v1.12.0 h1:Dlq8Qvcch7kiehm8wPGIW0W3KsCCHJnRacKW0UM8n5w=
|
github.com/jackc/pgtype v1.12.0 h1:Dlq8Qvcch7kiehm8wPGIW0W3KsCCHJnRacKW0UM8n5w=
|
||||||
github.com/jackc/pgtype v1.12.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4=
|
github.com/jackc/pgtype v1.12.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4=
|
||||||
github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y=
|
github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y=
|
||||||
github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM=
|
github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM=
|
||||||
github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc=
|
github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc=
|
||||||
github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs=
|
github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs=
|
||||||
github.com/jackc/pgx/v4 v4.14.0 h1:TgdrmgnM7VY72EuSQzBbBd4JA1RLqJolrw9nQVZABVc=
|
|
||||||
github.com/jackc/pgx/v4 v4.14.0/go.mod h1:jT3ibf/A0ZVCp89rtCIN0zCJxcE74ypROmHEZYsG/j8=
|
|
||||||
github.com/jackc/pgx/v4 v4.17.2 h1:0Ut0rpeKwvIVbMQ1KbMBU4h6wxehBI535LK6Flheh8E=
|
github.com/jackc/pgx/v4 v4.17.2 h1:0Ut0rpeKwvIVbMQ1KbMBU4h6wxehBI535LK6Flheh8E=
|
||||||
github.com/jackc/pgx/v4 v4.17.2/go.mod h1:lcxIZN44yMIrWI78a5CpucdD14hX0SBDbNRvjDBItsw=
|
github.com/jackc/pgx/v4 v4.17.2/go.mod h1:lcxIZN44yMIrWI78a5CpucdD14hX0SBDbNRvjDBItsw=
|
||||||
github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||||
github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||||
github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||||
github.com/jackc/puddle v1.2.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
|
||||||
github.com/jackc/puddle v1.3.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
github.com/jackc/puddle v1.3.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||||
github.com/jinzhu/now v1.1.2/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
|
||||||
github.com/jinzhu/now v1.1.3 h1:PlHq1bSCSZL9K0wUhbm2pGLoTWs2GwVhsP6emvGV/ZI=
|
|
||||||
github.com/jinzhu/now v1.1.3/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
|
||||||
github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||||
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
||||||
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||||
|
@ -332,16 +315,9 @@ github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Ky
|
||||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||||
github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
|
github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
|
||||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||||
github.com/mattn/go-sqlite3 v1.14.9 h1:10HX2Td0ocZpYEjhilsuo6WWtUqttj2Kb0KtD86/KYA=
|
|
||||||
github.com/mattn/go-sqlite3 v1.14.9/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
|
||||||
github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI=
|
|
||||||
github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||||
github.com/microsoft/go-mssqldb v0.17.0 h1:Fto83dMZPnYv1Zwx5vHHxpNraeEaUlQ/hhHLgZiaenE=
|
github.com/microsoft/go-mssqldb v0.17.0 h1:Fto83dMZPnYv1Zwx5vHHxpNraeEaUlQ/hhHLgZiaenE=
|
||||||
github.com/microsoft/go-mssqldb v0.17.0/go.mod h1:OkoNGhGEs8EZqchVTtochlXruEhEOaO4S0d2sB5aeGQ=
|
github.com/microsoft/go-mssqldb v0.17.0/go.mod h1:OkoNGhGEs8EZqchVTtochlXruEhEOaO4S0d2sB5aeGQ=
|
||||||
github.com/mitchellh/gox v1.0.1 h1:x0jD3dcHk9a9xPSDN6YEL4xL6Qz0dvNYm8yZqui5chI=
|
|
||||||
github.com/mitchellh/gox v1.0.1/go.mod h1:ED6BioOGXMswlXa2zxfh/xdd5QhwYliBFn9V18Ap4z4=
|
|
||||||
github.com/mitchellh/iochan v1.0.0 h1:C+X3KsSTLFVBr/tK1eYN/vs4rJcvsiLU338UhYPJWeY=
|
|
||||||
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
|
|
||||||
github.com/mitchellh/mapstructure v1.3.1 h1:cCBH2gTD2K0OtLlv/Y5H01VQCqmlDxz30kS5Y5bqfLA=
|
github.com/mitchellh/mapstructure v1.3.1 h1:cCBH2gTD2K0OtLlv/Y5H01VQCqmlDxz30kS5Y5bqfLA=
|
||||||
github.com/mitchellh/mapstructure v1.3.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
github.com/mitchellh/mapstructure v1.3.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
|
@ -457,7 +433,6 @@ go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||||
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
|
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
|
||||||
golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
||||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
|
@ -472,8 +447,6 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y
|
||||||
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/crypto v0.0.0-20220511200225-c6db032c6c88/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20220511200225-c6db032c6c88/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be h1:fmw3UbQh+nxngCAHrDCCztao/kbYFnWjoqop8dHx05A=
|
|
||||||
golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
|
||||||
golang.org/x/crypto v0.0.0-20221005025214-4161e89ecf1b h1:huxqepDufQpLLIRXiVkTvnxrzJlpwmIWAObmcCcUFr0=
|
golang.org/x/crypto v0.0.0-20221005025214-4161e89ecf1b h1:huxqepDufQpLLIRXiVkTvnxrzJlpwmIWAObmcCcUFr0=
|
||||||
golang.org/x/crypto v0.0.0-20221005025214-4161e89ecf1b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20221005025214-4161e89ecf1b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
|
@ -814,26 +787,13 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C
|
||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gorm.io/driver/mysql v1.2.1 h1:h+3f1l9Ng2C072Y2tIiLgPpWN78r1KXL7bHJ0nTjlhU=
|
|
||||||
gorm.io/driver/mysql v1.2.1/go.mod h1:qsiz+XcAyMrS6QY+X3M9R6b/lKM1imKmcuK9kac5LTo=
|
|
||||||
gorm.io/driver/mysql v1.4.3 h1:/JhWJhO2v17d8hjApTltKNADm7K7YI2ogkR7avJUL3k=
|
gorm.io/driver/mysql v1.4.3 h1:/JhWJhO2v17d8hjApTltKNADm7K7YI2ogkR7avJUL3k=
|
||||||
gorm.io/driver/mysql v1.4.3/go.mod h1:sSIebwZAVPiT+27jK9HIwvsqOGKx3YMPmrA3mBJR10c=
|
gorm.io/driver/mysql v1.4.3/go.mod h1:sSIebwZAVPiT+27jK9HIwvsqOGKx3YMPmrA3mBJR10c=
|
||||||
gorm.io/driver/postgres v1.2.3 h1:f4t0TmNMy9gh3TU2PX+EppoA6YsgFnyq8Ojtddb42To=
|
|
||||||
gorm.io/driver/postgres v1.2.3/go.mod h1:pJV6RgYQPG47aM1f0QeOzFH9HxQc8JcmAgjRCgS0wjs=
|
|
||||||
gorm.io/driver/postgres v1.4.5 h1:mTeXTTtHAgnS9PgmhN2YeUbazYpLhUI1doLnw42XUZc=
|
gorm.io/driver/postgres v1.4.5 h1:mTeXTTtHAgnS9PgmhN2YeUbazYpLhUI1doLnw42XUZc=
|
||||||
gorm.io/driver/postgres v1.4.5/go.mod h1:GKNQYSJ14qvWkvPwXljMGehpKrhlDNsqYRr5HnYGncg=
|
gorm.io/driver/postgres v1.4.5/go.mod h1:GKNQYSJ14qvWkvPwXljMGehpKrhlDNsqYRr5HnYGncg=
|
||||||
gorm.io/driver/sqlite v1.2.6 h1:SStaH/b+280M7C8vXeZLz/zo9cLQmIGwwj3cSj7p6l4=
|
|
||||||
gorm.io/driver/sqlite v1.2.6/go.mod h1:gyoX0vHiiwi0g49tv+x2E7l8ksauLK0U/gShcdUsjWY=
|
|
||||||
gorm.io/driver/sqlserver v1.2.1 h1:KhGOjvPX7JZ5hPyQICTJfMuTz88zgJ2lk9bWiHVNHd8=
|
|
||||||
gorm.io/driver/sqlserver v1.2.1/go.mod h1:nixq0OB3iLXZDiPv6JSOjWuPgpyaRpOIIevYtA4Ulb4=
|
|
||||||
gorm.io/driver/sqlserver v1.4.1 h1:t4r4r6Jam5E6ejqP7N82qAJIJAht27EGT41HyPfXRw0=
|
gorm.io/driver/sqlserver v1.4.1 h1:t4r4r6Jam5E6ejqP7N82qAJIJAht27EGT41HyPfXRw0=
|
||||||
gorm.io/driver/sqlserver v1.4.1/go.mod h1:DJ4P+MeZbc5rvY58PnmN1Lnyvb5gw5NPzGshHDnJLig=
|
gorm.io/driver/sqlserver v1.4.1/go.mod h1:DJ4P+MeZbc5rvY58PnmN1Lnyvb5gw5NPzGshHDnJLig=
|
||||||
gorm.io/gorm v1.22.2/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0=
|
|
||||||
gorm.io/gorm v1.22.3/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0=
|
|
||||||
gorm.io/gorm v1.22.4 h1:8aPcyEJhY0MAt8aY6Dc524Pn+pO29K+ydu+e/cXSpQM=
|
|
||||||
gorm.io/gorm v1.22.4/go.mod h1:1aeVC+pe9ZmvKZban/gW4QPra7PRoTEssyc922qCAkk=
|
|
||||||
gorm.io/gorm v1.23.8/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
|
gorm.io/gorm v1.23.8/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
|
||||||
gorm.io/gorm v1.24.0 h1:j/CoiSm6xpRpmzbFJsQHYj+I8bGYWLXVHeYEyyKlF74=
|
|
||||||
gorm.io/gorm v1.24.0/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA=
|
gorm.io/gorm v1.24.0/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA=
|
||||||
gorm.io/gorm v1.24.1-0.20221019064659-5dd2bb482755/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA=
|
gorm.io/gorm v1.24.1-0.20221019064659-5dd2bb482755/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA=
|
||||||
gorm.io/gorm v1.24.1 h1:CgvzRniUdG67hBAzsxDGOAuq4Te1osVMYsa1eQbd4fs=
|
gorm.io/gorm v1.24.1 h1:CgvzRniUdG67hBAzsxDGOAuq4Te1osVMYsa1eQbd4fs=
|
||||||
|
|
|
@ -2250,6 +2250,10 @@ input SignUpInput {
|
||||||
scope: [String!]
|
scope: [String!]
|
||||||
redirect_uri: String
|
redirect_uri: String
|
||||||
is_multi_factor_auth_enabled: Boolean
|
is_multi_factor_auth_enabled: Boolean
|
||||||
|
# state is used for authorization code grant flow
|
||||||
|
# it is used to get code for an on-going auth process during login
|
||||||
|
# and use that code for setting ` + "`" + `c_hash` + "`" + ` in id_token
|
||||||
|
state: String
|
||||||
}
|
}
|
||||||
|
|
||||||
input LoginInput {
|
input LoginInput {
|
||||||
|
@ -2257,10 +2261,18 @@ input LoginInput {
|
||||||
password: String!
|
password: String!
|
||||||
roles: [String!]
|
roles: [String!]
|
||||||
scope: [String!]
|
scope: [String!]
|
||||||
|
# state is used for authorization code grant flow
|
||||||
|
# it is used to get code for an on-going auth process during login
|
||||||
|
# and use that code for setting ` + "`" + `c_hash` + "`" + ` in id_token
|
||||||
|
state: String
|
||||||
}
|
}
|
||||||
|
|
||||||
input VerifyEmailInput {
|
input VerifyEmailInput {
|
||||||
token: String!
|
token: String!
|
||||||
|
# state is used for authorization code grant flow
|
||||||
|
# it is used to get code for an on-going auth process during login
|
||||||
|
# and use that code for setting ` + "`" + `c_hash` + "`" + ` in id_token
|
||||||
|
state: String
|
||||||
}
|
}
|
||||||
|
|
||||||
input ResendVerifyEmailInput {
|
input ResendVerifyEmailInput {
|
||||||
|
@ -14455,7 +14467,7 @@ func (ec *executionContext) unmarshalInputLoginInput(ctx context.Context, obj in
|
||||||
asMap[k] = v
|
asMap[k] = v
|
||||||
}
|
}
|
||||||
|
|
||||||
fieldsInOrder := [...]string{"email", "password", "roles", "scope"}
|
fieldsInOrder := [...]string{"email", "password", "roles", "scope", "state"}
|
||||||
for _, k := range fieldsInOrder {
|
for _, k := range fieldsInOrder {
|
||||||
v, ok := asMap[k]
|
v, ok := asMap[k]
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -14494,6 +14506,14 @@ func (ec *executionContext) unmarshalInputLoginInput(ctx context.Context, obj in
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return it, err
|
return it, err
|
||||||
}
|
}
|
||||||
|
case "state":
|
||||||
|
var err error
|
||||||
|
|
||||||
|
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("state"))
|
||||||
|
it.State, err = ec.unmarshalOString2ᚖstring(ctx, v)
|
||||||
|
if err != nil {
|
||||||
|
return it, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14803,7 +14823,7 @@ func (ec *executionContext) unmarshalInputSignUpInput(ctx context.Context, obj i
|
||||||
asMap[k] = v
|
asMap[k] = v
|
||||||
}
|
}
|
||||||
|
|
||||||
fieldsInOrder := [...]string{"email", "given_name", "family_name", "middle_name", "nickname", "gender", "birthdate", "phone_number", "picture", "password", "confirm_password", "roles", "scope", "redirect_uri", "is_multi_factor_auth_enabled"}
|
fieldsInOrder := [...]string{"email", "given_name", "family_name", "middle_name", "nickname", "gender", "birthdate", "phone_number", "picture", "password", "confirm_password", "roles", "scope", "redirect_uri", "is_multi_factor_auth_enabled", "state"}
|
||||||
for _, k := range fieldsInOrder {
|
for _, k := range fieldsInOrder {
|
||||||
v, ok := asMap[k]
|
v, ok := asMap[k]
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -14930,6 +14950,14 @@ func (ec *executionContext) unmarshalInputSignUpInput(ctx context.Context, obj i
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return it, err
|
return it, err
|
||||||
}
|
}
|
||||||
|
case "state":
|
||||||
|
var err error
|
||||||
|
|
||||||
|
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("state"))
|
||||||
|
it.State, err = ec.unmarshalOString2ᚖstring(ctx, v)
|
||||||
|
if err != nil {
|
||||||
|
return it, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15815,7 +15843,7 @@ func (ec *executionContext) unmarshalInputVerifyEmailInput(ctx context.Context,
|
||||||
asMap[k] = v
|
asMap[k] = v
|
||||||
}
|
}
|
||||||
|
|
||||||
fieldsInOrder := [...]string{"token"}
|
fieldsInOrder := [...]string{"token", "state"}
|
||||||
for _, k := range fieldsInOrder {
|
for _, k := range fieldsInOrder {
|
||||||
v, ok := asMap[k]
|
v, ok := asMap[k]
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -15830,6 +15858,14 @@ func (ec *executionContext) unmarshalInputVerifyEmailInput(ctx context.Context,
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return it, err
|
return it, err
|
||||||
}
|
}
|
||||||
|
case "state":
|
||||||
|
var err error
|
||||||
|
|
||||||
|
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("state"))
|
||||||
|
it.State, err = ec.unmarshalOString2ᚖstring(ctx, v)
|
||||||
|
if err != nil {
|
||||||
|
return it, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -151,6 +151,7 @@ type LoginInput struct {
|
||||||
Password string `json:"password"`
|
Password string `json:"password"`
|
||||||
Roles []string `json:"roles"`
|
Roles []string `json:"roles"`
|
||||||
Scope []string `json:"scope"`
|
Scope []string `json:"scope"`
|
||||||
|
State *string `json:"state"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type MagicLinkLoginInput struct {
|
type MagicLinkLoginInput struct {
|
||||||
|
@ -238,6 +239,7 @@ type SignUpInput struct {
|
||||||
Scope []string `json:"scope"`
|
Scope []string `json:"scope"`
|
||||||
RedirectURI *string `json:"redirect_uri"`
|
RedirectURI *string `json:"redirect_uri"`
|
||||||
IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled"`
|
IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled"`
|
||||||
|
State *string `json:"state"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type TestEndpointRequest struct {
|
type TestEndpointRequest struct {
|
||||||
|
@ -409,6 +411,7 @@ type VerificationRequests struct {
|
||||||
|
|
||||||
type VerifyEmailInput struct {
|
type VerifyEmailInput struct {
|
||||||
Token string `json:"token"`
|
Token string `json:"token"`
|
||||||
|
State *string `json:"state"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type VerifyOTPRequest struct {
|
type VerifyOTPRequest struct {
|
||||||
|
|
|
@ -285,6 +285,10 @@ input SignUpInput {
|
||||||
scope: [String!]
|
scope: [String!]
|
||||||
redirect_uri: String
|
redirect_uri: String
|
||||||
is_multi_factor_auth_enabled: Boolean
|
is_multi_factor_auth_enabled: Boolean
|
||||||
|
# state is used for authorization code grant flow
|
||||||
|
# it is used to get code for an on-going auth process during login
|
||||||
|
# and use that code for setting `c_hash` in id_token
|
||||||
|
state: String
|
||||||
}
|
}
|
||||||
|
|
||||||
input LoginInput {
|
input LoginInput {
|
||||||
|
@ -292,15 +296,27 @@ input LoginInput {
|
||||||
password: String!
|
password: String!
|
||||||
roles: [String!]
|
roles: [String!]
|
||||||
scope: [String!]
|
scope: [String!]
|
||||||
|
# state is used for authorization code grant flow
|
||||||
|
# it is used to get code for an on-going auth process during login
|
||||||
|
# and use that code for setting `c_hash` in id_token
|
||||||
|
state: String
|
||||||
}
|
}
|
||||||
|
|
||||||
input VerifyEmailInput {
|
input VerifyEmailInput {
|
||||||
token: String!
|
token: String!
|
||||||
|
# state is used for authorization code grant flow
|
||||||
|
# it is used to get code for an on-going auth process during login
|
||||||
|
# and use that code for setting `c_hash` in id_token
|
||||||
|
state: String
|
||||||
}
|
}
|
||||||
|
|
||||||
input ResendVerifyEmailInput {
|
input ResendVerifyEmailInput {
|
||||||
email: String!
|
email: String!
|
||||||
identifier: String!
|
identifier: String!
|
||||||
|
# state is used for authorization code grant flow
|
||||||
|
# it is used to get code for an on-going auth process during login
|
||||||
|
# and use that code for setting `c_hash` in id_token
|
||||||
|
state: String
|
||||||
}
|
}
|
||||||
|
|
||||||
input UpdateProfileInput {
|
input UpdateProfileInput {
|
||||||
|
@ -448,10 +464,18 @@ input DeleteEmailTemplateRequest {
|
||||||
input VerifyOTPRequest {
|
input VerifyOTPRequest {
|
||||||
email: String!
|
email: String!
|
||||||
otp: String!
|
otp: String!
|
||||||
|
# state is used for authorization code grant flow
|
||||||
|
# it is used to get code for an on-going auth process during login
|
||||||
|
# and use that code for setting `c_hash` in id_token
|
||||||
|
state: String
|
||||||
}
|
}
|
||||||
|
|
||||||
input ResendOTPRequest {
|
input ResendOTPRequest {
|
||||||
email: String!
|
email: String!
|
||||||
|
# state is used for authorization code grant flow
|
||||||
|
# it is used to get code for an on-going auth process during login
|
||||||
|
# and use that code for setting `c_hash` in id_token
|
||||||
|
state: String
|
||||||
}
|
}
|
||||||
|
|
||||||
type Mutation {
|
type Mutation {
|
||||||
|
|
|
@ -86,10 +86,23 @@ func AuthorizeHandler() gin.HandlerFunc {
|
||||||
"code": code,
|
"code": code,
|
||||||
})
|
})
|
||||||
|
|
||||||
memorystore.Provider.SetState(codeChallenge, code)
|
// memorystore.Provider.SetState(codeChallenge, code)
|
||||||
|
// TODO add state with timeout
|
||||||
|
|
||||||
// used for response mode query or fragment
|
// used for response mode query or fragment
|
||||||
loginState := "state=" + state + "&scope=" + strings.Join(scope, " ") + "&redirect_uri=" + redirectURI + "&code=" + code + "&nonce=" + nonce
|
loginState := "state=" + state + "&scope=" + strings.Join(scope, " ") + "&redirect_uri=" + redirectURI
|
||||||
|
if responseType == constants.ResponseTypeCode {
|
||||||
|
loginState += "&code=" + code
|
||||||
|
if err := memorystore.Provider.SetState(state, code+"@@"+codeChallenge); err != nil {
|
||||||
|
log.Debug("Error setting temp code", err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
loginState += "&nonce=" + nonce
|
||||||
|
if err := memorystore.Provider.SetState(state, nonce); err != nil {
|
||||||
|
log.Debug("Error setting temp code", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
loginURL := "/app?" + loginState
|
loginURL := "/app?" + loginState
|
||||||
|
|
||||||
if responseMode == constants.ResponseModeFragment {
|
if responseMode == constants.ResponseModeFragment {
|
||||||
|
@ -168,7 +181,15 @@ func AuthorizeHandler() gin.HandlerFunc {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := memorystore.Provider.SetState(codeChallenge, code+"@"+newSessionToken); err != nil {
|
// TODO: add state with timeout
|
||||||
|
// if err := memorystore.Provider.SetState(codeChallenge, code+"@"+newSessionToken); err != nil {
|
||||||
|
// log.Debug("SetState failed: ", err)
|
||||||
|
// handleResponse(gc, responseMode, loginURL, redirectURI, loginError, http.StatusOK)
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
|
||||||
|
// TODO: add state with timeout
|
||||||
|
if err := memorystore.Provider.SetState(code, codeChallenge+"@@"+newSessionToken); err != nil {
|
||||||
log.Debug("SetState failed: ", err)
|
log.Debug("SetState failed: ", err)
|
||||||
handleResponse(gc, responseMode, loginURL, redirectURI, loginError, http.StatusOK)
|
handleResponse(gc, responseMode, loginURL, redirectURI, loginError, http.StatusOK)
|
||||||
return
|
return
|
||||||
|
@ -317,13 +338,15 @@ func handleResponse(gc *gin.Context, responseMode, loginURI, redirectURI string,
|
||||||
isAuthenticationRequired = true
|
isAuthenticationRequired = true
|
||||||
}
|
}
|
||||||
|
|
||||||
switch responseMode {
|
|
||||||
case constants.ResponseModeQuery, constants.ResponseModeFragment:
|
|
||||||
if isAuthenticationRequired {
|
if isAuthenticationRequired {
|
||||||
gc.Redirect(http.StatusFound, loginURI)
|
gc.Redirect(http.StatusFound, loginURI)
|
||||||
} else {
|
return
|
||||||
gc.Redirect(http.StatusFound, redirectURI)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch responseMode {
|
||||||
|
case constants.ResponseModeQuery, constants.ResponseModeFragment:
|
||||||
|
|
||||||
|
gc.Redirect(http.StatusFound, redirectURI)
|
||||||
return
|
return
|
||||||
case constants.ResponseModeWebMessage:
|
case constants.ResponseModeWebMessage:
|
||||||
gc.HTML(httpStatusCode, authorizeWebMessageTemplate, gin.H{
|
gc.HTML(httpStatusCode, authorizeWebMessageTemplate, gin.H{
|
||||||
|
@ -332,6 +355,8 @@ func handleResponse(gc *gin.Context, responseMode, loginURI, redirectURI string,
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
case constants.ResponseModeFormPost:
|
case constants.ResponseModeFormPost:
|
||||||
|
fmt.Println("=> trying tof orm post")
|
||||||
|
fmt.Printf("=> %+v \n", data["response"])
|
||||||
gc.HTML(httpStatusCode, authorizeFormPostTemplate, gin.H{
|
gc.HTML(httpStatusCode, authorizeFormPostTemplate, gin.H{
|
||||||
"target_origin": redirectURI,
|
"target_origin": redirectURI,
|
||||||
"authorization_response": data["response"],
|
"authorization_response": data["response"],
|
||||||
|
|
|
@ -3,6 +3,7 @@ package handlers
|
||||||
import (
|
import (
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
@ -18,12 +19,26 @@ import (
|
||||||
"github.com/authorizerdev/authorizer/server/token"
|
"github.com/authorizerdev/authorizer/server/token"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type RequestBody struct {
|
||||||
|
CodeVerifier string `form:"code_verifier" json:"code_verifier"`
|
||||||
|
Code string `form:"code" json:"code"`
|
||||||
|
ClientID string `form:"client_id" json:"client_id"`
|
||||||
|
ClientSecret string `form:"client_secret" json:"client_secret"`
|
||||||
|
GrantType string `form:"grant_type" json:"grant_type"`
|
||||||
|
RefreshToken string `form:"refresh_token" json:"refresh_token"`
|
||||||
|
RedirectURI string `form:"redirect_uri" json:"redirect_uri"`
|
||||||
|
}
|
||||||
|
|
||||||
// TokenHandler to handle /oauth/token requests
|
// TokenHandler to handle /oauth/token requests
|
||||||
// grant type required
|
// grant type required
|
||||||
func TokenHandler() gin.HandlerFunc {
|
func TokenHandler() gin.HandlerFunc {
|
||||||
return func(gc *gin.Context) {
|
return func(gc *gin.Context) {
|
||||||
var reqBody map[string]string
|
// body := gc.Request.Body
|
||||||
if err := gc.BindJSON(&reqBody); err != nil {
|
// x, _ := ioutil.ReadAll(body)
|
||||||
|
|
||||||
|
// fmt.Printf("=> %s \n %s\n", string(x), gc.Request.Header.Get("Content-Type"))
|
||||||
|
var reqBody RequestBody
|
||||||
|
if err := gc.Bind(&reqBody); err != nil {
|
||||||
log.Debug("Error binding JSON: ", err)
|
log.Debug("Error binding JSON: ", err)
|
||||||
gc.JSON(http.StatusBadRequest, gin.H{
|
gc.JSON(http.StatusBadRequest, gin.H{
|
||||||
"error": "error_binding_json",
|
"error": "error_binding_json",
|
||||||
|
@ -32,11 +47,14 @@ func TokenHandler() gin.HandlerFunc {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
codeVerifier := strings.TrimSpace(reqBody["code_verifier"])
|
fmt.Printf("=>req body: %+v\n", reqBody)
|
||||||
code := strings.TrimSpace(reqBody["code"])
|
|
||||||
clientID := strings.TrimSpace(reqBody["client_id"])
|
codeVerifier := strings.TrimSpace(reqBody.CodeVerifier)
|
||||||
grantType := strings.TrimSpace(reqBody["grant_type"])
|
code := strings.TrimSpace(reqBody.Code)
|
||||||
refreshToken := strings.TrimSpace(reqBody["refresh_token"])
|
clientID := strings.TrimSpace(reqBody.ClientID)
|
||||||
|
grantType := strings.TrimSpace(reqBody.GrantType)
|
||||||
|
refreshToken := strings.TrimSpace(reqBody.RefreshToken)
|
||||||
|
clientSecret := strings.TrimSpace(reqBody.ClientSecret)
|
||||||
|
|
||||||
if grantType == "" {
|
if grantType == "" {
|
||||||
grantType = "authorization_code"
|
grantType = "authorization_code"
|
||||||
|
@ -77,15 +95,6 @@ func TokenHandler() gin.HandlerFunc {
|
||||||
sessionKey := ""
|
sessionKey := ""
|
||||||
|
|
||||||
if isAuthorizationCodeGrant {
|
if isAuthorizationCodeGrant {
|
||||||
if codeVerifier == "" {
|
|
||||||
log.Debug("Code verifier is empty")
|
|
||||||
gc.JSON(http.StatusBadRequest, gin.H{
|
|
||||||
"error": "invalid_code_verifier",
|
|
||||||
"error_description": "The code verifier is required",
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if code == "" {
|
if code == "" {
|
||||||
log.Debug("Code is empty")
|
log.Debug("Code is empty")
|
||||||
gc.JSON(http.StatusBadRequest, gin.H{
|
gc.JSON(http.StatusBadRequest, gin.H{
|
||||||
|
@ -95,14 +104,39 @@ func TokenHandler() gin.HandlerFunc {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
hash := sha256.New()
|
if codeVerifier == "" && clientSecret == "" {
|
||||||
hash.Write([]byte(codeVerifier))
|
gc.JSON(http.StatusBadRequest, gin.H{
|
||||||
encryptedCode := strings.ReplaceAll(base64.URLEncoding.EncodeToString(hash.Sum(nil)), "+", "-")
|
"error": "invalid_dat",
|
||||||
encryptedCode = strings.ReplaceAll(encryptedCode, "/", "_")
|
"error_description": "The code verifier or client secret is required",
|
||||||
encryptedCode = strings.ReplaceAll(encryptedCode, "=", "")
|
})
|
||||||
sessionData, err := memorystore.Provider.GetState(encryptedCode)
|
return
|
||||||
|
}
|
||||||
|
// Get state
|
||||||
|
sessionData, err := memorystore.Provider.GetState(code)
|
||||||
if sessionData == "" || err != nil {
|
if sessionData == "" || err != nil {
|
||||||
log.Debug("Session data is empty")
|
log.Debug("Session data is empty")
|
||||||
|
gc.JSON(http.StatusBadRequest, gin.H{
|
||||||
|
"error": "invalid_code",
|
||||||
|
"error_description": "The code is invalid",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// [0] -> code_challenge
|
||||||
|
// [1] -> session cookie
|
||||||
|
sessionDataSplit := strings.Split(sessionData, "@@")
|
||||||
|
fmt.Println("=> sessionDataSplit:", sessionDataSplit)
|
||||||
|
|
||||||
|
go memorystore.Provider.RemoveState(code)
|
||||||
|
|
||||||
|
if codeVerifier != "" {
|
||||||
|
hash := sha256.New()
|
||||||
|
hash.Write([]byte(codeVerifier))
|
||||||
|
encryptedCode := strings.ReplaceAll(base64.RawURLEncoding.EncodeToString(hash.Sum(nil)), "+", "-")
|
||||||
|
encryptedCode = strings.ReplaceAll(encryptedCode, "/", "_")
|
||||||
|
encryptedCode = strings.ReplaceAll(encryptedCode, "=", "")
|
||||||
|
fmt.Println("=> encryptedCode", encryptedCode)
|
||||||
|
if encryptedCode != sessionDataSplit[0] {
|
||||||
gc.JSON(http.StatusBadRequest, gin.H{
|
gc.JSON(http.StatusBadRequest, gin.H{
|
||||||
"error": "invalid_code_verifier",
|
"error": "invalid_code_verifier",
|
||||||
"error_description": "The code verifier is invalid",
|
"error_description": "The code verifier is invalid",
|
||||||
|
@ -110,19 +144,16 @@ func TokenHandler() gin.HandlerFunc {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
go memorystore.Provider.RemoveState(encryptedCode)
|
} else {
|
||||||
// split session data
|
if clientHash, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyClientSecret); clientSecret != clientHash || err != nil {
|
||||||
// it contains code@sessiontoken
|
log.Debug("Client Secret is invalid: ", clientID)
|
||||||
sessionDataSplit := strings.Split(sessionData, "@")
|
|
||||||
|
|
||||||
if sessionDataSplit[0] != code {
|
|
||||||
log.Debug("Invalid code verifier. Unable to split session data")
|
|
||||||
gc.JSON(http.StatusBadRequest, gin.H{
|
gc.JSON(http.StatusBadRequest, gin.H{
|
||||||
"error": "invalid_code_verifier",
|
"error": "invalid_client_secret",
|
||||||
"error_description": "The code verifier is invalid",
|
"error_description": "The client secret is invalid",
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// validate session
|
// validate session
|
||||||
claims, err := token.ValidateBrowserSession(gc, sessionDataSplit[1])
|
claims, err := token.ValidateBrowserSession(gc, sessionDataSplit[1])
|
||||||
|
@ -135,6 +166,8 @@ func TokenHandler() gin.HandlerFunc {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fmt.Printf("=>claims: %+v\n", &claims)
|
||||||
|
|
||||||
userID = claims.Subject
|
userID = claims.Subject
|
||||||
roles = claims.Roles
|
roles = claims.Roles
|
||||||
scope = claims.Scope
|
scope = claims.Scope
|
||||||
|
@ -147,6 +180,7 @@ func TokenHandler() gin.HandlerFunc {
|
||||||
}
|
}
|
||||||
|
|
||||||
go memorystore.Provider.DeleteUserSession(sessionKey, claims.Nonce)
|
go memorystore.Provider.DeleteUserSession(sessionKey, claims.Nonce)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// validate refresh token
|
// validate refresh token
|
||||||
if refreshToken == "" {
|
if refreshToken == "" {
|
||||||
|
@ -207,7 +241,11 @@ func TokenHandler() gin.HandlerFunc {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
nonce := uuid.New().String()
|
nonce := uuid.New().String() + "@@" + code
|
||||||
|
|
||||||
|
fmt.Println("=> code", code)
|
||||||
|
fmt.Println("=> nonce", nonce)
|
||||||
|
|
||||||
authToken, err := token.CreateAuthToken(gc, user, roles, scope, loginMethod, nonce)
|
authToken, err := token.CreateAuthToken(gc, user, roles, scope, loginMethod, nonce)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Debug("Error creating auth token: ", err)
|
log.Debug("Error creating auth token: ", err)
|
||||||
|
|
|
@ -142,6 +142,28 @@ func LoginResolver(ctx context.Context, params model.LoginInput) (*model.AuthRes
|
||||||
}
|
}
|
||||||
|
|
||||||
nonce := uuid.New().String()
|
nonce := uuid.New().String()
|
||||||
|
fmt.Println("=> state", refs.StringValue(params.State))
|
||||||
|
code := ""
|
||||||
|
codeChallenge := ""
|
||||||
|
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]
|
||||||
|
|
||||||
|
fmt.Println("=> code info", authorizeStateSplit)
|
||||||
|
nonce = nonce + "@@" + code
|
||||||
|
} else {
|
||||||
|
nonce = authorizeState
|
||||||
|
}
|
||||||
|
go memorystore.Provider.RemoveState(refs.StringValue(params.State))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
authToken, err := token.CreateAuthToken(gc, user, roles, scope, constants.AuthRecipeMethodBasicAuth, nonce)
|
authToken, err := token.CreateAuthToken(gc, user, roles, scope, constants.AuthRecipeMethodBasicAuth, nonce)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Debug("Failed to create auth token", err)
|
log.Debug("Failed to create auth token", err)
|
||||||
|
@ -165,6 +187,15 @@ func LoginResolver(ctx context.Context, params model.LoginInput) (*model.AuthRes
|
||||||
sessionStoreKey := constants.AuthRecipeMethodBasicAuth + ":" + user.ID
|
sessionStoreKey := constants.AuthRecipeMethodBasicAuth + ":" + user.ID
|
||||||
memorystore.Provider.SetUserSession(sessionStoreKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash)
|
memorystore.Provider.SetUserSession(sessionStoreKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash)
|
||||||
memorystore.Provider.SetUserSession(sessionStoreKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token)
|
memorystore.Provider.SetUserSession(sessionStoreKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token)
|
||||||
|
// Code challenge could be optional if PKCE flow is not used
|
||||||
|
|
||||||
|
if code != "" {
|
||||||
|
fmt.Println("=> setting the state here....")
|
||||||
|
if err := memorystore.Provider.SetState(code, codeChallenge+"@@"+authToken.FingerPrintHash); err != nil {
|
||||||
|
log.Debug("SetState failed: ", err)
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if authToken.RefreshToken != nil {
|
if authToken.RefreshToken != nil {
|
||||||
res.RefreshToken = &authToken.RefreshToken.Token
|
res.RefreshToken = &authToken.RefreshToken.Token
|
||||||
|
|
|
@ -34,6 +34,16 @@ func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthR
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
code := ""
|
||||||
|
if params.State != nil {
|
||||||
|
// Get state from store
|
||||||
|
code, err = memorystore.Provider.GetState(*params.State)
|
||||||
|
if err != nil {
|
||||||
|
log.Debug("Invalid Error State:", err)
|
||||||
|
return res, fmt.Errorf("invalid_state: %s", err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
isSignupDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableSignUp)
|
isSignupDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableSignUp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Debug("Error getting signup disabled: ", err)
|
log.Debug("Error getting signup disabled: ", err)
|
||||||
|
@ -244,6 +254,10 @@ func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthR
|
||||||
}
|
}
|
||||||
|
|
||||||
nonce := uuid.New().String()
|
nonce := uuid.New().String()
|
||||||
|
if code != "" {
|
||||||
|
nonce = nonce + "@@" + code
|
||||||
|
}
|
||||||
|
|
||||||
authToken, err := token.CreateAuthToken(gc, user, roles, scope, constants.AuthRecipeMethodBasicAuth, nonce)
|
authToken, err := token.CreateAuthToken(gc, user, roles, scope, constants.AuthRecipeMethodBasicAuth, nonce)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Debug("Failed to create auth token: ", err)
|
log.Debug("Failed to create auth token: ", err)
|
||||||
|
|
|
@ -125,7 +125,6 @@ func UpdateUserResolver(ctx context.Context, params model.UpdateUserInput) (*mod
|
||||||
return res, fmt.Errorf("user with this email address already exists")
|
return res, fmt.Errorf("user with this email address already exists")
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO figure out how to do this
|
|
||||||
go memorystore.Provider.DeleteAllUserSessions(user.ID)
|
go memorystore.Provider.DeleteAllUserSessions(user.ID)
|
||||||
|
|
||||||
hostname := parsers.GetHost(gc)
|
hostname := parsers.GetHost(gc)
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package token
|
package token
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/sha256"
|
||||||
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -46,28 +48,22 @@ type SessionData struct {
|
||||||
LoginMethod string `json:"login_method"`
|
LoginMethod string `json:"login_method"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateSessionToken creates a new session token
|
|
||||||
func CreateSessionToken(user models.User, nonce string, roles, scope []string, loginMethod string) (*SessionData, string, error) {
|
|
||||||
fingerPrintMap := &SessionData{
|
|
||||||
Nonce: nonce,
|
|
||||||
Roles: roles,
|
|
||||||
Subject: user.ID,
|
|
||||||
Scope: scope,
|
|
||||||
LoginMethod: loginMethod,
|
|
||||||
IssuedAt: time.Now().Unix(),
|
|
||||||
ExpiresAt: time.Now().AddDate(1, 0, 0).Unix(),
|
|
||||||
}
|
|
||||||
fingerPrintBytes, _ := json.Marshal(fingerPrintMap)
|
|
||||||
fingerPrintHash, err := crypto.EncryptAES(string(fingerPrintBytes))
|
|
||||||
if err != nil {
|
|
||||||
return nil, "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
return fingerPrintMap, fingerPrintHash, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateAuthToken creates a new auth token when userlogs in
|
// CreateAuthToken creates a new auth token when userlogs in
|
||||||
func CreateAuthToken(gc *gin.Context, user models.User, roles, scope []string, loginMethod, nonce string) (*Token, error) {
|
func CreateAuthToken(gc *gin.Context, user models.User, roles, scope []string, loginMethod, nonce string) (*Token, error) {
|
||||||
|
|
||||||
|
code := ""
|
||||||
|
nonceSplit := strings.Split(nonce, "@@")
|
||||||
|
fingerPrint := nonce
|
||||||
|
fmt.Println("=> nonce split", nonceSplit)
|
||||||
|
if len(nonceSplit) > 1 {
|
||||||
|
code = nonceSplit[1]
|
||||||
|
// use original nonce for session token and access token
|
||||||
|
nonce = nonceSplit[0]
|
||||||
|
fingerPrint = nonce
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("=> original nonce:", nonce)
|
||||||
|
|
||||||
hostname := parsers.GetHost(gc)
|
hostname := parsers.GetHost(gc)
|
||||||
_, fingerPrintHash, err := CreateSessionToken(user, nonce, roles, scope, loginMethod)
|
_, fingerPrintHash, err := CreateSessionToken(user, nonce, roles, scope, loginMethod)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -78,13 +74,31 @@ func CreateAuthToken(gc *gin.Context, user models.User, roles, scope []string, l
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
idToken, idTokenExpiresAt, err := CreateIDToken(user, roles, hostname, nonce, loginMethod)
|
atHash := sha256.New()
|
||||||
|
atHash.Write([]byte(accessToken))
|
||||||
|
atHashBytes := atHash.Sum(nil)
|
||||||
|
// hashedToken := string(bs)
|
||||||
|
atHashDigest := atHashBytes[0 : len(atHashBytes)/2]
|
||||||
|
atHashString := base64.RawURLEncoding.EncodeToString(atHashDigest)
|
||||||
|
|
||||||
|
codeHashString := ""
|
||||||
|
if code != "" {
|
||||||
|
fmt.Println("=> atHash", atHashString)
|
||||||
|
codeHash := sha256.New()
|
||||||
|
codeHash.Write([]byte(code))
|
||||||
|
codeHashBytes := codeHash.Sum(nil)
|
||||||
|
codeHashDigest := codeHashBytes[0 : len(codeHashBytes)/2]
|
||||||
|
codeHashString = base64.RawURLEncoding.EncodeToString(codeHashDigest)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("=> at hash nonce", nonce)
|
||||||
|
idToken, idTokenExpiresAt, err := CreateIDToken(user, roles, hostname, nonce, atHashString, codeHashString, loginMethod)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
res := &Token{
|
res := &Token{
|
||||||
FingerPrint: nonce,
|
FingerPrint: fingerPrint,
|
||||||
FingerPrintHash: fingerPrintHash,
|
FingerPrintHash: fingerPrintHash,
|
||||||
AccessToken: &JWTToken{Token: accessToken, ExpiresAt: accessTokenExpiresAt},
|
AccessToken: &JWTToken{Token: accessToken, ExpiresAt: accessTokenExpiresAt},
|
||||||
IDToken: &JWTToken{Token: idToken, ExpiresAt: idTokenExpiresAt},
|
IDToken: &JWTToken{Token: idToken, ExpiresAt: idTokenExpiresAt},
|
||||||
|
@ -102,6 +116,27 @@ func CreateAuthToken(gc *gin.Context, user models.User, roles, scope []string, l
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreateSessionToken creates a new session token
|
||||||
|
func CreateSessionToken(user models.User, nonce string, roles, scope []string, loginMethod string) (*SessionData, string, error) {
|
||||||
|
fingerPrintMap := &SessionData{
|
||||||
|
Nonce: nonce,
|
||||||
|
Roles: roles,
|
||||||
|
Subject: user.ID,
|
||||||
|
Scope: scope,
|
||||||
|
LoginMethod: loginMethod,
|
||||||
|
IssuedAt: time.Now().Unix(),
|
||||||
|
ExpiresAt: time.Now().AddDate(1, 0, 0).Unix(),
|
||||||
|
}
|
||||||
|
fmt.Printf("=> session data %+v\n", fingerPrintMap)
|
||||||
|
fingerPrintBytes, _ := json.Marshal(fingerPrintMap)
|
||||||
|
fingerPrintHash, err := crypto.EncryptAES(string(fingerPrintBytes))
|
||||||
|
if err != nil {
|
||||||
|
return nil, "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return fingerPrintMap, fingerPrintHash, nil
|
||||||
|
}
|
||||||
|
|
||||||
// CreateRefreshToken util to create JWT token
|
// CreateRefreshToken util to create JWT token
|
||||||
func CreateRefreshToken(user models.User, roles, scopes []string, hostname, nonce, loginMethod string) (string, int64, error) {
|
func CreateRefreshToken(user models.User, roles, scopes []string, hostname, nonce, loginMethod string) (string, int64, error) {
|
||||||
// expires in 1 year
|
// expires in 1 year
|
||||||
|
@ -318,7 +353,7 @@ func ValidateBrowserSession(gc *gin.Context, encryptedSession string) (*SessionD
|
||||||
// user information, roles config and CUSTOM_ACCESS_TOKEN_SCRIPT
|
// user information, roles config and CUSTOM_ACCESS_TOKEN_SCRIPT
|
||||||
// For response_type (code) / authorization_code grant nonce should be empty
|
// For response_type (code) / authorization_code grant nonce should be empty
|
||||||
// for implicit flow it should be present to verify with actual state
|
// for implicit flow it should be present to verify with actual state
|
||||||
func CreateIDToken(user models.User, roles []string, hostname, nonce, loginMethod string) (string, int64, error) {
|
func CreateIDToken(user models.User, roles []string, hostname, nonce, atHash, cHash, loginMethod string) (string, int64, error) {
|
||||||
expireTime, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAccessTokenExpiryTime)
|
expireTime, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAccessTokenExpiryTime)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", 0, err
|
return "", 0, err
|
||||||
|
@ -344,10 +379,10 @@ func CreateIDToken(user models.User, roles []string, hostname, nonce, loginMetho
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", 0, err
|
return "", 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
customClaims := jwt.MapClaims{
|
customClaims := jwt.MapClaims{
|
||||||
"iss": hostname,
|
"iss": hostname,
|
||||||
"aud": clientID,
|
"aud": clientID,
|
||||||
// "nonce": nonce,
|
|
||||||
"sub": user.ID,
|
"sub": user.ID,
|
||||||
"exp": expiresAt,
|
"exp": expiresAt,
|
||||||
"iat": time.Now().Unix(),
|
"iat": time.Now().Unix(),
|
||||||
|
@ -357,6 +392,20 @@ func CreateIDToken(user models.User, roles []string, hostname, nonce, loginMetho
|
||||||
claimKey: roles,
|
claimKey: roles,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fmt.Println("=> nonce", nonce)
|
||||||
|
|
||||||
|
// split nonce to see if its authorization code grant method
|
||||||
|
|
||||||
|
if cHash != "" {
|
||||||
|
customClaims["at_hash"] = atHash
|
||||||
|
customClaims["c_hash"] = cHash
|
||||||
|
} else {
|
||||||
|
customClaims["nonce"] = nonce
|
||||||
|
customClaims["at_hash"] = atHash
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("custom_claims", customClaims)
|
||||||
|
|
||||||
for k, v := range userMap {
|
for k, v := range userMap {
|
||||||
if k != "roles" {
|
if k != "roles" {
|
||||||
customClaims[k] = v
|
customClaims[k] = v
|
||||||
|
|
|
@ -7,8 +7,6 @@ import (
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO re-name GinContextKey -> GinContext
|
|
||||||
|
|
||||||
// GinContext to get gin context from context
|
// GinContext to get gin context from context
|
||||||
func GinContextFromContext(ctx context.Context) (*gin.Context, error) {
|
func GinContextFromContext(ctx context.Context) (*gin.Context, error) {
|
||||||
ginContext := ctx.Value("GinContextKey")
|
ginContext := ctx.Value("GinContextKey")
|
||||||
|
|
Loading…
Reference in New Issue
Block a user