diff --git a/package.json b/package.json
index 8b36cb3a8..e7092fa17 100644
--- a/package.json
+++ b/package.json
@@ -19,7 +19,7 @@
"docker:dobbelOmega:run": "docker compose -f docker-compose.dev.yml exec projectnext /bin/sh -c 'npm run dobbelOmega:run'",
"docker:seed": "docker compose -f docker-compose.dev.yml exec projectnext /bin/sh -c 'npm run seed'",
"seed": "npx prisma db push --force-reset --skip-generate && IGNORE_SERVER_ONLY=true npx prisma db seed",
- "dev-seed": "(if [ ! -d './node_modules/.prisma-dobbel-omega' ]; then npm run dobbelOmega-generate; fi) && npm run seed && npm run dev"
+ "dev-seed": "(if [ ! -d './node_modules/.prisma-dobbel-omega' ]; then npm run dobbelOmega:generate; fi) && npm run seed && npm run dev"
},
"prisma": {
"schema": "src/prisma/schema",
diff --git a/src/app/api/users/connectStudentCard/route.ts b/src/app/api/users/connectStudentCard/route.ts
deleted file mode 100644
index 6ce1703b6..000000000
--- a/src/app/api/users/connectStudentCard/route.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import { apiHandler } from '@/api/apiHandler'
-import { userOperations } from '@/services/users/operations'
-
-
-export const POST = apiHandler({
- serviceOperation: userOperations.connectStudentCard
-})
diff --git a/src/app/connect-student-card/[newCard]/page.tsx b/src/app/connect-student-card/[newCard]/page.tsx
new file mode 100644
index 000000000..c01c6326f
--- /dev/null
+++ b/src/app/connect-student-card/[newCard]/page.tsx
@@ -0,0 +1,32 @@
+import Form from '@/components/Form/Form'
+import PageWrapper from '@/components/PageWrapper/PageWrapper'
+import { configureAction } from '@/services/configureAction'
+import { connectStudentCardAction } from '@/services/users/actions'
+
+
+export default async function ConnectStucentCard({ params }: { params: Promise<{ newCard: string }> }) {
+ const newCard = (await params).newCard
+
+ const cardParsed = parseInt(newCard, 10)
+
+ if (isNaN(cardParsed)) {
+ return
Kortet er ikke gyldig. Det må være et heltall.
+ }
+
+
+ return
@@ -111,7 +111,7 @@ export default async function Event({ params }: PropTypes) {
{event.waitingList &&
På venteliste: {event.numOnWaitingList}
}
-
+
> :
Dette arrangementet tar ikke påmeldinger
diff --git a/src/app/users/[username]/(user-admin)/settings/RegisterStudentCardButton.tsx b/src/app/users/[username]/(user-admin)/settings/RegisterStudentCardButton.tsx
deleted file mode 100644
index ca098eb37..000000000
--- a/src/app/users/[username]/(user-admin)/settings/RegisterStudentCardButton.tsx
+++ /dev/null
@@ -1,24 +0,0 @@
-'use client'
-import { registerStudentCardInQueueAction } from '@/services/users/actions'
-import { configureAction } from '@/services/configureAction'
-import Form from '@/app/_components/Form/Form'
-import { studentCardRegistrationExpiry } from '@/services/users/constants'
-
-
-export default function RegisterStudentCardButton({
- userId,
-}: {
- userId: number,
-}) {
- return
-}
diff --git a/src/app/users/[username]/(user-admin)/settings/page.tsx b/src/app/users/[username]/(user-admin)/settings/page.tsx
index ffefa3d44..98a53a843 100644
--- a/src/app/users/[username]/(user-admin)/settings/page.tsx
+++ b/src/app/users/[username]/(user-admin)/settings/page.tsx
@@ -1,4 +1,3 @@
-import RegisterStudentCardButton from './RegisterStudentCardButton'
import { getProfileForAdmin } from '@/app/users/[username]/(user-admin)/getProfileForAdmin'
import Image from '@/components/Image/Image'
import type { PropTypes } from '@/app/users/[username]/page'
@@ -10,7 +9,6 @@ export default async function UserSettings({ params }: PropTypes) {
Generelle Instillinger
-
)
}
diff --git a/src/prisma/schema/permission.prisma b/src/prisma/schema/permission.prisma
index 918d9021a..347105e96 100644
--- a/src/prisma/schema/permission.prisma
+++ b/src/prisma/schema/permission.prisma
@@ -71,8 +71,6 @@ enum Permission {
USERS_DESTROY
USERS_CREATE
- USERS_CONNECT_STUDENT_CARD
-
IMAGE_COLLECTION_CREATE
IMAGE_ADMIN
diff --git a/src/prisma/schema/user.prisma b/src/prisma/schema/user.prisma
index c31cd5548..ffe30f225 100644
--- a/src/prisma/schema/user.prisma
+++ b/src/prisma/schema/user.prisma
@@ -37,7 +37,6 @@ model User {
dots DotWrapper[] @relation(name: "dot_user")
dotsAccused DotWrapper[] @relation(name: "dot_accuser")
- registerStudentCardQueue RegisterStudentCardQueue[]
Event Event[]
cabinBooking Booking[] @relation()
@@ -70,12 +69,6 @@ model FeideAccount {
user User @relation(fields: [userId], references: [id], onDelete: Cascade, onUpdate: Cascade)
}
-model RegisterStudentCardQueue {
- userId Int @id
- user User @relation(fields: [userId], references: [id], onDelete: Cascade)
- expiry DateTime
-}
-
model ContactDetails {
id Int @id @default(autoincrement())
name String
diff --git a/src/prisma/seeder/src/dobbelOmega/migrateCommittees.ts b/src/prisma/seeder/src/dobbelOmega/migrateCommittees.ts
index 0ba09d88b..01ba4bf81 100644
--- a/src/prisma/seeder/src/dobbelOmega/migrateCommittees.ts
+++ b/src/prisma/seeder/src/dobbelOmega/migrateCommittees.ts
@@ -59,13 +59,13 @@ export default async function migrateCommittees(
// })).order
await Promise.all(committees.map(async committee => {
- const committeeParagraph = await readCommitteParagraph(`${committee.shortName}_p.md`)
- const committeArticle = await readCommitteArticle(`${committee.shortName}_a.md`)
+ const committeeParagraph = await readCommitteParagraph(`${committee.shortname}_p.md`)
+ const committeArticle = await readCommitteArticle(`${committee.shortname}_a.md`)
const newCommittee = await pnPrisma.committee.create({
data: {
name: committee.name,
- shortName: committee.shortName,
+ shortName: committee.shortname,
videoLink: committee.applicationVideo,
logoImage: {
create: {
@@ -85,7 +85,7 @@ export default async function migrateCommittees(
name: committee.name,
coverImage: {
create: {
- name: `${committee.shortName}'s bilde`
+ name: `${committee.shortname}'s bilde`
}
},
articleSections: committeArticle
@@ -102,7 +102,7 @@ export default async function migrateCommittees(
await Promise.all(committee.CommitteeMembers.map(async member => {
if (member.UserId === null) {
- console.warn(`${committee.shortName} has a member that is not connected to a user!`)
+ console.warn(`${committee.shortname} has a member that is not connected to a user!`)
console.warn(member)
return
}
diff --git a/src/prisma/seeder/src/dobbelOmega/migrateUsers.ts b/src/prisma/seeder/src/dobbelOmega/migrateUsers.ts
index 9668819be..111e6d164 100644
--- a/src/prisma/seeder/src/dobbelOmega/migrateUsers.ts
+++ b/src/prisma/seeder/src/dobbelOmega/migrateUsers.ts
@@ -38,10 +38,16 @@ type ExtendedMemberGroup = Prisma.OmegaMembershipGroupGetPayload<{
const userIncluder = {
StudyProgrammes: {
select: {
- years: true
- }
- }
-}
+ years: true,
+ },
+ },
+ MoneySourceAccounts: {
+ select: {
+ NTNUCard: true,
+ },
+ },
+} satisfies VevenPrisma.UsersInclude
+
type userExtended = VevenPrisma.UsersGetPayload<{
include: typeof userIncluder
}>
@@ -192,7 +198,8 @@ export class UserMigrator {
updatedAt: user.updatedAt,
imageId: vevenIdToPnId(this.imageIdMap, user.ImageId),
archived: user.archived,
- }
+ } satisfies Prisma.UserUncheckedCreateInput
+
try {
pnUser = await this.pnPrisma.user.create({
data: userData
@@ -215,6 +222,25 @@ export class UserMigrator {
}
this.userIdMap[user.id] = pnUser.id
+ // Try to add the studentCard, this can throw an unique contraint exception
+ if (user.MoneySourceAccounts?.NTNUCard) {
+ try {
+ await this.pnPrisma.user.update({
+ where: {
+ id: pnUser.id
+ },
+ data: {
+ studentCard: user.MoneySourceAccounts?.NTNUCard
+ }
+ })
+ } catch (e) {
+ console.error(
+ `Failed to conenct StudentCard to user. StudentCard: ${user.MoneySourceAccounts?.NTNUCard} `,
+ `User: ${pnUser} Error: ${e}`
+ )
+ }
+ }
+
return pnUser
}
diff --git a/src/prisma/vevenSchema/schema.veven.prisma b/src/prisma/vevenSchema/schema.veven.prisma
index 78fb22d53..94c375c25 100644
--- a/src/prisma/vevenSchema/schema.veven.prisma
+++ b/src/prisma/vevenSchema/schema.veven.prisma
@@ -1,13 +1,13 @@
-datasource db {
- provider = "postgresql"
- url = env("VEVEN_DB_URI")
-}
-
generator veven {
provider = "prisma-client-js"
output = "../../../node_modules/.prisma-dobbel-omega"
}
+datasource db {
+ provider = "postgresql"
+ url = env("VEVEN_DB_URI")
+}
+
model AliasAssociations {
MailAliasId Int
UserId Int
@@ -109,7 +109,7 @@ model CommitteeMembersHist {
model Committees {
id Int @id @default(autoincrement())
name String @db.VarChar(255)
- shortName String @unique @db.VarChar(255)
+ shortname String @unique @db.VarChar(255)
applicationLead String?
applicationVideo String? @db.VarChar(255)
applicationText String?
@@ -509,7 +509,7 @@ model PollVotes {
model Polls {
id Int @id @default(autoincrement())
question String
- deadline DateTime @default(dbgenerated("'2022-10-17 19:43:15.587+02'::timestamp with time zone")) @db.Timestamptz(6)
+ deadline DateTime @default(dbgenerated("'2022-10-17 17:43:15.587+00'::timestamp with time zone")) @db.Timestamptz(6)
anonymous Boolean @default(false)
allow enum_Polls_allow @default(everyone)
createdAt DateTime @db.Timestamptz(6)
diff --git a/src/services/permissions/constants.ts b/src/services/permissions/constants.ts
index 51abb9070..e90e0fe40 100644
--- a/src/services/permissions/constants.ts
+++ b/src/services/permissions/constants.ts
@@ -206,12 +206,6 @@ export const permissionConfig = {
description: 'kan oppdatere bruker',
category: 'brukere',
},
- USERS_CONNECT_STUDENT_CARD: {
- name: 'Koble studentkort til andre brukere',
- description: `Kan legge til andre personer i registreringskøen for å
- registrere et kort og kan registrere et kort på en person`,
- category: 'brukere'
- },
IMAGE_ADMIN: {
name: 'Bildeadministrator',
description: 'kan administrere bilder',
diff --git a/src/services/users/actions.ts b/src/services/users/actions.ts
index 17de12e36..04fb4edd1 100644
--- a/src/services/users/actions.ts
+++ b/src/services/users/actions.ts
@@ -41,4 +41,5 @@ export const readGroupsForPageFilteringAction = makeAction(groupOperations.readG
export const updateUserAction = makeAction(userOperations.update)
export const registerNewEmailAction = makeAction(userOperations.registerNewEmail)
export const registerUser = makeAction(userOperations.register)
-export const registerStudentCardInQueueAction = makeAction(userOperations.registerStudentCardInQueue)
+
+export const connectStudentCardAction = makeAction(userOperations.connectStudentCard)
diff --git a/src/services/users/auth.ts b/src/services/users/auth.ts
index 6ca87888c..a52e56514 100644
--- a/src/services/users/auth.ts
+++ b/src/services/users/auth.ts
@@ -1,4 +1,5 @@
import { RequirePermission } from '@/auth/auther/RequirePermission'
+import { RequireUser } from '@/auth/auther/RequireUser'
import { RequireUserFieldOrPermission } from '@/auth/auther/RequireUserFieldOrPermission'
import { RequireUserId } from '@/auth/auther/RequireUserId'
import { RequireUserIdOrPermission } from '@/auth/auther/RequireUserIdOrPermission'
@@ -10,8 +11,7 @@ export const userAuth = {
readOrNull: RequireUserFieldOrPermission.staticFields({ permission: 'USERS_READ' }),
readPage: RequirePermission.staticFields({ permission: 'USERS_READ' }),
create: RequirePermission.staticFields({ permission: 'USERS_CREATE' }),
- connectStudentCard: RequirePermission.staticFields({ permission: 'USERS_CONNECT_STUDENT_CARD' }),
- registerStudentCardInQueue: RequireUserIdOrPermission.staticFields({ permission: 'USERS_CONNECT_STUDENT_CARD' }),
+ connectStudentCard: RequireUser.staticFields({}),
registerNewEmail: RequireUserIdOrPermission.staticFields({ permission: 'USERS_UPDATE' }),
updatePassword: RequireUserIdOrPermission.staticFields({ permission: 'USERS_UPDATE' }),
update: RequirePermission.staticFields({ permission: 'USERS_UPDATE' }),
diff --git a/src/services/users/constants.ts b/src/services/users/constants.ts
index fd21e4d5e..308aeae12 100644
--- a/src/services/users/constants.ts
+++ b/src/services/users/constants.ts
@@ -2,7 +2,6 @@ import { createSelection } from '@/services/createSelection'
import type { Prisma, User, SEX } from '@prisma/client'
export const maxNumberOfGroupsInFilter = 7
-export const studentCardRegistrationExpiry = 2 // minutter
// TODO: This needs to be divived into seperate filters, depending on how much information is needed
export const userFieldsToExpose = [
diff --git a/src/services/users/operations.ts b/src/services/users/operations.ts
index d25a69f69..502023505 100644
--- a/src/services/users/operations.ts
+++ b/src/services/users/operations.ts
@@ -4,7 +4,6 @@ import { userAuth } from './auth'
import {
maxNumberOfGroupsInFilter,
standardMembershipSelection,
- studentCardRegistrationExpiry,
userFilterSelection
} from './constants'
import { imageOperations } from '@/services/images/operations'
@@ -296,71 +295,20 @@ export const userOperations = {
connectStudentCard: defineOperation({
authorizer: () => userAuth.connectStudentCard.dynamicFields({}),
- dataSchema: userSchemas.connectStudentCard,
- opensTransaction: true,
- operation: async ({ prisma, data }) => {
- const currentQueue = await prisma.registerStudentCardQueue.findMany({
- where: {
- expiry: {
- gt: new Date(),
- },
- },
- orderBy: {
- expiry: 'desc',
- },
- take: 1,
- })
-
- if (currentQueue.length === 0) {
- throw new ServerError(
- 'NOT FOUND',
- `No user has placed them selves in the registration queue at ${process.env.DOMAIN}`
- )
- }
-
- const userId = currentQueue[0].userId
- const result = await prisma.$transaction([
- prisma.registerStudentCardQueue.delete({
- where: {
- userId,
- }
- }),
- prisma.user.update({
- where: {
- id: userId,
- },
- data: {
- studentCard: data.studentCard,
- },
- select: userFilterSelection,
- })
- ])
-
- return result[1]
- }
- }),
-
- registerStudentCardInQueue: defineOperation({
paramsSchema: z.object({
- userId: z.number(),
+ studentCard: z.coerce.number().int().min(0).optional(),
}),
- authorizer: ({ params }) => userAuth.registerStudentCardInQueue.dynamicFields(params),
- operation: async (args) => {
- const expiry = (new Date()).getTime() + studentCardRegistrationExpiry * 60 * 1000
- await args.prisma.registerStudentCardQueue.upsert({
+ operation: async ({ prisma, params, session }) => {
+ if (!session.user) {
+ throw new ServerError('DISSALLOWED', 'This endpoint requires a user conencted to the session.')
+ }
+
+ await prisma.user.update({
where: {
- userId: args.params.userId,
- },
- update: {
- expiry: new Date(expiry),
+ id: session.user.id
},
- create: {
- user: {
- connect: {
- id: args.params.userId,
- },
- },
- expiry: new Date(expiry),
+ data: {
+ studentCard: params.studentCard?.toString()
}
})
}
@@ -587,6 +535,12 @@ export const userOperations = {
}
})
+ if (!user.image) {
+ user.image = await imageOperations.readSpecial({
+ params: { special: 'DEFAULT_PROFILE_IMAGE' },
+ })
+ }
+
return {
balance: 191900,
user,