diff --git a/backend/package.json b/backend/package.json index 8a8d14e00..8534b9434 100644 --- a/backend/package.json +++ b/backend/package.json @@ -33,7 +33,7 @@ "graphql": "^15.5.1", "graphql-request": "5.0.0", "i18n": "^0.15.1", - "jsonwebtoken": "^8.5.1", + "jose": "^4.14.4", "lodash.clonedeep": "^4.5.0", "log4js": "^6.4.6", "mysql2": "^2.3.0", @@ -52,7 +52,6 @@ "@types/faker": "^5.5.9", "@types/i18n": "^0.13.4", "@types/jest": "^27.0.2", - "@types/jsonwebtoken": "^8.5.2", "@types/lodash.clonedeep": "^4.5.6", "@types/node": "^16.10.3", "@types/nodemailer": "^6.4.4", diff --git a/backend/src/auth/CustomJwtPayload.ts b/backend/src/auth/CustomJwtPayload.ts index 7966b413e..e20e5b272 100644 --- a/backend/src/auth/CustomJwtPayload.ts +++ b/backend/src/auth/CustomJwtPayload.ts @@ -1,5 +1,5 @@ -import { JwtPayload } from 'jsonwebtoken' +import { JWTPayload } from 'jose' -export interface CustomJwtPayload extends JwtPayload { +export interface CustomJwtPayload extends JWTPayload { gradidoID: string } diff --git a/backend/src/auth/JWT.ts b/backend/src/auth/JWT.ts index 90e6947ba..d8c6c81cf 100644 --- a/backend/src/auth/JWT.ts +++ b/backend/src/auth/JWT.ts @@ -1,22 +1,33 @@ -import { verify, sign } from 'jsonwebtoken' +import { SignJWT, jwtVerify } from 'jose' import { CONFIG } from '@/config/' import { LogError } from '@/server/LogError' import { CustomJwtPayload } from './CustomJwtPayload' -export const decode = (token: string): CustomJwtPayload | null => { +export const decode = async (token: string): Promise => { if (!token) throw new LogError('401 Unauthorized') + try { - return verify(token, CONFIG.JWT_SECRET) as CustomJwtPayload + const secret = new TextEncoder().encode(CONFIG.JWT_SECRET) + const { payload } = await jwtVerify(token, secret, { + issuer: 'urn:gradido:issuer', + audience: 'urn:gradido:audience', + }) + return payload as CustomJwtPayload } catch (err) { return null } } -export const encode = (gradidoID: string): string => { - const token = sign({ gradidoID }, CONFIG.JWT_SECRET, { - expiresIn: CONFIG.JWT_EXPIRES_IN, - }) +export const encode = async (gradidoID: string): Promise => { + const secret = new TextEncoder().encode(CONFIG.JWT_SECRET) + const token = await new SignJWT({ gradidoID, 'urn:gradido:claim': true }) + .setProtectedHeader({ alg: 'HS256' }) + .setIssuedAt() + .setIssuer('urn:gradido:issuer') + .setAudience('urn:gradido:audience') + .setExpirationTime(CONFIG.JWT_EXPIRES_IN) + .sign(secret) return token } diff --git a/backend/src/graphql/directive/isAuthorized.ts b/backend/src/graphql/directive/isAuthorized.ts index 8f4c6e22c..e41f41151 100644 --- a/backend/src/graphql/directive/isAuthorized.ts +++ b/backend/src/graphql/directive/isAuthorized.ts @@ -21,7 +21,7 @@ export const isAuthorized: AuthChecker = async ({ context }, rights) => } // Decode the token - const decoded = decode(context.token) + const decoded = await decode(context.token) if (!decoded) { throw new LogError('403.13 - Client certificate revoked') } @@ -49,6 +49,6 @@ export const isAuthorized: AuthChecker = async ({ context }, rights) => } // set new header token - context.setHeaders.push({ key: 'token', value: encode(decoded.gradidoID) }) + context.setHeaders.push({ key: 'token', value: await encode(decoded.gradidoID) }) return true } diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index a19d9e7d7..cbfd9b5c5 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -186,7 +186,7 @@ export class UserResolver { context.setHeaders.push({ key: 'token', - value: encode(dbUser.gradidoID), + value: await encode(dbUser.gradidoID), }) await EVENT_USER_LOGIN(dbUser) diff --git a/backend/yarn.lock b/backend/yarn.lock index 237a265e3..4d070934b 100644 --- a/backend/yarn.lock +++ b/backend/yarn.lock @@ -1059,13 +1059,6 @@ resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= -"@types/jsonwebtoken@^8.5.2": - version "8.5.5" - resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-8.5.5.tgz#da5f2f4baee88f052ef3e4db4c1a0afb46cff22c" - integrity sha512-OGqtHQ7N5/Ap/TUwO6IgHDuLiAoTmHhGpNvgkCm/F4N6pKzx/RBSfr2OXZSwC6vkfnsEdb6+7DNZVtiXiwdwFw== - dependencies: - "@types/node" "*" - "@types/keygrip@*": version "1.0.2" resolved "https://registry.yarnpkg.com/@types/keygrip/-/keygrip-1.0.2.tgz#513abfd256d7ad0bf1ee1873606317b33b1b2a72" @@ -2002,11 +1995,6 @@ bser@2.1.1: dependencies: node-int64 "^0.4.0" -buffer-equal-constant-time@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" - integrity sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk= - buffer-from@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" @@ -2699,13 +2687,6 @@ duplexer3@^0.1.4: resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= -ecdsa-sig-formatter@1.0.11: - version "1.0.11" - resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf" - integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ== - dependencies: - safe-buffer "^5.0.1" - ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" @@ -4805,6 +4786,11 @@ jest@^27.2.4: import-local "^3.0.2" jest-cli "^27.2.5" +jose@^4.14.4: + version "4.14.4" + resolved "https://registry.yarnpkg.com/jose/-/jose-4.14.4.tgz#59e09204e2670c3164ee24cbfe7115c6f8bff9ca" + integrity sha512-j8GhLiKmUAh+dsFXlX1aJCbt5KMibuKb+d7j1JaOJG6s2UjX1PQlW+OKB/sD4a/5ZYF4RcmYmLSndOoU3Lt/3g== + js-sdsl@^4.1.4: version "4.3.0" resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.3.0.tgz#aeefe32a451f7af88425b11fdb5f58c90ae1d711" @@ -4918,22 +4904,6 @@ jsonfile@^6.0.1: optionalDependencies: graceful-fs "^4.1.6" -jsonwebtoken@^8.5.1: - version "8.5.1" - resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz#00e71e0b8df54c2121a1f26137df2280673bcc0d" - integrity sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w== - dependencies: - jws "^3.2.2" - lodash.includes "^4.3.0" - lodash.isboolean "^3.0.3" - lodash.isinteger "^4.0.4" - lodash.isnumber "^3.0.3" - lodash.isplainobject "^4.0.6" - lodash.isstring "^4.0.1" - lodash.once "^4.0.0" - ms "^2.1.1" - semver "^5.6.0" - jstransformer@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/jstransformer/-/jstransformer-1.0.0.tgz#ed8bf0921e2f3f1ed4d5c1a44f68709ed24722c3" @@ -4953,23 +4923,6 @@ juice@^8.0.0: slick "^1.12.2" web-resource-inliner "^6.0.1" -jwa@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.4.1.tgz#743c32985cb9e98655530d53641b66c8645b039a" - integrity sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA== - dependencies: - buffer-equal-constant-time "1.0.1" - ecdsa-sig-formatter "1.0.11" - safe-buffer "^5.0.1" - -jws@^3.2.2: - version "3.2.2" - resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304" - integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA== - dependencies: - jwa "^1.4.1" - safe-buffer "^5.0.1" - keyv@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9" @@ -5073,46 +5026,11 @@ lodash.get@^4.4.2: resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk= -lodash.includes@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" - integrity sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8= - -lodash.isboolean@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" - integrity sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY= - -lodash.isinteger@^4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343" - integrity sha1-YZwK89A/iwTDH1iChAt3sRzWg0M= - -lodash.isnumber@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc" - integrity sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w= - -lodash.isplainobject@^4.0.6: - version "4.0.6" - resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" - integrity sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs= - -lodash.isstring@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" - integrity sha1-1SfftUVuynzJu5XV2ur4i6VKVFE= - lodash.merge@^4.6.2: version "4.6.2" resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== -lodash.once@^4.0.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" - integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w= - lodash.sortby@^4.7.0: version "4.7.0" resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" @@ -6344,7 +6262,7 @@ semver@7.x, semver@^7.3.2, semver@^7.3.4: dependencies: lru-cache "^6.0.0" -semver@^5.5.0, semver@^5.6.0, semver@^5.7.1: +semver@^5.5.0, semver@^5.7.1: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==