diff --git a/app/.prettierrc.json b/app/.prettierrc.json index c9de62a..8eb506e 100644 --- a/app/.prettierrc.json +++ b/app/.prettierrc.json @@ -2,5 +2,5 @@ "tabWidth": 2, "singleQuote": true, "trailingComma": "all", - "useTabs": false + "useTabs": true } diff --git a/app/package-lock.json b/app/package-lock.json index 657df4a..42e0140 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -9,7 +9,7 @@ "version": "1.0.0", "license": "ISC", "dependencies": { - "@authorizerdev/authorizer-react": "^1.1.2", + "@authorizerdev/authorizer-react": "^1.1.3-beta.1", "@types/react": "^17.0.15", "@types/react-dom": "^17.0.9", "esbuild": "^0.12.17", @@ -27,9 +27,9 @@ } }, "node_modules/@authorizerdev/authorizer-js": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-1.1.0.tgz", - "integrity": "sha512-MdEw1SjhIm7pXq20AscHSbnAta2PC3w7GNBY52/OzmlBXUGH3ooUQX/aszbYOse3FlhapcrGrRvg4sNM7faGAg==", + "version": "1.1.2-beta.1", + "resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-1.1.2-beta.1.tgz", + "integrity": "sha512-u+O2iB3tqF1HtdJ6LfBXL9iMycqlCCL3othBQkqitGP1ldhASWLJ2pcXZAcHgyoeczKdj2XKZKdIcWB3GYR0IQ==", "dependencies": { "cross-fetch": "^3.1.5" }, @@ -38,11 +38,11 @@ } }, "node_modules/@authorizerdev/authorizer-react": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-1.1.2.tgz", - "integrity": "sha512-uBmuKnOVX8gp8CEUuGJuz04ep+8qMEzJXWd5leEGKYMIgolHpu/lOinnMUXhjh8YL3pA4+EhvB+hQXxUX+rRHQ==", + "version": "1.1.3-beta.1", + "resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-1.1.3-beta.1.tgz", + "integrity": "sha512-+ZsOBp6XjZVnDyeJCXgaqZ8xzFO7ygpHB6v2cblCKIA3wX5pg/Dsg1oumHGrSHIEK8No/GOtCjSx4Rv6/CweBQ==", "dependencies": { - "@authorizerdev/authorizer-js": "^1.1.0", + "@authorizerdev/authorizer-js": "^1.1.2-beta.1", "final-form": "^4.20.2", "react-final-form": "^6.5.3", "styled-components": "^5.3.0" @@ -876,19 +876,19 @@ }, "dependencies": { "@authorizerdev/authorizer-js": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-1.1.0.tgz", - "integrity": "sha512-MdEw1SjhIm7pXq20AscHSbnAta2PC3w7GNBY52/OzmlBXUGH3ooUQX/aszbYOse3FlhapcrGrRvg4sNM7faGAg==", + "version": "1.1.2-beta.1", + "resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-1.1.2-beta.1.tgz", + "integrity": "sha512-u+O2iB3tqF1HtdJ6LfBXL9iMycqlCCL3othBQkqitGP1ldhASWLJ2pcXZAcHgyoeczKdj2XKZKdIcWB3GYR0IQ==", "requires": { "cross-fetch": "^3.1.5" } }, "@authorizerdev/authorizer-react": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-1.1.2.tgz", - "integrity": "sha512-uBmuKnOVX8gp8CEUuGJuz04ep+8qMEzJXWd5leEGKYMIgolHpu/lOinnMUXhjh8YL3pA4+EhvB+hQXxUX+rRHQ==", + "version": "1.1.3-beta.1", + "resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-1.1.3-beta.1.tgz", + "integrity": "sha512-+ZsOBp6XjZVnDyeJCXgaqZ8xzFO7ygpHB6v2cblCKIA3wX5pg/Dsg1oumHGrSHIEK8No/GOtCjSx4Rv6/CweBQ==", "requires": { - "@authorizerdev/authorizer-js": "^1.1.0", + "@authorizerdev/authorizer-js": "^1.1.2-beta.1", "final-form": "^4.20.2", "react-final-form": "^6.5.3", "styled-components": "^5.3.0" diff --git a/app/package.json b/app/package.json index 07f4063..14c520d 100644 --- a/app/package.json +++ b/app/package.json @@ -6,13 +6,13 @@ "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)'" + "format": "prettier --write 'src/**/*.(ts|tsx|js|jsx)'" }, "keywords": [], "author": "Lakhan Samani", "license": "ISC", "dependencies": { - "@authorizerdev/authorizer-react": "^1.1.2", + "@authorizerdev/authorizer-react": "^1.1.3-beta.1", "@types/react": "^17.0.15", "@types/react-dom": "^17.0.9", "esbuild": "^0.12.17", diff --git a/app/src/Root.tsx b/app/src/Root.tsx index 522e4ca..abffef6 100644 --- a/app/src/Root.tsx +++ b/app/src/Root.tsx @@ -38,8 +38,8 @@ export default function Root({ const scope = searchParams.get('scope') ? searchParams.get('scope')?.toString().split(' ') : ['openid', 'profile', 'email']; - const code = searchParams.get('code') || '' - const nonce = searchParams.get('nonce') || '' + const code = searchParams.get('code') || ''; + const nonce = searchParams.get('nonce') || ''; const urlProps: Record = { state, @@ -57,16 +57,17 @@ export default function Root({ urlProps.redirect_uri = urlProps.redirectURL; useEffect(() => { + console.log(config); if (token) { 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}`; if (code !== '') { - params += `&code=${code}` + params += `&code=${code}`; } if (nonce !== '') { - params += `&nonce=${nonce}` + params += `&nonce=${nonce}`; } if (token.refresh_token) { @@ -86,7 +87,7 @@ export default function Root({ } } return () => {}; - }, [token]); + }, [token, config]); if (loading) { return

Loading...

; diff --git a/dashboard/.prettierrc.json b/dashboard/.prettierrc.json index c9de62a..8eb506e 100644 --- a/dashboard/.prettierrc.json +++ b/dashboard/.prettierrc.json @@ -2,5 +2,5 @@ "tabWidth": 2, "singleQuote": true, "trailingComma": "all", - "useTabs": false + "useTabs": true } diff --git a/server/go.mod b/server/go.mod index ca7f949..fbcf5ab 100644 --- a/server/go.mod +++ b/server/go.mod @@ -7,9 +7,8 @@ require ( github.com/arangodb/go-driver v1.2.1 github.com/aws/aws-sdk-go v1.44.109 github.com/coreos/go-oidc/v3 v3.1.0 - github.com/denisenkom/go-mssqldb v0.11.0 // indirect github.com/gin-gonic/gin v1.8.1 - github.com/glebarez/sqlite v1.5.0 // indirect + github.com/glebarez/sqlite v1.5.0 github.com/go-playground/validator/v10 v10.11.1 // indirect github.com/go-redis/redis/v8 v8.11.0 github.com/goccy/go-json v0.9.11 // indirect @@ -19,7 +18,6 @@ require ( github.com/google/uuid v1.3.0 github.com/guregu/dynamo v1.16.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/pelletier/go-toml/v2 v2.0.5 // indirect github.com/robertkrimen/otto v0.0.0-20211024170158-b87d35c0b86f diff --git a/server/go.sum b/server/go.sum index 3a9f6d3..f1a0545 100644 --- a/server/go.sum +++ b/server/go.sum @@ -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/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= 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/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= -github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY= github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA= github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= @@ -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/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8= github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= -github.com/hashicorp/go-version v1.0.0 h1:21MVWPKDphxa7ineQQTrCU5brh7OuVVAzGOCnnCPtE8= -github.com/hashicorp/go-version v1.0.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= 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.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.10.1 h1:DzdIHIjG1AxGwoEEqS+mGsURyjt4enSmqzACXvVzOT8= -github.com/jackc/pgconn v1.10.1/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI= github.com/jackc/pgconn v1.13.0 h1:3L1XMNV2Zvca/8BYhzcRFS70Lr0WlDg16Di6SFGAbys= github.com/jackc/pgconn v1.13.0/go.mod h1:AnowpAqO4CMIIJNZl2VJp+KrkAZciAkhEl0W0JIobpI= github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE= @@ -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.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.2.0 h1:r7JypeP2D3onoQTCxWdTpCtJ4D+qpKr0TxvoyMhZ5ns= -github.com/jackc/pgproto3/v2 v2.2.0/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgproto3/v2 v2.3.1 h1:nwj7qwf0S+Q7ISFfBndqeLwSwxs+4DPsbRFjECT1Y4Y= github.com/jackc/pgproto3/v2 v2.3.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b h1:C8S2+VttkHFdOOCXJe+YGfa4vHYwlt4Zx+IVXQ97jYg= @@ -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-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.9.0 h1:/SH1RxEtltvJgsDqp3TbiTFApD3mey3iygpuEGeuBXk= -github.com/jackc/pgtype v1.9.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4= github.com/jackc/pgtype v1.12.0 h1:Dlq8Qvcch7kiehm8wPGIW0W3KsCCHJnRacKW0UM8n5w= github.com/jackc/pgtype v1.12.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4= github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y= github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM= github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc= github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs= -github.com/jackc/pgx/v4 v4.14.0 h1:TgdrmgnM7VY72EuSQzBbBd4JA1RLqJolrw9nQVZABVc= -github.com/jackc/pgx/v4 v4.14.0/go.mod h1:jT3ibf/A0ZVCp89rtCIN0zCJxcE74ypROmHEZYsG/j8= github.com/jackc/pgx/v4 v4.17.2 h1:0Ut0rpeKwvIVbMQ1KbMBU4h6wxehBI535LK6Flheh8E= github.com/jackc/pgx/v4 v4.17.2/go.mod h1:lcxIZN44yMIrWI78a5CpucdD14hX0SBDbNRvjDBItsw= github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= -github.com/jackc/puddle v1.2.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.3.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= -github.com/jinzhu/now v1.1.2/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= -github.com/jinzhu/now v1.1.3 h1:PlHq1bSCSZL9K0wUhbm2pGLoTWs2GwVhsP6emvGV/ZI= -github.com/jinzhu/now v1.1.3/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= @@ -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.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-sqlite3 v1.14.9 h1:10HX2Td0ocZpYEjhilsuo6WWtUqttj2Kb0KtD86/KYA= -github.com/mattn/go-sqlite3 v1.14.9/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= -github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI= github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= github.com/microsoft/go-mssqldb v0.17.0 h1:Fto83dMZPnYv1Zwx5vHHxpNraeEaUlQ/hhHLgZiaenE= github.com/microsoft/go-mssqldb v0.17.0/go.mod h1:OkoNGhGEs8EZqchVTtochlXruEhEOaO4S0d2sB5aeGQ= -github.com/mitchellh/gox v1.0.1 h1:x0jD3dcHk9a9xPSDN6YEL4xL6Qz0dvNYm8yZqui5chI= -github.com/mitchellh/gox v1.0.1/go.mod h1:ED6BioOGXMswlXa2zxfh/xdd5QhwYliBFn9V18Ap4z4= -github.com/mitchellh/iochan v1.0.0 h1:C+X3KsSTLFVBr/tK1eYN/vs4rJcvsiLU338UhYPJWeY= -github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v1.3.1 h1:cCBH2gTD2K0OtLlv/Y5H01VQCqmlDxz30kS5Y5bqfLA= github.com/mitchellh/mapstructure v1.3.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -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.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-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-20190510104115-cbcb75029529/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-20220511200225-c6db032c6c88/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be h1:fmw3UbQh+nxngCAHrDCCztao/kbYFnWjoqop8dHx05A= -golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20221005025214-4161e89ecf1b h1:huxqepDufQpLLIRXiVkTvnxrzJlpwmIWAObmcCcUFr0= golang.org/x/crypto v0.0.0-20221005025214-4161e89ecf1b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -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.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gorm.io/driver/mysql v1.2.1 h1:h+3f1l9Ng2C072Y2tIiLgPpWN78r1KXL7bHJ0nTjlhU= -gorm.io/driver/mysql v1.2.1/go.mod h1:qsiz+XcAyMrS6QY+X3M9R6b/lKM1imKmcuK9kac5LTo= gorm.io/driver/mysql v1.4.3 h1:/JhWJhO2v17d8hjApTltKNADm7K7YI2ogkR7avJUL3k= gorm.io/driver/mysql v1.4.3/go.mod h1:sSIebwZAVPiT+27jK9HIwvsqOGKx3YMPmrA3mBJR10c= -gorm.io/driver/postgres v1.2.3 h1:f4t0TmNMy9gh3TU2PX+EppoA6YsgFnyq8Ojtddb42To= -gorm.io/driver/postgres v1.2.3/go.mod h1:pJV6RgYQPG47aM1f0QeOzFH9HxQc8JcmAgjRCgS0wjs= gorm.io/driver/postgres v1.4.5 h1:mTeXTTtHAgnS9PgmhN2YeUbazYpLhUI1doLnw42XUZc= gorm.io/driver/postgres v1.4.5/go.mod h1:GKNQYSJ14qvWkvPwXljMGehpKrhlDNsqYRr5HnYGncg= -gorm.io/driver/sqlite v1.2.6 h1:SStaH/b+280M7C8vXeZLz/zo9cLQmIGwwj3cSj7p6l4= -gorm.io/driver/sqlite v1.2.6/go.mod h1:gyoX0vHiiwi0g49tv+x2E7l8ksauLK0U/gShcdUsjWY= -gorm.io/driver/sqlserver v1.2.1 h1:KhGOjvPX7JZ5hPyQICTJfMuTz88zgJ2lk9bWiHVNHd8= -gorm.io/driver/sqlserver v1.2.1/go.mod h1:nixq0OB3iLXZDiPv6JSOjWuPgpyaRpOIIevYtA4Ulb4= gorm.io/driver/sqlserver v1.4.1 h1:t4r4r6Jam5E6ejqP7N82qAJIJAht27EGT41HyPfXRw0= gorm.io/driver/sqlserver v1.4.1/go.mod h1:DJ4P+MeZbc5rvY58PnmN1Lnyvb5gw5NPzGshHDnJLig= -gorm.io/gorm v1.22.2/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0= -gorm.io/gorm v1.22.3/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0= -gorm.io/gorm v1.22.4 h1:8aPcyEJhY0MAt8aY6Dc524Pn+pO29K+ydu+e/cXSpQM= -gorm.io/gorm v1.22.4/go.mod h1:1aeVC+pe9ZmvKZban/gW4QPra7PRoTEssyc922qCAkk= gorm.io/gorm v1.23.8/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk= -gorm.io/gorm v1.24.0 h1:j/CoiSm6xpRpmzbFJsQHYj+I8bGYWLXVHeYEyyKlF74= gorm.io/gorm v1.24.0/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA= gorm.io/gorm v1.24.1-0.20221019064659-5dd2bb482755/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA= gorm.io/gorm v1.24.1 h1:CgvzRniUdG67hBAzsxDGOAuq4Te1osVMYsa1eQbd4fs= diff --git a/server/graph/generated/generated.go b/server/graph/generated/generated.go index e3286c2..c841b05 100644 --- a/server/graph/generated/generated.go +++ b/server/graph/generated/generated.go @@ -1971,501 +1971,513 @@ scalar Map scalar Any type Pagination { - limit: Int64! - page: Int64! - offset: Int64! - total: Int64! + limit: Int64! + page: Int64! + offset: Int64! + total: Int64! } type Meta { - version: String! - client_id: String! - is_google_login_enabled: Boolean! - is_facebook_login_enabled: Boolean! - is_github_login_enabled: Boolean! - is_linkedin_login_enabled: Boolean! - is_apple_login_enabled: Boolean! - is_twitter_login_enabled: Boolean! - is_email_verification_enabled: Boolean! - is_basic_authentication_enabled: Boolean! - is_magic_link_login_enabled: Boolean! - is_sign_up_enabled: Boolean! - is_strong_password_enabled: Boolean! - is_multi_factor_auth_enabled: Boolean! + version: String! + client_id: String! + is_google_login_enabled: Boolean! + is_facebook_login_enabled: Boolean! + is_github_login_enabled: Boolean! + is_linkedin_login_enabled: Boolean! + is_apple_login_enabled: Boolean! + is_twitter_login_enabled: Boolean! + is_email_verification_enabled: Boolean! + is_basic_authentication_enabled: Boolean! + is_magic_link_login_enabled: Boolean! + is_sign_up_enabled: Boolean! + is_strong_password_enabled: Boolean! + is_multi_factor_auth_enabled: Boolean! } type User { - id: ID! - email: String! - email_verified: Boolean! - signup_methods: String! - given_name: String - family_name: String - middle_name: String - nickname: String - # defaults to email - preferred_username: String - gender: String - birthdate: String - phone_number: String - phone_number_verified: Boolean - picture: String - roles: [String!]! - created_at: Int64 - updated_at: Int64 - revoked_timestamp: Int64 - is_multi_factor_auth_enabled: Boolean + id: ID! + email: String! + email_verified: Boolean! + signup_methods: String! + given_name: String + family_name: String + middle_name: String + nickname: String + # defaults to email + preferred_username: String + gender: String + birthdate: String + phone_number: String + phone_number_verified: Boolean + picture: String + roles: [String!]! + created_at: Int64 + updated_at: Int64 + revoked_timestamp: Int64 + is_multi_factor_auth_enabled: Boolean } type Users { - pagination: Pagination! - users: [User!]! + pagination: Pagination! + users: [User!]! } type VerificationRequest { - id: ID! - identifier: String - token: String - email: String - expires: Int64 - created_at: Int64 - updated_at: Int64 - nonce: String - redirect_uri: String + id: ID! + identifier: String + token: String + email: String + expires: Int64 + created_at: Int64 + updated_at: Int64 + nonce: String + redirect_uri: String } type VerificationRequests { - pagination: Pagination! - verification_requests: [VerificationRequest!]! + pagination: Pagination! + verification_requests: [VerificationRequest!]! } type Error { - message: String! - reason: String! + message: String! + reason: String! } type AuthResponse { - message: String! - should_show_otp_screen: Boolean - access_token: String - id_token: String - refresh_token: String - expires_in: Int64 - user: User + message: String! + should_show_otp_screen: Boolean + access_token: String + id_token: String + refresh_token: String + expires_in: Int64 + user: User } type Response { - message: String! + message: String! } type Env { - ACCESS_TOKEN_EXPIRY_TIME: String - ADMIN_SECRET: String - DATABASE_NAME: String - DATABASE_URL: String - DATABASE_TYPE: String - DATABASE_USERNAME: String - DATABASE_PASSWORD: String - DATABASE_HOST: String - DATABASE_PORT: String - CLIENT_ID: String! - CLIENT_SECRET: String! - CUSTOM_ACCESS_TOKEN_SCRIPT: String - SMTP_HOST: String - SMTP_PORT: String - SMTP_USERNAME: String - SMTP_PASSWORD: String - SMTP_LOCAL_NAME: String - SENDER_EMAIL: String - JWT_TYPE: String - JWT_SECRET: String - JWT_PRIVATE_KEY: String - JWT_PUBLIC_KEY: String - ALLOWED_ORIGINS: [String!] - APP_URL: String - REDIS_URL: String - RESET_PASSWORD_URL: String - DISABLE_EMAIL_VERIFICATION: Boolean! - DISABLE_BASIC_AUTHENTICATION: Boolean! - DISABLE_MAGIC_LINK_LOGIN: Boolean! - DISABLE_LOGIN_PAGE: Boolean! - DISABLE_SIGN_UP: Boolean! - DISABLE_REDIS_FOR_ENV: Boolean! - DISABLE_STRONG_PASSWORD: Boolean! - DISABLE_MULTI_FACTOR_AUTHENTICATION: Boolean! - ENFORCE_MULTI_FACTOR_AUTHENTICATION: Boolean! - ROLES: [String!] - PROTECTED_ROLES: [String!] - DEFAULT_ROLES: [String!] - JWT_ROLE_CLAIM: String - GOOGLE_CLIENT_ID: String - GOOGLE_CLIENT_SECRET: String - GITHUB_CLIENT_ID: String - GITHUB_CLIENT_SECRET: String - FACEBOOK_CLIENT_ID: String - FACEBOOK_CLIENT_SECRET: String - LINKEDIN_CLIENT_ID: String - LINKEDIN_CLIENT_SECRET: String - APPLE_CLIENT_ID: String - APPLE_CLIENT_SECRET: String - TWITTER_CLIENT_ID: String - TWITTER_CLIENT_SECRET: String - ORGANIZATION_NAME: String - ORGANIZATION_LOGO: String - APP_COOKIE_SECURE: Boolean! - ADMIN_COOKIE_SECURE: Boolean! + ACCESS_TOKEN_EXPIRY_TIME: String + ADMIN_SECRET: String + DATABASE_NAME: String + DATABASE_URL: String + DATABASE_TYPE: String + DATABASE_USERNAME: String + DATABASE_PASSWORD: String + DATABASE_HOST: String + DATABASE_PORT: String + CLIENT_ID: String! + CLIENT_SECRET: String! + CUSTOM_ACCESS_TOKEN_SCRIPT: String + SMTP_HOST: String + SMTP_PORT: String + SMTP_USERNAME: String + SMTP_PASSWORD: String + SMTP_LOCAL_NAME: String + SENDER_EMAIL: String + JWT_TYPE: String + JWT_SECRET: String + JWT_PRIVATE_KEY: String + JWT_PUBLIC_KEY: String + ALLOWED_ORIGINS: [String!] + APP_URL: String + REDIS_URL: String + RESET_PASSWORD_URL: String + DISABLE_EMAIL_VERIFICATION: Boolean! + DISABLE_BASIC_AUTHENTICATION: Boolean! + DISABLE_MAGIC_LINK_LOGIN: Boolean! + DISABLE_LOGIN_PAGE: Boolean! + DISABLE_SIGN_UP: Boolean! + DISABLE_REDIS_FOR_ENV: Boolean! + DISABLE_STRONG_PASSWORD: Boolean! + DISABLE_MULTI_FACTOR_AUTHENTICATION: Boolean! + ENFORCE_MULTI_FACTOR_AUTHENTICATION: Boolean! + ROLES: [String!] + PROTECTED_ROLES: [String!] + DEFAULT_ROLES: [String!] + JWT_ROLE_CLAIM: String + GOOGLE_CLIENT_ID: String + GOOGLE_CLIENT_SECRET: String + GITHUB_CLIENT_ID: String + GITHUB_CLIENT_SECRET: String + FACEBOOK_CLIENT_ID: String + FACEBOOK_CLIENT_SECRET: String + LINKEDIN_CLIENT_ID: String + LINKEDIN_CLIENT_SECRET: String + APPLE_CLIENT_ID: String + APPLE_CLIENT_SECRET: String + TWITTER_CLIENT_ID: String + TWITTER_CLIENT_SECRET: String + ORGANIZATION_NAME: String + ORGANIZATION_LOGO: String + APP_COOKIE_SECURE: Boolean! + ADMIN_COOKIE_SECURE: Boolean! } type ValidateJWTTokenResponse { - is_valid: Boolean! - claims: Map + is_valid: Boolean! + claims: Map } type GenerateJWTKeysResponse { - secret: String - public_key: String - private_key: String + secret: String + public_key: String + private_key: String } type Webhook { - id: ID! - event_name: String - endpoint: String - enabled: Boolean - headers: Map - created_at: Int64 - updated_at: Int64 + id: ID! + event_name: String + endpoint: String + enabled: Boolean + headers: Map + created_at: Int64 + updated_at: Int64 } type Webhooks { - pagination: Pagination! - webhooks: [Webhook!]! + pagination: Pagination! + webhooks: [Webhook!]! } type WebhookLog { - id: ID! - http_status: Int64 - response: String - request: String - webhook_id: ID - created_at: Int64 - updated_at: Int64 + id: ID! + http_status: Int64 + response: String + request: String + webhook_id: ID + created_at: Int64 + updated_at: Int64 } type TestEndpointResponse { - http_status: Int64 - response: String + http_status: Int64 + response: String } type WebhookLogs { - pagination: Pagination! - webhook_logs: [WebhookLog!]! + pagination: Pagination! + webhook_logs: [WebhookLog!]! } type EmailTemplate { - id: ID! - event_name: String! - template: String! - design: String! - subject: String! - created_at: Int64 - updated_at: Int64 + id: ID! + event_name: String! + template: String! + design: String! + subject: String! + created_at: Int64 + updated_at: Int64 } type EmailTemplates { - pagination: Pagination! - email_templates: [EmailTemplate!]! + pagination: Pagination! + email_templates: [EmailTemplate!]! } input UpdateEnvInput { - ACCESS_TOKEN_EXPIRY_TIME: String - ADMIN_SECRET: String - CUSTOM_ACCESS_TOKEN_SCRIPT: String - OLD_ADMIN_SECRET: String - SMTP_HOST: String - SMTP_PORT: String - SMTP_USERNAME: String - SMTP_PASSWORD: String - SMTP_LOCAL_NAME: String - SENDER_EMAIL: String - JWT_TYPE: String - JWT_SECRET: String - JWT_PRIVATE_KEY: String - JWT_PUBLIC_KEY: String - ALLOWED_ORIGINS: [String!] - APP_URL: String - RESET_PASSWORD_URL: String - APP_COOKIE_SECURE: Boolean - ADMIN_COOKIE_SECURE: Boolean - DISABLE_EMAIL_VERIFICATION: Boolean - DISABLE_BASIC_AUTHENTICATION: Boolean - DISABLE_MAGIC_LINK_LOGIN: Boolean - DISABLE_LOGIN_PAGE: Boolean - DISABLE_SIGN_UP: Boolean - DISABLE_REDIS_FOR_ENV: Boolean - DISABLE_STRONG_PASSWORD: Boolean - DISABLE_MULTI_FACTOR_AUTHENTICATION: Boolean - ENFORCE_MULTI_FACTOR_AUTHENTICATION: Boolean - ROLES: [String!] - PROTECTED_ROLES: [String!] - DEFAULT_ROLES: [String!] - JWT_ROLE_CLAIM: String - GOOGLE_CLIENT_ID: String - GOOGLE_CLIENT_SECRET: String - GITHUB_CLIENT_ID: String - GITHUB_CLIENT_SECRET: String - FACEBOOK_CLIENT_ID: String - FACEBOOK_CLIENT_SECRET: String - LINKEDIN_CLIENT_ID: String - LINKEDIN_CLIENT_SECRET: String - APPLE_CLIENT_ID: String - APPLE_CLIENT_SECRET: String - TWITTER_CLIENT_ID: String - TWITTER_CLIENT_SECRET: String - ORGANIZATION_NAME: String - ORGANIZATION_LOGO: String + ACCESS_TOKEN_EXPIRY_TIME: String + ADMIN_SECRET: String + CUSTOM_ACCESS_TOKEN_SCRIPT: String + OLD_ADMIN_SECRET: String + SMTP_HOST: String + SMTP_PORT: String + SMTP_USERNAME: String + SMTP_PASSWORD: String + SMTP_LOCAL_NAME: String + SENDER_EMAIL: String + JWT_TYPE: String + JWT_SECRET: String + JWT_PRIVATE_KEY: String + JWT_PUBLIC_KEY: String + ALLOWED_ORIGINS: [String!] + APP_URL: String + RESET_PASSWORD_URL: String + APP_COOKIE_SECURE: Boolean + ADMIN_COOKIE_SECURE: Boolean + DISABLE_EMAIL_VERIFICATION: Boolean + DISABLE_BASIC_AUTHENTICATION: Boolean + DISABLE_MAGIC_LINK_LOGIN: Boolean + DISABLE_LOGIN_PAGE: Boolean + DISABLE_SIGN_UP: Boolean + DISABLE_REDIS_FOR_ENV: Boolean + DISABLE_STRONG_PASSWORD: Boolean + DISABLE_MULTI_FACTOR_AUTHENTICATION: Boolean + ENFORCE_MULTI_FACTOR_AUTHENTICATION: Boolean + ROLES: [String!] + PROTECTED_ROLES: [String!] + DEFAULT_ROLES: [String!] + JWT_ROLE_CLAIM: String + GOOGLE_CLIENT_ID: String + GOOGLE_CLIENT_SECRET: String + GITHUB_CLIENT_ID: String + GITHUB_CLIENT_SECRET: String + FACEBOOK_CLIENT_ID: String + FACEBOOK_CLIENT_SECRET: String + LINKEDIN_CLIENT_ID: String + LINKEDIN_CLIENT_SECRET: String + APPLE_CLIENT_ID: String + APPLE_CLIENT_SECRET: String + TWITTER_CLIENT_ID: String + TWITTER_CLIENT_SECRET: String + ORGANIZATION_NAME: String + ORGANIZATION_LOGO: String } input AdminLoginInput { - admin_secret: String! + admin_secret: String! } input AdminSignupInput { - admin_secret: String! + admin_secret: String! } input SignUpInput { - email: String! - given_name: String - family_name: String - middle_name: String - nickname: String - gender: String - birthdate: String - phone_number: String - picture: String - password: String! - confirm_password: String! - roles: [String!] - scope: [String!] - redirect_uri: String - is_multi_factor_auth_enabled: Boolean + email: String! + given_name: String + family_name: String + middle_name: String + nickname: String + gender: String + birthdate: String + phone_number: String + picture: String + password: String! + confirm_password: String! + roles: [String!] + scope: [String!] + redirect_uri: String + is_multi_factor_auth_enabled: Boolean + # 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 { - email: String! - password: String! - roles: [String!] - scope: [String!] + email: String! + password: String! + roles: [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 { - 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 { - email: String! - identifier: String! + email: String! + identifier: String! } input UpdateProfileInput { - old_password: String - new_password: String - confirm_new_password: String - email: String - given_name: String - family_name: String - middle_name: String - nickname: String - gender: String - birthdate: String - phone_number: String - picture: String - is_multi_factor_auth_enabled: Boolean + old_password: String + new_password: String + confirm_new_password: String + email: String + given_name: String + family_name: String + middle_name: String + nickname: String + gender: String + birthdate: String + phone_number: String + picture: String + is_multi_factor_auth_enabled: Boolean } input UpdateUserInput { - id: ID! - email: String - email_verified: Boolean - given_name: String - family_name: String - middle_name: String - nickname: String - gender: String - birthdate: String - phone_number: String - picture: String - roles: [String] - is_multi_factor_auth_enabled: Boolean + id: ID! + email: String + email_verified: Boolean + given_name: String + family_name: String + middle_name: String + nickname: String + gender: String + birthdate: String + phone_number: String + picture: String + roles: [String] + is_multi_factor_auth_enabled: Boolean } input ForgotPasswordInput { - email: String! - state: String - redirect_uri: String + email: String! + state: String + redirect_uri: String } input ResetPasswordInput { - token: String! - password: String! - confirm_password: String! + token: String! + password: String! + confirm_password: String! } input DeleteUserInput { - email: String! + email: String! } input MagicLinkLoginInput { - email: String! - roles: [String!] - scope: [String!] - state: String - redirect_uri: String + email: String! + roles: [String!] + scope: [String!] + state: String + redirect_uri: String } input SessionQueryInput { - roles: [String!] - scope: [String!] + roles: [String!] + scope: [String!] } input PaginationInput { - limit: Int64 - page: Int64 + limit: Int64 + page: Int64 } input PaginatedInput { - pagination: PaginationInput + pagination: PaginationInput } input OAuthRevokeInput { - refresh_token: String! + refresh_token: String! } input InviteMemberInput { - emails: [String!]! - redirect_uri: String + emails: [String!]! + redirect_uri: String } input UpdateAccessInput { - user_id: String! + user_id: String! } input ValidateJWTTokenInput { - token_type: String! - token: String! - roles: [String!] + token_type: String! + token: String! + roles: [String!] } input GenerateJWTKeysInput { - type: String! + type: String! } input ListWebhookLogRequest { - pagination: PaginationInput - webhook_id: String + pagination: PaginationInput + webhook_id: String } input AddWebhookRequest { - event_name: String! - endpoint: String! - enabled: Boolean! - headers: Map + event_name: String! + endpoint: String! + enabled: Boolean! + headers: Map } input UpdateWebhookRequest { - id: ID! - event_name: String - endpoint: String - enabled: Boolean - headers: Map + id: ID! + event_name: String + endpoint: String + enabled: Boolean + headers: Map } input WebhookRequest { - id: ID! + id: ID! } input TestEndpointRequest { - endpoint: String! - event_name: String! - headers: Map + endpoint: String! + event_name: String! + headers: Map } input AddEmailTemplateRequest { - event_name: String! - subject: String! - template: String! - design: String! + event_name: String! + subject: String! + template: String! + design: String! } input UpdateEmailTemplateRequest { - id: ID! - event_name: String - template: String - subject: String - design: String + id: ID! + event_name: String + template: String + subject: String + design: String } input DeleteEmailTemplateRequest { - id: ID! + id: ID! } input VerifyOTPRequest { - email: String! - otp: String! + email: String! + otp: String! } input ResendOTPRequest { - email: String! + email: String! } type Mutation { - signup(params: SignUpInput!): AuthResponse! - login(params: LoginInput!): AuthResponse! - magic_link_login(params: MagicLinkLoginInput!): Response! - logout: Response! - update_profile(params: UpdateProfileInput!): Response! - verify_email(params: VerifyEmailInput!): AuthResponse! - resend_verify_email(params: ResendVerifyEmailInput!): Response! - forgot_password(params: ForgotPasswordInput!): Response! - reset_password(params: ResetPasswordInput!): Response! - revoke(params: OAuthRevokeInput!): Response! - verify_otp(params: VerifyOTPRequest!): AuthResponse! - resend_otp(params: ResendOTPRequest!): Response! - # admin only apis - _delete_user(params: DeleteUserInput!): Response! - _update_user(params: UpdateUserInput!): User! - _admin_signup(params: AdminSignupInput!): Response! - _admin_login(params: AdminLoginInput!): Response! - _admin_logout: Response! - _update_env(params: UpdateEnvInput!): Response! - _invite_members(params: InviteMemberInput!): Response! - _revoke_access(param: UpdateAccessInput!): Response! - _enable_access(param: UpdateAccessInput!): Response! - _generate_jwt_keys(params: GenerateJWTKeysInput!): GenerateJWTKeysResponse! - _add_webhook(params: AddWebhookRequest!): Response! - _update_webhook(params: UpdateWebhookRequest!): Response! - _delete_webhook(params: WebhookRequest!): Response! - _test_endpoint(params: TestEndpointRequest!): TestEndpointResponse! - _add_email_template(params: AddEmailTemplateRequest!): Response! - _update_email_template(params: UpdateEmailTemplateRequest!): Response! - _delete_email_template(params: DeleteEmailTemplateRequest!): Response! + signup(params: SignUpInput!): AuthResponse! + login(params: LoginInput!): AuthResponse! + magic_link_login(params: MagicLinkLoginInput!): Response! + logout: Response! + update_profile(params: UpdateProfileInput!): Response! + verify_email(params: VerifyEmailInput!): AuthResponse! + resend_verify_email(params: ResendVerifyEmailInput!): Response! + forgot_password(params: ForgotPasswordInput!): Response! + reset_password(params: ResetPasswordInput!): Response! + revoke(params: OAuthRevokeInput!): Response! + verify_otp(params: VerifyOTPRequest!): AuthResponse! + resend_otp(params: ResendOTPRequest!): Response! + # admin only apis + _delete_user(params: DeleteUserInput!): Response! + _update_user(params: UpdateUserInput!): User! + _admin_signup(params: AdminSignupInput!): Response! + _admin_login(params: AdminLoginInput!): Response! + _admin_logout: Response! + _update_env(params: UpdateEnvInput!): Response! + _invite_members(params: InviteMemberInput!): Response! + _revoke_access(param: UpdateAccessInput!): Response! + _enable_access(param: UpdateAccessInput!): Response! + _generate_jwt_keys(params: GenerateJWTKeysInput!): GenerateJWTKeysResponse! + _add_webhook(params: AddWebhookRequest!): Response! + _update_webhook(params: UpdateWebhookRequest!): Response! + _delete_webhook(params: WebhookRequest!): Response! + _test_endpoint(params: TestEndpointRequest!): TestEndpointResponse! + _add_email_template(params: AddEmailTemplateRequest!): Response! + _update_email_template(params: UpdateEmailTemplateRequest!): Response! + _delete_email_template(params: DeleteEmailTemplateRequest!): Response! } type Query { - meta: Meta! - session(params: SessionQueryInput): AuthResponse! - profile: User! - validate_jwt_token(params: ValidateJWTTokenInput!): ValidateJWTTokenResponse! - # admin only apis - _users(params: PaginatedInput): Users! - _verification_requests(params: PaginatedInput): VerificationRequests! - _admin_session: Response! - _env: Env! - _webhook(params: WebhookRequest!): Webhook! - _webhooks(params: PaginatedInput): Webhooks! - _webhook_logs(params: ListWebhookLogRequest): WebhookLogs! - _email_templates(params: PaginatedInput): EmailTemplates! + meta: Meta! + session(params: SessionQueryInput): AuthResponse! + profile: User! + validate_jwt_token(params: ValidateJWTTokenInput!): ValidateJWTTokenResponse! + # admin only apis + _users(params: PaginatedInput): Users! + _verification_requests(params: PaginatedInput): VerificationRequests! + _admin_session: Response! + _env: Env! + _webhook(params: WebhookRequest!): Webhook! + _webhooks(params: PaginatedInput): Webhooks! + _webhook_logs(params: ListWebhookLogRequest): WebhookLogs! + _email_templates(params: PaginatedInput): EmailTemplates! } `, BuiltIn: false}, } @@ -14455,7 +14467,7 @@ func (ec *executionContext) unmarshalInputLoginInput(ctx context.Context, obj in asMap[k] = v } - fieldsInOrder := [...]string{"email", "password", "roles", "scope"} + fieldsInOrder := [...]string{"email", "password", "roles", "scope", "state"} for _, k := range fieldsInOrder { v, ok := asMap[k] if !ok { @@ -14494,6 +14506,14 @@ func (ec *executionContext) unmarshalInputLoginInput(ctx context.Context, obj in if err != nil { 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 } - 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 { v, ok := asMap[k] if !ok { @@ -14930,6 +14950,14 @@ func (ec *executionContext) unmarshalInputSignUpInput(ctx context.Context, obj i if err != nil { 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 } - fieldsInOrder := [...]string{"token"} + fieldsInOrder := [...]string{"token", "state"} for _, k := range fieldsInOrder { v, ok := asMap[k] if !ok { @@ -15830,6 +15858,14 @@ func (ec *executionContext) unmarshalInputVerifyEmailInput(ctx context.Context, if err != nil { 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 + } } } diff --git a/server/graph/model/models_gen.go b/server/graph/model/models_gen.go index b4e33fb..1fe5db6 100644 --- a/server/graph/model/models_gen.go +++ b/server/graph/model/models_gen.go @@ -151,6 +151,7 @@ type LoginInput struct { Password string `json:"password"` Roles []string `json:"roles"` Scope []string `json:"scope"` + State *string `json:"state"` } type MagicLinkLoginInput struct { @@ -238,6 +239,7 @@ type SignUpInput struct { Scope []string `json:"scope"` RedirectURI *string `json:"redirect_uri"` IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled"` + State *string `json:"state"` } type TestEndpointRequest struct { @@ -408,7 +410,8 @@ type VerificationRequests struct { } type VerifyEmailInput struct { - Token string `json:"token"` + Token string `json:"token"` + State *string `json:"state"` } type VerifyOTPRequest struct { diff --git a/server/graph/schema.graphqls b/server/graph/schema.graphqls index b73df14..135c7e8 100644 --- a/server/graph/schema.graphqls +++ b/server/graph/schema.graphqls @@ -6,499 +6,523 @@ scalar Map scalar Any type Pagination { - limit: Int64! - page: Int64! - offset: Int64! - total: Int64! + limit: Int64! + page: Int64! + offset: Int64! + total: Int64! } type Meta { - version: String! - client_id: String! - is_google_login_enabled: Boolean! - is_facebook_login_enabled: Boolean! - is_github_login_enabled: Boolean! - is_linkedin_login_enabled: Boolean! - is_apple_login_enabled: Boolean! - is_twitter_login_enabled: Boolean! - is_email_verification_enabled: Boolean! - is_basic_authentication_enabled: Boolean! - is_magic_link_login_enabled: Boolean! - is_sign_up_enabled: Boolean! - is_strong_password_enabled: Boolean! - is_multi_factor_auth_enabled: Boolean! + version: String! + client_id: String! + is_google_login_enabled: Boolean! + is_facebook_login_enabled: Boolean! + is_github_login_enabled: Boolean! + is_linkedin_login_enabled: Boolean! + is_apple_login_enabled: Boolean! + is_twitter_login_enabled: Boolean! + is_email_verification_enabled: Boolean! + is_basic_authentication_enabled: Boolean! + is_magic_link_login_enabled: Boolean! + is_sign_up_enabled: Boolean! + is_strong_password_enabled: Boolean! + is_multi_factor_auth_enabled: Boolean! } type User { - id: ID! - email: String! - email_verified: Boolean! - signup_methods: String! - given_name: String - family_name: String - middle_name: String - nickname: String - # defaults to email - preferred_username: String - gender: String - birthdate: String - phone_number: String - phone_number_verified: Boolean - picture: String - roles: [String!]! - created_at: Int64 - updated_at: Int64 - revoked_timestamp: Int64 - is_multi_factor_auth_enabled: Boolean + id: ID! + email: String! + email_verified: Boolean! + signup_methods: String! + given_name: String + family_name: String + middle_name: String + nickname: String + # defaults to email + preferred_username: String + gender: String + birthdate: String + phone_number: String + phone_number_verified: Boolean + picture: String + roles: [String!]! + created_at: Int64 + updated_at: Int64 + revoked_timestamp: Int64 + is_multi_factor_auth_enabled: Boolean } type Users { - pagination: Pagination! - users: [User!]! + pagination: Pagination! + users: [User!]! } type VerificationRequest { - id: ID! - identifier: String - token: String - email: String - expires: Int64 - created_at: Int64 - updated_at: Int64 - nonce: String - redirect_uri: String + id: ID! + identifier: String + token: String + email: String + expires: Int64 + created_at: Int64 + updated_at: Int64 + nonce: String + redirect_uri: String } type VerificationRequests { - pagination: Pagination! - verification_requests: [VerificationRequest!]! + pagination: Pagination! + verification_requests: [VerificationRequest!]! } type Error { - message: String! - reason: String! + message: String! + reason: String! } type AuthResponse { - message: String! - should_show_otp_screen: Boolean - access_token: String - id_token: String - refresh_token: String - expires_in: Int64 - user: User + message: String! + should_show_otp_screen: Boolean + access_token: String + id_token: String + refresh_token: String + expires_in: Int64 + user: User } type Response { - message: String! + message: String! } type Env { - ACCESS_TOKEN_EXPIRY_TIME: String - ADMIN_SECRET: String - DATABASE_NAME: String - DATABASE_URL: String - DATABASE_TYPE: String - DATABASE_USERNAME: String - DATABASE_PASSWORD: String - DATABASE_HOST: String - DATABASE_PORT: String - CLIENT_ID: String! - CLIENT_SECRET: String! - CUSTOM_ACCESS_TOKEN_SCRIPT: String - SMTP_HOST: String - SMTP_PORT: String - SMTP_USERNAME: String - SMTP_PASSWORD: String - SMTP_LOCAL_NAME: String - SENDER_EMAIL: String - JWT_TYPE: String - JWT_SECRET: String - JWT_PRIVATE_KEY: String - JWT_PUBLIC_KEY: String - ALLOWED_ORIGINS: [String!] - APP_URL: String - REDIS_URL: String - RESET_PASSWORD_URL: String - DISABLE_EMAIL_VERIFICATION: Boolean! - DISABLE_BASIC_AUTHENTICATION: Boolean! - DISABLE_MAGIC_LINK_LOGIN: Boolean! - DISABLE_LOGIN_PAGE: Boolean! - DISABLE_SIGN_UP: Boolean! - DISABLE_REDIS_FOR_ENV: Boolean! - DISABLE_STRONG_PASSWORD: Boolean! - DISABLE_MULTI_FACTOR_AUTHENTICATION: Boolean! - ENFORCE_MULTI_FACTOR_AUTHENTICATION: Boolean! - ROLES: [String!] - PROTECTED_ROLES: [String!] - DEFAULT_ROLES: [String!] - JWT_ROLE_CLAIM: String - GOOGLE_CLIENT_ID: String - GOOGLE_CLIENT_SECRET: String - GITHUB_CLIENT_ID: String - GITHUB_CLIENT_SECRET: String - FACEBOOK_CLIENT_ID: String - FACEBOOK_CLIENT_SECRET: String - LINKEDIN_CLIENT_ID: String - LINKEDIN_CLIENT_SECRET: String - APPLE_CLIENT_ID: String - APPLE_CLIENT_SECRET: String - TWITTER_CLIENT_ID: String - TWITTER_CLIENT_SECRET: String - ORGANIZATION_NAME: String - ORGANIZATION_LOGO: String - APP_COOKIE_SECURE: Boolean! - ADMIN_COOKIE_SECURE: Boolean! + ACCESS_TOKEN_EXPIRY_TIME: String + ADMIN_SECRET: String + DATABASE_NAME: String + DATABASE_URL: String + DATABASE_TYPE: String + DATABASE_USERNAME: String + DATABASE_PASSWORD: String + DATABASE_HOST: String + DATABASE_PORT: String + CLIENT_ID: String! + CLIENT_SECRET: String! + CUSTOM_ACCESS_TOKEN_SCRIPT: String + SMTP_HOST: String + SMTP_PORT: String + SMTP_USERNAME: String + SMTP_PASSWORD: String + SMTP_LOCAL_NAME: String + SENDER_EMAIL: String + JWT_TYPE: String + JWT_SECRET: String + JWT_PRIVATE_KEY: String + JWT_PUBLIC_KEY: String + ALLOWED_ORIGINS: [String!] + APP_URL: String + REDIS_URL: String + RESET_PASSWORD_URL: String + DISABLE_EMAIL_VERIFICATION: Boolean! + DISABLE_BASIC_AUTHENTICATION: Boolean! + DISABLE_MAGIC_LINK_LOGIN: Boolean! + DISABLE_LOGIN_PAGE: Boolean! + DISABLE_SIGN_UP: Boolean! + DISABLE_REDIS_FOR_ENV: Boolean! + DISABLE_STRONG_PASSWORD: Boolean! + DISABLE_MULTI_FACTOR_AUTHENTICATION: Boolean! + ENFORCE_MULTI_FACTOR_AUTHENTICATION: Boolean! + ROLES: [String!] + PROTECTED_ROLES: [String!] + DEFAULT_ROLES: [String!] + JWT_ROLE_CLAIM: String + GOOGLE_CLIENT_ID: String + GOOGLE_CLIENT_SECRET: String + GITHUB_CLIENT_ID: String + GITHUB_CLIENT_SECRET: String + FACEBOOK_CLIENT_ID: String + FACEBOOK_CLIENT_SECRET: String + LINKEDIN_CLIENT_ID: String + LINKEDIN_CLIENT_SECRET: String + APPLE_CLIENT_ID: String + APPLE_CLIENT_SECRET: String + TWITTER_CLIENT_ID: String + TWITTER_CLIENT_SECRET: String + ORGANIZATION_NAME: String + ORGANIZATION_LOGO: String + APP_COOKIE_SECURE: Boolean! + ADMIN_COOKIE_SECURE: Boolean! } type ValidateJWTTokenResponse { - is_valid: Boolean! - claims: Map + is_valid: Boolean! + claims: Map } type GenerateJWTKeysResponse { - secret: String - public_key: String - private_key: String + secret: String + public_key: String + private_key: String } type Webhook { - id: ID! - event_name: String - endpoint: String - enabled: Boolean - headers: Map - created_at: Int64 - updated_at: Int64 + id: ID! + event_name: String + endpoint: String + enabled: Boolean + headers: Map + created_at: Int64 + updated_at: Int64 } type Webhooks { - pagination: Pagination! - webhooks: [Webhook!]! + pagination: Pagination! + webhooks: [Webhook!]! } type WebhookLog { - id: ID! - http_status: Int64 - response: String - request: String - webhook_id: ID - created_at: Int64 - updated_at: Int64 + id: ID! + http_status: Int64 + response: String + request: String + webhook_id: ID + created_at: Int64 + updated_at: Int64 } type TestEndpointResponse { - http_status: Int64 - response: String + http_status: Int64 + response: String } type WebhookLogs { - pagination: Pagination! - webhook_logs: [WebhookLog!]! + pagination: Pagination! + webhook_logs: [WebhookLog!]! } type EmailTemplate { - id: ID! - event_name: String! - template: String! - design: String! - subject: String! - created_at: Int64 - updated_at: Int64 + id: ID! + event_name: String! + template: String! + design: String! + subject: String! + created_at: Int64 + updated_at: Int64 } type EmailTemplates { - pagination: Pagination! - email_templates: [EmailTemplate!]! + pagination: Pagination! + email_templates: [EmailTemplate!]! } input UpdateEnvInput { - ACCESS_TOKEN_EXPIRY_TIME: String - ADMIN_SECRET: String - CUSTOM_ACCESS_TOKEN_SCRIPT: String - OLD_ADMIN_SECRET: String - SMTP_HOST: String - SMTP_PORT: String - SMTP_USERNAME: String - SMTP_PASSWORD: String - SMTP_LOCAL_NAME: String - SENDER_EMAIL: String - JWT_TYPE: String - JWT_SECRET: String - JWT_PRIVATE_KEY: String - JWT_PUBLIC_KEY: String - ALLOWED_ORIGINS: [String!] - APP_URL: String - RESET_PASSWORD_URL: String - APP_COOKIE_SECURE: Boolean - ADMIN_COOKIE_SECURE: Boolean - DISABLE_EMAIL_VERIFICATION: Boolean - DISABLE_BASIC_AUTHENTICATION: Boolean - DISABLE_MAGIC_LINK_LOGIN: Boolean - DISABLE_LOGIN_PAGE: Boolean - DISABLE_SIGN_UP: Boolean - DISABLE_REDIS_FOR_ENV: Boolean - DISABLE_STRONG_PASSWORD: Boolean - DISABLE_MULTI_FACTOR_AUTHENTICATION: Boolean - ENFORCE_MULTI_FACTOR_AUTHENTICATION: Boolean - ROLES: [String!] - PROTECTED_ROLES: [String!] - DEFAULT_ROLES: [String!] - JWT_ROLE_CLAIM: String - GOOGLE_CLIENT_ID: String - GOOGLE_CLIENT_SECRET: String - GITHUB_CLIENT_ID: String - GITHUB_CLIENT_SECRET: String - FACEBOOK_CLIENT_ID: String - FACEBOOK_CLIENT_SECRET: String - LINKEDIN_CLIENT_ID: String - LINKEDIN_CLIENT_SECRET: String - APPLE_CLIENT_ID: String - APPLE_CLIENT_SECRET: String - TWITTER_CLIENT_ID: String - TWITTER_CLIENT_SECRET: String - ORGANIZATION_NAME: String - ORGANIZATION_LOGO: String + ACCESS_TOKEN_EXPIRY_TIME: String + ADMIN_SECRET: String + CUSTOM_ACCESS_TOKEN_SCRIPT: String + OLD_ADMIN_SECRET: String + SMTP_HOST: String + SMTP_PORT: String + SMTP_USERNAME: String + SMTP_PASSWORD: String + SMTP_LOCAL_NAME: String + SENDER_EMAIL: String + JWT_TYPE: String + JWT_SECRET: String + JWT_PRIVATE_KEY: String + JWT_PUBLIC_KEY: String + ALLOWED_ORIGINS: [String!] + APP_URL: String + RESET_PASSWORD_URL: String + APP_COOKIE_SECURE: Boolean + ADMIN_COOKIE_SECURE: Boolean + DISABLE_EMAIL_VERIFICATION: Boolean + DISABLE_BASIC_AUTHENTICATION: Boolean + DISABLE_MAGIC_LINK_LOGIN: Boolean + DISABLE_LOGIN_PAGE: Boolean + DISABLE_SIGN_UP: Boolean + DISABLE_REDIS_FOR_ENV: Boolean + DISABLE_STRONG_PASSWORD: Boolean + DISABLE_MULTI_FACTOR_AUTHENTICATION: Boolean + ENFORCE_MULTI_FACTOR_AUTHENTICATION: Boolean + ROLES: [String!] + PROTECTED_ROLES: [String!] + DEFAULT_ROLES: [String!] + JWT_ROLE_CLAIM: String + GOOGLE_CLIENT_ID: String + GOOGLE_CLIENT_SECRET: String + GITHUB_CLIENT_ID: String + GITHUB_CLIENT_SECRET: String + FACEBOOK_CLIENT_ID: String + FACEBOOK_CLIENT_SECRET: String + LINKEDIN_CLIENT_ID: String + LINKEDIN_CLIENT_SECRET: String + APPLE_CLIENT_ID: String + APPLE_CLIENT_SECRET: String + TWITTER_CLIENT_ID: String + TWITTER_CLIENT_SECRET: String + ORGANIZATION_NAME: String + ORGANIZATION_LOGO: String } input AdminLoginInput { - admin_secret: String! + admin_secret: String! } input AdminSignupInput { - admin_secret: String! + admin_secret: String! } input SignUpInput { - email: String! - given_name: String - family_name: String - middle_name: String - nickname: String - gender: String - birthdate: String - phone_number: String - picture: String - password: String! - confirm_password: String! - roles: [String!] - scope: [String!] - redirect_uri: String - is_multi_factor_auth_enabled: Boolean + email: String! + given_name: String + family_name: String + middle_name: String + nickname: String + gender: String + birthdate: String + phone_number: String + picture: String + password: String! + confirm_password: String! + roles: [String!] + scope: [String!] + redirect_uri: String + is_multi_factor_auth_enabled: Boolean + # 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 { - email: String! - password: String! - roles: [String!] - scope: [String!] + email: String! + password: String! + roles: [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 { - 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 { - email: String! - identifier: String! + email: 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 { - old_password: String - new_password: String - confirm_new_password: String - email: String - given_name: String - family_name: String - middle_name: String - nickname: String - gender: String - birthdate: String - phone_number: String - picture: String - is_multi_factor_auth_enabled: Boolean + old_password: String + new_password: String + confirm_new_password: String + email: String + given_name: String + family_name: String + middle_name: String + nickname: String + gender: String + birthdate: String + phone_number: String + picture: String + is_multi_factor_auth_enabled: Boolean } input UpdateUserInput { - id: ID! - email: String - email_verified: Boolean - given_name: String - family_name: String - middle_name: String - nickname: String - gender: String - birthdate: String - phone_number: String - picture: String - roles: [String] - is_multi_factor_auth_enabled: Boolean + id: ID! + email: String + email_verified: Boolean + given_name: String + family_name: String + middle_name: String + nickname: String + gender: String + birthdate: String + phone_number: String + picture: String + roles: [String] + is_multi_factor_auth_enabled: Boolean } input ForgotPasswordInput { - email: String! - state: String - redirect_uri: String + email: String! + state: String + redirect_uri: String } input ResetPasswordInput { - token: String! - password: String! - confirm_password: String! + token: String! + password: String! + confirm_password: String! } input DeleteUserInput { - email: String! + email: String! } input MagicLinkLoginInput { - email: String! - roles: [String!] - scope: [String!] - state: String - redirect_uri: String + email: String! + roles: [String!] + scope: [String!] + state: String + redirect_uri: String } input SessionQueryInput { - roles: [String!] - scope: [String!] + roles: [String!] + scope: [String!] } input PaginationInput { - limit: Int64 - page: Int64 + limit: Int64 + page: Int64 } input PaginatedInput { - pagination: PaginationInput + pagination: PaginationInput } input OAuthRevokeInput { - refresh_token: String! + refresh_token: String! } input InviteMemberInput { - emails: [String!]! - redirect_uri: String + emails: [String!]! + redirect_uri: String } input UpdateAccessInput { - user_id: String! + user_id: String! } input ValidateJWTTokenInput { - token_type: String! - token: String! - roles: [String!] + token_type: String! + token: String! + roles: [String!] } input GenerateJWTKeysInput { - type: String! + type: String! } input ListWebhookLogRequest { - pagination: PaginationInput - webhook_id: String + pagination: PaginationInput + webhook_id: String } input AddWebhookRequest { - event_name: String! - endpoint: String! - enabled: Boolean! - headers: Map + event_name: String! + endpoint: String! + enabled: Boolean! + headers: Map } input UpdateWebhookRequest { - id: ID! - event_name: String - endpoint: String - enabled: Boolean - headers: Map + id: ID! + event_name: String + endpoint: String + enabled: Boolean + headers: Map } input WebhookRequest { - id: ID! + id: ID! } input TestEndpointRequest { - endpoint: String! - event_name: String! - headers: Map + endpoint: String! + event_name: String! + headers: Map } input AddEmailTemplateRequest { - event_name: String! - subject: String! - template: String! - design: String! + event_name: String! + subject: String! + template: String! + design: String! } input UpdateEmailTemplateRequest { - id: ID! - event_name: String - template: String - subject: String - design: String + id: ID! + event_name: String + template: String + subject: String + design: String } input DeleteEmailTemplateRequest { - id: ID! + id: ID! } input VerifyOTPRequest { - email: String! - otp: String! + email: String! + otp: String! + # 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 { - 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 { - signup(params: SignUpInput!): AuthResponse! - login(params: LoginInput!): AuthResponse! - magic_link_login(params: MagicLinkLoginInput!): Response! - logout: Response! - update_profile(params: UpdateProfileInput!): Response! - verify_email(params: VerifyEmailInput!): AuthResponse! - resend_verify_email(params: ResendVerifyEmailInput!): Response! - forgot_password(params: ForgotPasswordInput!): Response! - reset_password(params: ResetPasswordInput!): Response! - revoke(params: OAuthRevokeInput!): Response! - verify_otp(params: VerifyOTPRequest!): AuthResponse! - resend_otp(params: ResendOTPRequest!): Response! - # admin only apis - _delete_user(params: DeleteUserInput!): Response! - _update_user(params: UpdateUserInput!): User! - _admin_signup(params: AdminSignupInput!): Response! - _admin_login(params: AdminLoginInput!): Response! - _admin_logout: Response! - _update_env(params: UpdateEnvInput!): Response! - _invite_members(params: InviteMemberInput!): Response! - _revoke_access(param: UpdateAccessInput!): Response! - _enable_access(param: UpdateAccessInput!): Response! - _generate_jwt_keys(params: GenerateJWTKeysInput!): GenerateJWTKeysResponse! - _add_webhook(params: AddWebhookRequest!): Response! - _update_webhook(params: UpdateWebhookRequest!): Response! - _delete_webhook(params: WebhookRequest!): Response! - _test_endpoint(params: TestEndpointRequest!): TestEndpointResponse! - _add_email_template(params: AddEmailTemplateRequest!): Response! - _update_email_template(params: UpdateEmailTemplateRequest!): Response! - _delete_email_template(params: DeleteEmailTemplateRequest!): Response! + signup(params: SignUpInput!): AuthResponse! + login(params: LoginInput!): AuthResponse! + magic_link_login(params: MagicLinkLoginInput!): Response! + logout: Response! + update_profile(params: UpdateProfileInput!): Response! + verify_email(params: VerifyEmailInput!): AuthResponse! + resend_verify_email(params: ResendVerifyEmailInput!): Response! + forgot_password(params: ForgotPasswordInput!): Response! + reset_password(params: ResetPasswordInput!): Response! + revoke(params: OAuthRevokeInput!): Response! + verify_otp(params: VerifyOTPRequest!): AuthResponse! + resend_otp(params: ResendOTPRequest!): Response! + # admin only apis + _delete_user(params: DeleteUserInput!): Response! + _update_user(params: UpdateUserInput!): User! + _admin_signup(params: AdminSignupInput!): Response! + _admin_login(params: AdminLoginInput!): Response! + _admin_logout: Response! + _update_env(params: UpdateEnvInput!): Response! + _invite_members(params: InviteMemberInput!): Response! + _revoke_access(param: UpdateAccessInput!): Response! + _enable_access(param: UpdateAccessInput!): Response! + _generate_jwt_keys(params: GenerateJWTKeysInput!): GenerateJWTKeysResponse! + _add_webhook(params: AddWebhookRequest!): Response! + _update_webhook(params: UpdateWebhookRequest!): Response! + _delete_webhook(params: WebhookRequest!): Response! + _test_endpoint(params: TestEndpointRequest!): TestEndpointResponse! + _add_email_template(params: AddEmailTemplateRequest!): Response! + _update_email_template(params: UpdateEmailTemplateRequest!): Response! + _delete_email_template(params: DeleteEmailTemplateRequest!): Response! } type Query { - meta: Meta! - session(params: SessionQueryInput): AuthResponse! - profile: User! - validate_jwt_token(params: ValidateJWTTokenInput!): ValidateJWTTokenResponse! - # admin only apis - _users(params: PaginatedInput): Users! - _verification_requests(params: PaginatedInput): VerificationRequests! - _admin_session: Response! - _env: Env! - _webhook(params: WebhookRequest!): Webhook! - _webhooks(params: PaginatedInput): Webhooks! - _webhook_logs(params: ListWebhookLogRequest): WebhookLogs! - _email_templates(params: PaginatedInput): EmailTemplates! + meta: Meta! + session(params: SessionQueryInput): AuthResponse! + profile: User! + validate_jwt_token(params: ValidateJWTTokenInput!): ValidateJWTTokenResponse! + # admin only apis + _users(params: PaginatedInput): Users! + _verification_requests(params: PaginatedInput): VerificationRequests! + _admin_session: Response! + _env: Env! + _webhook(params: WebhookRequest!): Webhook! + _webhooks(params: PaginatedInput): Webhooks! + _webhook_logs(params: ListWebhookLogRequest): WebhookLogs! + _email_templates(params: PaginatedInput): EmailTemplates! } diff --git a/server/handlers/authorize.go b/server/handlers/authorize.go index f57c98d..43360b8 100644 --- a/server/handlers/authorize.go +++ b/server/handlers/authorize.go @@ -86,10 +86,23 @@ func AuthorizeHandler() gin.HandlerFunc { "code": code, }) - memorystore.Provider.SetState(codeChallenge, code) + // memorystore.Provider.SetState(codeChallenge, code) + // TODO add state with timeout // 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 if responseMode == constants.ResponseModeFragment { @@ -168,7 +181,15 @@ func AuthorizeHandler() gin.HandlerFunc { 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) handleResponse(gc, responseMode, loginURL, redirectURI, loginError, http.StatusOK) return @@ -317,13 +338,15 @@ func handleResponse(gc *gin.Context, responseMode, loginURI, redirectURI string, isAuthenticationRequired = true } + if isAuthenticationRequired { + gc.Redirect(http.StatusFound, loginURI) + return + } + switch responseMode { case constants.ResponseModeQuery, constants.ResponseModeFragment: - if isAuthenticationRequired { - gc.Redirect(http.StatusFound, loginURI) - } else { - gc.Redirect(http.StatusFound, redirectURI) - } + + gc.Redirect(http.StatusFound, redirectURI) return case constants.ResponseModeWebMessage: gc.HTML(httpStatusCode, authorizeWebMessageTemplate, gin.H{ @@ -332,6 +355,8 @@ func handleResponse(gc *gin.Context, responseMode, loginURI, redirectURI string, }) return case constants.ResponseModeFormPost: + fmt.Println("=> trying tof orm post") + fmt.Printf("=> %+v \n", data["response"]) gc.HTML(httpStatusCode, authorizeFormPostTemplate, gin.H{ "target_origin": redirectURI, "authorization_response": data["response"], diff --git a/server/handlers/token.go b/server/handlers/token.go index b9976a8..9a9ca1f 100644 --- a/server/handlers/token.go +++ b/server/handlers/token.go @@ -3,6 +3,7 @@ package handlers import ( "crypto/sha256" "encoding/base64" + "fmt" "net/http" "strings" "time" @@ -18,12 +19,26 @@ import ( "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 // grant type required func TokenHandler() gin.HandlerFunc { return func(gc *gin.Context) { - var reqBody map[string]string - if err := gc.BindJSON(&reqBody); err != nil { + // body := gc.Request.Body + // 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) gc.JSON(http.StatusBadRequest, gin.H{ "error": "error_binding_json", @@ -32,11 +47,14 @@ func TokenHandler() gin.HandlerFunc { return } - codeVerifier := strings.TrimSpace(reqBody["code_verifier"]) - code := strings.TrimSpace(reqBody["code"]) - clientID := strings.TrimSpace(reqBody["client_id"]) - grantType := strings.TrimSpace(reqBody["grant_type"]) - refreshToken := strings.TrimSpace(reqBody["refresh_token"]) + fmt.Printf("=>req body: %+v\n", reqBody) + + codeVerifier := strings.TrimSpace(reqBody.CodeVerifier) + code := strings.TrimSpace(reqBody.Code) + clientID := strings.TrimSpace(reqBody.ClientID) + grantType := strings.TrimSpace(reqBody.GrantType) + refreshToken := strings.TrimSpace(reqBody.RefreshToken) + clientSecret := strings.TrimSpace(reqBody.ClientSecret) if grantType == "" { grantType = "authorization_code" @@ -77,15 +95,6 @@ func TokenHandler() gin.HandlerFunc { sessionKey := "" 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 == "" { log.Debug("Code is empty") gc.JSON(http.StatusBadRequest, gin.H{ @@ -95,33 +104,55 @@ func TokenHandler() gin.HandlerFunc { return } - hash := sha256.New() - hash.Write([]byte(codeVerifier)) - encryptedCode := strings.ReplaceAll(base64.URLEncoding.EncodeToString(hash.Sum(nil)), "+", "-") - encryptedCode = strings.ReplaceAll(encryptedCode, "/", "_") - encryptedCode = strings.ReplaceAll(encryptedCode, "=", "") - sessionData, err := memorystore.Provider.GetState(encryptedCode) + if codeVerifier == "" && clientSecret == "" { + gc.JSON(http.StatusBadRequest, gin.H{ + "error": "invalid_dat", + "error_description": "The code verifier or client secret is required", + }) + return + } + // Get state + sessionData, err := memorystore.Provider.GetState(code) if sessionData == "" || err != nil { log.Debug("Session data is empty") gc.JSON(http.StatusBadRequest, gin.H{ - "error": "invalid_code_verifier", - "error_description": "The code verifier is invalid", + "error": "invalid_code", + "error_description": "The code is invalid", }) return } - go memorystore.Provider.RemoveState(encryptedCode) - // split session data - // it contains code@sessiontoken - sessionDataSplit := strings.Split(sessionData, "@") + // [0] -> code_challenge + // [1] -> session cookie + sessionDataSplit := strings.Split(sessionData, "@@") + fmt.Println("=> sessionDataSplit:", sessionDataSplit) - if sessionDataSplit[0] != code { - log.Debug("Invalid code verifier. Unable to split session data") - gc.JSON(http.StatusBadRequest, gin.H{ - "error": "invalid_code_verifier", - "error_description": "The code verifier is invalid", - }) - return + 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{ + "error": "invalid_code_verifier", + "error_description": "The code verifier is invalid", + }) + return + } + + } else { + if clientHash, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyClientSecret); clientSecret != clientHash || err != nil { + log.Debug("Client Secret is invalid: ", clientID) + gc.JSON(http.StatusBadRequest, gin.H{ + "error": "invalid_client_secret", + "error_description": "The client secret is invalid", + }) + return + } } // validate session @@ -135,6 +166,8 @@ func TokenHandler() gin.HandlerFunc { return } + fmt.Printf("=>claims: %+v\n", &claims) + userID = claims.Subject roles = claims.Roles scope = claims.Scope @@ -147,6 +180,7 @@ func TokenHandler() gin.HandlerFunc { } go memorystore.Provider.DeleteUserSession(sessionKey, claims.Nonce) + } else { // validate refresh token if refreshToken == "" { @@ -207,7 +241,11 @@ func TokenHandler() gin.HandlerFunc { 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) if err != nil { log.Debug("Error creating auth token: ", err) diff --git a/server/resolvers/login.go b/server/resolvers/login.go index 7683932..99b26f2 100644 --- a/server/resolvers/login.go +++ b/server/resolvers/login.go @@ -142,6 +142,28 @@ func LoginResolver(ctx context.Context, params model.LoginInput) (*model.AuthRes } 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) if err != nil { 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 memorystore.Provider.SetUserSession(sessionStoreKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash) 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 { res.RefreshToken = &authToken.RefreshToken.Token diff --git a/server/resolvers/signup.go b/server/resolvers/signup.go index 3365cd6..06a477c 100644 --- a/server/resolvers/signup.go +++ b/server/resolvers/signup.go @@ -34,6 +34,16 @@ func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthR 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) if err != nil { 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() + if code != "" { + nonce = nonce + "@@" + code + } + authToken, err := token.CreateAuthToken(gc, user, roles, scope, constants.AuthRecipeMethodBasicAuth, nonce) if err != nil { log.Debug("Failed to create auth token: ", err) diff --git a/server/resolvers/update_user.go b/server/resolvers/update_user.go index e2f6618..057b797 100644 --- a/server/resolvers/update_user.go +++ b/server/resolvers/update_user.go @@ -125,7 +125,6 @@ func UpdateUserResolver(ctx context.Context, params model.UpdateUserInput) (*mod return res, fmt.Errorf("user with this email address already exists") } - // TODO figure out how to do this go memorystore.Provider.DeleteAllUserSessions(user.ID) hostname := parsers.GetHost(gc) diff --git a/server/token/auth_token.go b/server/token/auth_token.go index 0d3114e..1833db3 100644 --- a/server/token/auth_token.go +++ b/server/token/auth_token.go @@ -1,6 +1,8 @@ package token import ( + "crypto/sha256" + "encoding/base64" "encoding/json" "fmt" "strings" @@ -46,28 +48,22 @@ type SessionData struct { 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 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) _, fingerPrintHash, err := CreateSessionToken(user, nonce, roles, scope, loginMethod) if err != nil { @@ -78,13 +74,31 @@ func CreateAuthToken(gc *gin.Context, user models.User, roles, scope []string, l 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 { return nil, err } res := &Token{ - FingerPrint: nonce, + FingerPrint: fingerPrint, FingerPrintHash: fingerPrintHash, AccessToken: &JWTToken{Token: accessToken, ExpiresAt: accessTokenExpiresAt}, 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 } +// 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 func CreateRefreshToken(user models.User, roles, scopes []string, hostname, nonce, loginMethod string) (string, int64, error) { // 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 // 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, 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) if err != nil { return "", 0, err @@ -344,10 +379,10 @@ func CreateIDToken(user models.User, roles []string, hostname, nonce, loginMetho if err != nil { return "", 0, err } + customClaims := jwt.MapClaims{ - "iss": hostname, - "aud": clientID, - // "nonce": nonce, + "iss": hostname, + "aud": clientID, "sub": user.ID, "exp": expiresAt, "iat": time.Now().Unix(), @@ -357,6 +392,20 @@ func CreateIDToken(user models.User, roles []string, hostname, nonce, loginMetho 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 { if k != "roles" { customClaims[k] = v diff --git a/server/utils/gin_context.go b/server/utils/gin_context.go index 7e3ced6..0491cbe 100644 --- a/server/utils/gin_context.go +++ b/server/utils/gin_context.go @@ -7,8 +7,6 @@ import ( "github.com/gin-gonic/gin" ) -// TODO re-name GinContextKey -> GinContext - // GinContext to get gin context from context func GinContextFromContext(ctx context.Context) (*gin.Context, error) { ginContext := ctx.Value("GinContextKey")