diff --git a/CHANGELOG.MD b/CHANGELOG.MD index 267a30c5..04125d3d 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -5,6 +5,12 @@ Alla märkbara ändringar ska dokumenteras i denna fil. Baserat på [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), och följer [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.7.1] - 2024-01-24 + +### Ändrat + +- Update the `updateUser` function so that it corectly updates the `luCard` field and sets it to null if the input is an empty string. + ## [1.7.0] - 2023-08-31 ### Tillagt @@ -18,17 +24,23 @@ och följer [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ### Borttaget - Testen `forget a user` och `reset password properly` i `user.api.ts`. -- + ## [1.6.1] - 2023-12-14 +### Tillagt + Adds the `ahs_admin` feature access type ## [1.6.0] - 2023-12-04 +### Tillagt + la till ny gql metod: allUsersWithIndividualAccess ## [1.5.0] - 2023-11-26 +### Tillagt + Adds ledtoa as a door ## [1.4.1] - 2023-08-06 diff --git a/package-lock.json b/package-lock.json index d4490504..bf793da4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "ekorre-ts", - "version": "1.6.0", + "version": "1.7.1", "lockfileVersion": 2, "requires": true, "packages": { diff --git a/package.json b/package.json index 23182bb0..6b00519f 100644 --- a/package.json +++ b/package.json @@ -1,105 +1,104 @@ { - "name": "ekorre-ts", - "version": "1.7.0", - "description": "E-Sektionens backend", - "main": "src/index.ts", - "scripts": { - "run": "node -r ts-node/register/transpile-only -r tsconfig-paths/register build/src/index.js", - "build": "tsc --project ./tsconfig.build.json", - "prestart": "npm run build", - "start": "npm run run", - "dev": "nodemon -e ts,graphql --watch src --exec \"node --nolazy --inspect -r tsconfig-paths/register -r ts-node/register src/index.ts\"", - "prettier-format": "prettier --config .prettierrc \"src/**/*.ts\" \"test/**/*.ts\" --write", - "lint": "eslint src test", - "test": "jest", - "test:prebuild": "jest test/unit test/integration", - "test:unit": "jest test/unit", - "test:integration": "jest test/integration", - "test:regression": "jest test/regression --coverage=false", - "benchmark": "ts-node tools/benchmark/index.ts", - "prisma:ci": "prisma generate && prisma db push --accept-data-loss && prisma db seed", - "prisma:reset": "prisma migrate reset --skip-seed; prisma db push; prisma db seed", - "prisma:generate": "prisma generate", - "prisma:push": "prisma db push", - "prisma:migrate": "prisma migrate dev", - "graphql:generate": "graphql-codegen --config codegen.yml", - "generate": "npm run graphql:generate && npm run prisma:generate" - }, - "author": "Emil Blennow ", - "Axel Froborg ", - "Marcus Lindell ", - "Eric Weidow ", - "Axel Andersson " - ], - "bugs": { - "email": "macapar@esek.se" - }, - "license": "AGPL-3.0-only", - "repository": { - "type": "git", - "url": "https://github.com/esek/ekorre.git" - }, - "prisma": { - "seed": "ts-node prisma/data/seed.ts" - }, - "dependencies": { - "@esek/auth-server": "5.0.2", - "@graphql-tools/graphql-file-loader": "^7.5.13", - "@graphql-tools/load": "^7.8.8", - "@graphql-tools/schema": "^9.0.12", - "@prisma/client": "^5.0.0", - "apollo-server-core": "^3.11.1", - "apollo-server-errors": "^3.3.1", - "apollo-server-express": "^3.11.1", - "axios": "^1.2.2", - "cookie-parser": "^1.4.6", - "dataloader": "^2.1.0", - "dotenv": "^16.0.3", - "express": "^4.18.2", - "express-fileupload": "^1.4.0", - "graphql": "^16.6.0", - "graphql-scalars": "^1.20.1", - "jsdom": "^20.0.3", - "jsonwebtoken": "^9.0.0", - "regenerator-runtime": "^0.13.11", - "set-cookie-parser": "^2.5.1", - "ts-node": "^10.9.1", - "tsconfig-paths": "^4.1.2", - "typescript": "^4.9.4" - }, - "devDependencies": { - "@graphql-codegen/cli": "^2.16.2", - "@graphql-codegen/introspection": "2.2.3", - "@graphql-codegen/typescript": "2.8.6", - "@graphql-codegen/typescript-resolvers": "2.7.11", - "@trivago/prettier-plugin-sort-imports": "^4.0.0", - "@types/cookie-parser": "^1.4.3", - "@types/express": "^4.17.15", - "@types/express-fileupload": "^1.4.1", - "@types/inquirer": "^9.0.3", - "@types/jest": "^29.2.5", - "@types/jsdom": "^20.0.1", - "@types/jsonwebtoken": "^9.0.0", - "@types/node": "^18.11.18", - "@types/set-cookie-parser": "^2.4.2", - "@types/supertest": "^2.0.12", - "@typescript-eslint/eslint-plugin": "^5.48.0", - "@typescript-eslint/parser": "^5.48.0", - "eslint": "^8.31.0", - "eslint-config-airbnb-typescript": "^17.0.0", - "eslint-config-prettier": "^8.6.0", - "eslint-import-resolver-typescript": "^3.5.2", - "eslint-plugin-import": "^2.26.0", - "inquirer": "^9.1.4", - "jest": "^29.3.1", - "nanospinner": "^1.1.0", - "nodemon": "^2.0.20", - "prettier": "^2.8.1", - "prisma": "^5.0.0", - "prisma-dbml-generator": "^0.10.0", - "supertest": "^6.3.3", - "ts-jest": "^29.0.3" - } -} \ No newline at end of file + "name": "ekorre-ts", + "version": "1.7.1", + "description": "E-Sektionens backend", + "main": "src/index.ts", + "scripts": { + "run": "node -r ts-node/register/transpile-only -r tsconfig-paths/register build/src/index.js", + "build": "tsc --project ./tsconfig.build.json", + "prestart": "npm run build", + "start": "npm run run", + "dev": "nodemon -e ts,graphql --watch src --exec \"node --nolazy --inspect -r tsconfig-paths/register -r ts-node/register src/index.ts\"", + "prettier-format": "prettier --config .prettierrc \"src/**/*.ts\" \"test/**/*.ts\" --write", + "lint": "eslint src test", + "test": "jest", + "test:prebuild": "jest test/unit test/integration", + "test:unit": "jest test/unit", + "test:integration": "jest test/integration", + "test:regression": "jest test/regression --coverage=false", + "benchmark": "ts-node tools/benchmark/index.ts", + "prisma:ci": "prisma generate && prisma db push --accept-data-loss && prisma db seed", + "prisma:reset": "prisma migrate reset --skip-seed; prisma db push; prisma db seed", + "prisma:generate": "prisma generate", + "prisma:push": "prisma db push", + "prisma:migrate": "prisma migrate dev", + "graphql:generate": "graphql-codegen --config codegen.yml", + "generate": "npm run graphql:generate && npm run prisma:generate" + }, + "author": "Emil Blennow ", + "Axel Froborg ", + "Marcus Lindell ", + "Eric Weidow " + ], + "bugs": { + "email": "macapar@esek.se" + }, + "license": "AGPL-3.0-only", + "repository": { + "type": "git", + "url": "https://github.com/esek/ekorre.git" + }, + "prisma": { + "seed": "ts-node prisma/data/seed.ts" + }, + "dependencies": { + "@esek/auth-server": "5.0.2", + "@graphql-tools/graphql-file-loader": "^7.5.13", + "@graphql-tools/load": "^7.8.8", + "@graphql-tools/schema": "^9.0.12", + "@prisma/client": "^5.0.0", + "apollo-server-core": "^3.11.1", + "apollo-server-errors": "^3.3.1", + "apollo-server-express": "^3.11.1", + "axios": "^1.2.2", + "cookie-parser": "^1.4.6", + "dataloader": "^2.1.0", + "dotenv": "^16.0.3", + "express": "^4.18.2", + "express-fileupload": "^1.4.0", + "graphql": "^16.6.0", + "graphql-scalars": "^1.20.1", + "jsdom": "^20.0.3", + "jsonwebtoken": "^9.0.0", + "regenerator-runtime": "^0.13.11", + "set-cookie-parser": "^2.5.1", + "ts-node": "^10.9.1", + "tsconfig-paths": "^4.1.2", + "typescript": "^4.9.4" + }, + "devDependencies": { + "@graphql-codegen/cli": "^2.16.2", + "@graphql-codegen/introspection": "2.2.3", + "@graphql-codegen/typescript": "2.8.6", + "@graphql-codegen/typescript-resolvers": "2.7.11", + "@trivago/prettier-plugin-sort-imports": "^4.0.0", + "@types/cookie-parser": "^1.4.3", + "@types/express": "^4.17.15", + "@types/express-fileupload": "^1.4.1", + "@types/inquirer": "^9.0.3", + "@types/jest": "^29.2.5", + "@types/jsdom": "^20.0.1", + "@types/jsonwebtoken": "^9.0.0", + "@types/node": "^18.11.18", + "@types/set-cookie-parser": "^2.4.2", + "@types/supertest": "^2.0.12", + "@typescript-eslint/eslint-plugin": "^5.48.0", + "@typescript-eslint/parser": "^5.48.0", + "eslint": "^8.31.0", + "eslint-config-airbnb-typescript": "^17.0.0", + "eslint-config-prettier": "^8.6.0", + "eslint-import-resolver-typescript": "^3.5.2", + "eslint-plugin-import": "^2.26.0", + "inquirer": "^9.1.4", + "jest": "^29.3.1", + "nanospinner": "^1.1.0", + "nodemon": "^2.0.20", + "prettier": "^2.8.1", + "prisma": "^5.0.0", + "prisma-dbml-generator": "^0.10.0", + "supertest": "^6.3.3", + "ts-jest": "^29.0.3" + } +} diff --git a/src/api/user.api.ts b/src/api/user.api.ts index b4a0c455..689be789 100644 --- a/src/api/user.api.ts +++ b/src/api/user.api.ts @@ -357,6 +357,12 @@ export class UserAPI { throw new BadRequestError('Användarnamn kan inte uppdateras'); } + // If we are trying to set the LU card to an empty string, set it to null + // we can't have empty strings in the database because if unique constraints + if (partial.luCard === '') { + partial.luCard = null; + } + // check if we are trying to update the LU card, and that it's not an empty string or null if ('luCard' in partial && partial.luCard && !this.validLuCard(partial.luCard)) { throw new BadRequestError('Ogiltigt LU-kort'); diff --git a/test/unit/user.api.test.ts b/test/unit/user.api.test.ts index e087340c..05ca97ac 100644 --- a/test/unit/user.api.test.ts +++ b/test/unit/user.api.test.ts @@ -175,13 +175,13 @@ test('updating lu card', async () => { await api.createUser(mockNewUser1); - await expect( - api.updateUser(mockNewUser1.username, { ...u, luCard: '002504' }), - ).rejects.toThrowError(BadRequestError); + await expect(api.updateUser(mockNewUser1.username, { ...u, luCard: '002504' })).rejects.toThrow( + BadRequestError, + ); await expect( api.updateUser(mockNewUser1.username, { ...u, luCard: '002504000000000A' }), - ).rejects.toThrowError(BadRequestError); - await expect(api.updateUser(mockNewUser1.username, { ...u, luCard: '00' })).rejects.toThrowError( + ).rejects.toThrow(BadRequestError); + await expect(api.updateUser(mockNewUser1.username, { ...u, luCard: '00' })).rejects.toThrow( BadRequestError, ); @@ -203,7 +203,10 @@ test('updating lu card', async () => { }; await expect(api.updateUser(mockNewUser1.username, deleteLuCard)).resolves.not.toThrow(); - await expect(api.getSingleUser(mockNewUser1.username)).resolves.toMatchObject(deleteLuCard); + await expect(api.getSingleUser(mockNewUser1.username)).resolves.toMatchObject({ + ...u, + luCard: null, + }); }); test('updating username', async () => { @@ -316,6 +319,38 @@ test('reset password with expired resetPasswordToken', async () => { ).rejects.toThrowError(NotFoundError); }); +test('forget a user', async () => { + // idk why this works but it does + // https://github.com/prisma/prisma/issues/19542#issuecomment-1686102323 + jest.useFakeTimers({ doNotFake: ['nextTick', 'setImmediate'] }); + + const couldForget = await api.forgetUser(mockNewUser0.username); // How could you forget me? + expect(couldForget).toBeTruthy(); + + const user = await api.getSingleUser(mockNewUser0.username); + expect(user.firstName).toEqual('Raderad'); + expect(user.lastName).toEqual('Användare'); + expect(user.email).toEqual(''); + + await expect(api.loginUser(mockNewUser0.username, mockNewUser0.password)).rejects.toThrow(); +}); + +test('reset password properly', async () => { + await api.createUser(mockNewUser1); + const token = await api.requestPasswordReset(mockNewUser1.username); + const newPassword = 'Detta test skrevs på valmötet 2021'; + + // Försäkra sig om att nya lösenordet inte funkar till att börja med + await expect(api.loginUser(mockNewUser1.username, newPassword)).rejects.toThrowError( + UnauthenticatedError, + ); + + await api.resetPassword(token, mockNewUser1.username, newPassword); + + // Försäkra oss om att lösen ändras + await expect(api.loginUser(mockNewUser1.username, newPassword)).resolves.toBeTruthy(); +}); + test('getting number of members', async () => { // Svårtestat då users skrivs och tas bort från DB konstant under tester const numberOfMembers = await api.getNumberOfMembers();