Skip to content

Commit

Permalink
888-be-sso-migrate-user-name-to-sso (#959)
Browse files Browse the repository at this point in the history
* 888-be-sso-migrate-user-name-to-sso

* fix: naming refactor
  • Loading branch information
danny-mv authored Feb 12, 2024
1 parent 37846e2 commit d9b409d
Show file tree
Hide file tree
Showing 133 changed files with 1,419 additions and 720 deletions.
28 changes: 28 additions & 0 deletions back/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,34 @@

All notable changes to this project will be documented in this file.

## [0.10.0] - 2024-02-12

### Added

- `attachUserNamesToResources` to unify and simplify resource object structure across the application by ensuring all resources include `user` details (name and optionally `avatarId`) and `favorites`
-`markFavorites` to mark resources as favorites based on user interaction,
- Get users name by id from SSO endpoint

### Changed

- Endpoint naming conventions in SSOhandler have been updated to align with the latest changes in the SSO. This update affects several endpoints and query string handling. For a complete list of endpoint naming changes and their implications, please refer to the [SSO changelog](../sso/CHANGELOG.md#190---2024-02-07).
- Removed unnecessary nesting in the Prisma query within the `getFavoriteResources` middleware.
- Adjusted middleware sequence: errorMiddleware now initialized before koaBody to capture body parsing errors.
- User name is now handled by SSO.

### Removed

- name from "users" table

### Testing

- Organized MSW handlers into separate files
- Added to ssoServer mock, get users name by id handler.

### Documentation

- Added `UpstreamServiceFail` response

## [0.9.0] - 2024-01-24

### Changed
Expand Down
18 changes: 16 additions & 2 deletions back/openapi.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
info:
version: 0.9.0
version: 0.10.0
title: IT Academy Wiki
description: Our app implements a Wiki to be used as a knowledge base by the
students of the Barcelona Activa's IT Academy
Expand Down Expand Up @@ -74,6 +74,14 @@ components:
example: User not found
required:
- message
UpstreamServiceFail:
type: object
properties:
message:
type: string
example: Upstream service failed to respond with the required data
required:
- message
ServiceUnavailableError:
type: object
properties:
Expand Down Expand Up @@ -877,7 +885,7 @@ paths:
example: tailwind
responses:
"200":
description: Sucessful operation
description: Successful operation
content:
application/json:
schema:
Expand Down Expand Up @@ -2067,6 +2075,12 @@ paths:
example: Database error
required:
- message
"502":
description: Upstream service fail
content:
application/json:
schema:
$ref: "#/components/schemas/UpstreamServiceFail"
/api/v1/favorites:
put:
tags:
Expand Down
4 changes: 2 additions & 2 deletions back/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion back/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "back",
"private": true,
"version": "0.9.0",
"version": "0.10.0",
"prisma": {
"seed": "tsx prisma/seed.ts"
},
Expand Down
6 changes: 3 additions & 3 deletions back/prisma/data/users.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ import { Prisma } from '@prisma/client'

export const users: Prisma.UserCreateArgs['data'][] = [
{
name: 'Kevin Mamaqi',
id: 'cikq4kixu3386a1zb64t0gkw',
},
{
name: 'Django Unchained',
id: 'lmx9b6kkym55xqwai2gbhfem',
},
{
name: 'Linux Mint',
id: 'qbdlyw0p08mltg72ua19jezc',
},
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*
Warnings:
- You are about to drop the column `name` on the `user` table. All the data in the column will be lost.
*/
-- AlterTable
ALTER TABLE "user" DROP COLUMN "name";
1 change: 0 additions & 1 deletion back/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ datasource db {

model User {
id String @id @default(cuid())
name String
resources Resource[]
media Media[]
avatarId String? @unique @map("avatar_id")
Expand Down
6 changes: 3 additions & 3 deletions back/prisma/seed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,15 @@ async function seedDB() {
})

const userAdmin = await prisma.user.findFirst({
where: { name: 'Kevin Mamaqi' },
where: { id: users[0].id },
})

const userMentor = await prisma.user.findFirst({
where: { name: 'Linux Mint' },
where: { id: users[1].id },
})

const userRegistered = await prisma.user.findFirst({
where: { name: 'Django Unchained' },
where: { id: users[2].id },
})

const topicCategories = [
Expand Down
4 changes: 2 additions & 2 deletions back/src/__tests__/auth/me.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { pathRoot } from '../../routes/routes'
import { checkInvalidToken } from '../helpers/checkInvalidToken'
import { prisma } from '../../prisma/client'
import { userGetSchema } from '../../schemas'
import { authToken } from '../mocks/ssoServer'
import { authToken } from '../mocks/ssoHandlers/authToken'

describe('Testing ME endpoint', () => {
const pathUploadMedia = './static/media'
Expand All @@ -22,7 +22,7 @@ describe('Testing ME endpoint', () => {
// const savedFile = fs.readFile(`${pathUploadMedia}/testImage.png`)

user = (await prisma.user.findFirst({
where: { name: testUserData.admin.name },
where: { id: testUserData.admin.id },
})) as User

await prisma.media.create({
Expand Down
5 changes: 3 additions & 2 deletions back/src/__tests__/auth/register.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,18 @@ import { expect, it, describe, afterAll, afterEach } from 'vitest'
import { server } from '../globalSetup'
import { prisma } from '../../prisma/client'
import { pathRoot } from '../../routes/routes'
import { mockRegisterId } from '../mocks/ssoHandlers'

afterEach(async () => {
await prisma.user.deleteMany({
where: {
OR: [{ name: 'Example2' }],
OR: [{ id: mockRegisterId }],
},
})
})
afterAll(async () => {
await prisma.user.deleteMany({
where: { name: 'Example2' },
where: { id: mockRegisterId },
})
})
describe('Testing registration endpoint', () => {
Expand Down
2 changes: 1 addition & 1 deletion back/src/__tests__/categories/createCategory.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { server } from '../globalSetup'
import { prisma } from '../../prisma/client'
import { pathRoot } from '../../routes/routes'
import { checkInvalidToken } from '../helpers/checkInvalidToken'
import { authToken } from '../mocks/ssoServer'
import { authToken } from '../mocks/ssoHandlers/authToken'

const newCategory = { name: 'New Category' }
describe('Testing category POST method', () => {
Expand Down
2 changes: 1 addition & 1 deletion back/src/__tests__/categories/patchCategory.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { prisma } from '../../prisma/client'
import { server } from '../globalSetup'
import { pathRoot } from '../../routes/routes'
import { checkInvalidToken } from '../helpers/checkInvalidToken'
import { authToken } from '../mocks/ssoServer'
import { authToken } from '../mocks/ssoHandlers/authToken'

describe('Testing category PATCH method', async () => {
let newTestCategory: Category | null = null
Expand Down
4 changes: 2 additions & 2 deletions back/src/__tests__/favorites/putFavoriteByUserId.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ import { Favorites, User, Resource } from '@prisma/client'
import { server, testUserData } from '../globalSetup'
import { pathRoot } from '../../routes/routes'
import { prisma } from '../../prisma/client'
import { authToken } from '../mocks/ssoServer'
import { authToken } from '../mocks/ssoHandlers/authToken'
import { checkInvalidToken } from '../helpers/checkInvalidToken'

describe('Testing resource modify endpoint', () => {
const req: { id: string } = { id: '' }
let user: User | null
beforeEach(async () => {
user = await prisma.user.findFirst({
where: { name: testUserData.user.name },
where: { id: testUserData.user.id },
})

const category = await prisma.category.findUnique({
Expand Down
38 changes: 5 additions & 33 deletions back/src/__tests__/globalSetup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,40 +71,12 @@ export async function setup() {
},
})

const { password, email, dni, role, status, ...admin } = testUserData.admin
const {
password: p0,
email: e0,
dni: d0,
role: r0,
status: s0,
...user
} = testUserData.user
const {
password: p1,
email: e1,
dni: d1,
role: r1,
status: s1,
...mentor
} = testUserData.mentor
const {
password: p2,
email: e2,
dni: d2,
role: r2,
status: s2,
...inactiveUser
} = testUserData.inactiveUser
const users = Object.values(testUserData).map((userData) => {
const { name, dni, email, password, role, status, ...rest } = userData
return { ...rest }
})
await prisma.user.createMany({
data: [
{ ...admin },
{ ...user },
{ ...mentor },
{
...inactiveUser,
},
],
data: [...users],
})

await prisma.topic.create({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import supertest from 'supertest'
import { expect, it, describe } from 'vitest'
import { server } from '../globalSetup'
import { pathRoot } from '../../routes/routes'
import { itineraryGetSchema } from '../../schemas/itinerary/itineraryGetSchema'
import { ssoServer } from '../mocks/ssoServer'
import { itinerariesListSchema } from '../../schemas/itinerary/itinerariesListSchema'

describe('Testing category GET method', () => {
it('Should respond OK status and return itineraries as an array. As per seed data, it should not be empty, and contain objects with an id and category name.', async () => {
Expand All @@ -12,7 +12,7 @@ describe('Testing category GET method', () => {
expect(response.status).toBe(200)
expect(response.body).toBeInstanceOf(Array)
expect(response.body.length).toBeGreaterThan(0)
expect(() => itineraryGetSchema.parse(response.body)).not.toThrow()
expect(() => itinerariesListSchema.parse(response.body)).not.toThrow()
expect(response.body).toEqual(
expect.arrayContaining([
expect.objectContaining({
Expand Down
4 changes: 2 additions & 2 deletions back/src/__tests__/media/media.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ import { expect, test, describe, it, afterAll } from 'vitest'
import { server, testUserData } from '../globalSetup'
import { pathRoot } from '../../routes/routes'
import { prisma } from '../../prisma/client'
import { authToken } from '../mocks/ssoServer'
import { authToken } from '../mocks/ssoHandlers/authToken'

const pathUploadMedia = './static/media'

afterAll(async () => {
const testUser = await prisma.user.findFirst({
where: { name: testUserData.user.name },
where: { id: testUserData.user.id },
})
await prisma.media.deleteMany({
where: { userId: testUser!.id },
Expand Down
14 changes: 14 additions & 0 deletions back/src/__tests__/mocks/ssoHandlers/authToken.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export const authToken: {
admin: string
mentor: string
user: string
inactiveUser: string
} = {
admin:
'ebJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c',
mentor:
'ecJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c',
user: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c',
inactiveUser:
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5d',
}
47 changes: 47 additions & 0 deletions back/src/__tests__/mocks/ssoHandlers/getMeUsersHandler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { http, HttpResponse } from 'msw'
import { testUserData } from '../../globalSetup'
import { authToken } from './authToken'

type GetMeUsersResponse =
| { message: string }
| { dni: string; email: string; role: string; status: string }
export const getMeUsersHandler = http.post(
'http://localhost:8000/api/v1/users/me',
async ({ request }) => {
const { authToken: token } = (await request.json()) as {
authToken: string
}
const isValidToken = Object.values(authToken).includes(token)
if (!isValidToken) {
return HttpResponse.json(
{
message: 'Invalid Credentials',
} as GetMeUsersResponse,
{ status: 401 }
)
}
const userType = Object.keys(authToken).find(
(key) => authToken[key] === token
)
if (!userType) {
return HttpResponse.json(
{
message: 'Invalid Credentials',
} as GetMeUsersResponse,
{ status: 401 }
)
}
const { dni, email, name, role, status } = testUserData[userType]

return HttpResponse.json(
{
dni,
email,
name,
role,
status,
} as GetMeUsersResponse,
{ status: 200 }
)
}
)
7 changes: 7 additions & 0 deletions back/src/__tests__/mocks/ssoHandlers/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export { loginHandler } from './loginHandler'
export { registerHandler, mockRegisterId } from './registerHandler'
export { validateTokenHandler } from './validateTokenHandler'
export { getMeUsersHandler as getUserHandler } from './getMeUsersHandler'
export { updateUserHandler } from './updateUserHandler'
export { listUsersHandler as getUsersNameByIdHandler } from './listUsersHandler'
export { listItinerariesHandler } from './listItinerariesHandler'
Loading

0 comments on commit d9b409d

Please sign in to comment.