From ebde70d917e06c64cf063dd7362906cca56a4aaa Mon Sep 17 00:00:00 2001 From: Aleksi Vuorjoki Date: Tue, 14 Jul 2026 16:44:24 +0300 Subject: [PATCH 1/8] Fix userFor authentication to reflect kapa reality When impersonating an ssn that has an user account the userAccountId will exist and the userdetails might also exist though in production some accounts don't have them --- packages/user-management/src/user-types.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/user-management/src/user-types.ts b/packages/user-management/src/user-types.ts index a7f7654..dfc2899 100644 --- a/packages/user-management/src/user-types.ts +++ b/packages/user-management/src/user-types.ts @@ -141,7 +141,8 @@ export const UserSchema = StoredUserDetailsSchema.extend({ ssn: zodSsn, userAccountId: z.string(), schools: z.array(UserSchoolSchema), - censorRole: CensorRoleSchema.optional() + censorRole: CensorRoleSchema.optional(), + impersonation: z.never().optional() }) export type UserToUpsert = z.infer @@ -151,7 +152,8 @@ export const UserToUpsertSchema = UserDetailsSchema.extend({ }).strict() export type ImpersonatedUser = z.infer -const ImpersonatedUserSchema = z.object({ +const ImpersonatedUserSchema = StoredUserDetailsSchema.extend({ + userAccountId: z.string().optional(), ssn: z.string(), schools: z.array(UserSchoolSchema), impersonation: ImpersonationSchema, From 19823fd8768cc906d1f79ee67ff0503aae0101a7 Mon Sep 17 00:00:00 2001 From: Aleksi Vuorjoki Date: Wed, 15 Jul 2026 14:03:15 +0300 Subject: [PATCH 2/8] Make the 3 different userForAuthentication cases clearer --- packages/user-management/src/user-types.ts | 35 +++++++++++++++------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/packages/user-management/src/user-types.ts b/packages/user-management/src/user-types.ts index dfc2899..df94325 100644 --- a/packages/user-management/src/user-types.ts +++ b/packages/user-management/src/user-types.ts @@ -143,7 +143,7 @@ export const UserSchema = StoredUserDetailsSchema.extend({ schools: z.array(UserSchoolSchema), censorRole: CensorRoleSchema.optional(), impersonation: z.never().optional() -}) +}).strict() export type UserToUpsert = z.infer export const UserToUpsertSchema = UserDetailsSchema.extend({ @@ -151,17 +151,32 @@ export const UserToUpsertSchema = UserDetailsSchema.extend({ schools: z.array(UserSchoolToUpsertSchema) }).strict() -export type ImpersonatedUser = z.infer -const ImpersonatedUserSchema = StoredUserDetailsSchema.extend({ - userAccountId: z.string().optional(), - ssn: z.string(), - schools: z.array(UserSchoolSchema), - impersonation: ImpersonationSchema, - censorRole: CensorRoleSchema.optional() -}) +export type PersonalImpersonation = z.infer +export const personalImpersonationSchema = UserSchema.extend({ + impersonation: ImpersonationSchema +}).strict() +export type SchoolImpersonation = z.infer +export const schoolImpersonationSchema = z + .object({ + impersonation: ImpersonationSchema, + ssn: z.literal('IMPERSONATED'), + schools: z + .array( + z.object({ + schoolId: z.string(), + principal: z.literal(true), + permissions: z.array(z.unknown()).max(0, "Impersonated principal doesn't have other permissions") + }) + ) + .max(1, 'Impersonated principal has one school') + }) + .strict() + +export type ImpersonatedUser = z.infer +export const ImpersonatedUserSchema = z.xor([personalImpersonationSchema, schoolImpersonationSchema]) export type UserForAuthentication = z.infer -export const UserForAuthenticationSchema = z.union([UserSchema, ImpersonatedUserSchema]) +export const UserForAuthenticationSchema = z.xor([UserSchema, ImpersonatedUserSchema]) export type UserWithSchoolRoleAndSchoolId = z.infer export const UserWithSchoolRoleAndSchoolIdSchema = z.object({ From c0751f9843b5e860af8095c64076afd204759af7 Mon Sep 17 00:00:00 2001 From: Github CI Date: Wed, 15 Jul 2026 11:50:02 +0000 Subject: [PATCH 3/8] CI: Release @digabi/2fa@3.0.0 with tag latest --- package-lock.json | 2 +- packages/2fa/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index f9d9172..338b5a6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18417,7 +18417,7 @@ }, "packages/2fa": { "name": "@digabi/2fa", - "version": "2.1.0", + "version": "3.0.0", "license": "EUPL-1.2", "dependencies": { "qr": "^0.5.2" diff --git a/packages/2fa/package.json b/packages/2fa/package.json index 67e5fab..440a914 100644 --- a/packages/2fa/package.json +++ b/packages/2fa/package.json @@ -1,6 +1,6 @@ { "name": "@digabi/2fa", - "version": "2.1.0", + "version": "3.0.0", "author": "Matriculation Examination Board, Finland", "license": "EUPL-1.2", "repository": { From 8bb0036bf53209d96c6e03e6eae4a88693bc56d5 Mon Sep 17 00:00:00 2001 From: Github CI Date: Wed, 15 Jul 2026 11:58:06 +0000 Subject: [PATCH 4/8] CI: Release @digabi/user-management@0.5.0-fixUserForAuthentication.0 with tag fixUserForAuthentication --- package-lock.json | 2 +- packages/user-management/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 338b5a6..ca38f9b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18737,7 +18737,7 @@ }, "packages/user-management": { "name": "@digabi/user-management", - "version": "0.4.0", + "version": "0.5.0-fixUserForAuthentication.0", "license": "EUPL-1.2", "dependencies": { "@digabi/validation": "^3.1.0", diff --git a/packages/user-management/package.json b/packages/user-management/package.json index d6558df..2fe96e1 100644 --- a/packages/user-management/package.json +++ b/packages/user-management/package.json @@ -1,6 +1,6 @@ { "name": "@digabi/user-management", - "version": "0.4.0", + "version": "0.5.0-fixUserForAuthentication.0", "author": "Matriculation Examination Board, Finland", "license": "EUPL-1.2", "repository": { From df8c7b6dd67e10b2eed9d384d57d58a822ecef67 Mon Sep 17 00:00:00 2001 From: Aleksi Vuorjoki Date: Wed, 15 Jul 2026 15:13:24 +0300 Subject: [PATCH 5/8] Fix casing and exports --- packages/user-management/src/user-types.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/user-management/src/user-types.ts b/packages/user-management/src/user-types.ts index df94325..7b27aca 100644 --- a/packages/user-management/src/user-types.ts +++ b/packages/user-management/src/user-types.ts @@ -151,13 +151,13 @@ export const UserToUpsertSchema = UserDetailsSchema.extend({ schools: z.array(UserSchoolToUpsertSchema) }).strict() -export type PersonalImpersonation = z.infer -export const personalImpersonationSchema = UserSchema.extend({ +export type PersonalImpersonation = z.infer +export const PersonalImpersonationSchema = UserSchema.extend({ impersonation: ImpersonationSchema }).strict() -export type SchoolImpersonation = z.infer -export const schoolImpersonationSchema = z +export type SchoolImpersonation = z.infer +export const SchoolImpersonationSchema = z .object({ impersonation: ImpersonationSchema, ssn: z.literal('IMPERSONATED'), @@ -174,7 +174,7 @@ export const schoolImpersonationSchema = z .strict() export type ImpersonatedUser = z.infer -export const ImpersonatedUserSchema = z.xor([personalImpersonationSchema, schoolImpersonationSchema]) +export const ImpersonatedUserSchema = z.xor([PersonalImpersonationSchema, SchoolImpersonationSchema]) export type UserForAuthentication = z.infer export const UserForAuthenticationSchema = z.xor([UserSchema, ImpersonatedUserSchema]) From d01ddcc48beb615de359e169a3c2f715787583dd Mon Sep 17 00:00:00 2001 From: Github CI Date: Wed, 15 Jul 2026 12:14:55 +0000 Subject: [PATCH 6/8] CI: Release @digabi/user-management@0.6.0-fixUserForAuthentication.0 with tag fixUserForAuthentication --- package-lock.json | 2 +- packages/user-management/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index ca38f9b..25db499 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18737,7 +18737,7 @@ }, "packages/user-management": { "name": "@digabi/user-management", - "version": "0.5.0-fixUserForAuthentication.0", + "version": "0.6.0-fixUserForAuthentication.0", "license": "EUPL-1.2", "dependencies": { "@digabi/validation": "^3.1.0", diff --git a/packages/user-management/package.json b/packages/user-management/package.json index 2fe96e1..80c70d1 100644 --- a/packages/user-management/package.json +++ b/packages/user-management/package.json @@ -1,6 +1,6 @@ { "name": "@digabi/user-management", - "version": "0.5.0-fixUserForAuthentication.0", + "version": "0.6.0-fixUserForAuthentication.0", "author": "Matriculation Examination Board, Finland", "license": "EUPL-1.2", "repository": { From 8b938a17918459ca8f4e63f3a662427010d35daf Mon Sep 17 00:00:00 2001 From: Aleksi Vuorjoki Date: Wed, 15 Jul 2026 16:37:05 +0300 Subject: [PATCH 7/8] Testing revealed mistakes in impersonation type --- packages/user-management/src/user-types.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/user-management/src/user-types.ts b/packages/user-management/src/user-types.ts index 7b27aca..b002db6 100644 --- a/packages/user-management/src/user-types.ts +++ b/packages/user-management/src/user-types.ts @@ -18,13 +18,13 @@ export const PrincipalOrganizationSchema = z.object({ export type Impersonation = z.infer export const ImpersonationSchema = z.object({ - id: z.number(), + id: z.uuid(), realSsn: zodSsn, - impersonatedSsn: zodSsn, + impersonatedSsn: zodSsn.or(z.literal('')), explanation: z.string(), validityStart: z.string(), validityEnd: z.string(), - schoolUuid: z.string().optional() + schoolUuid: z.string().nullish() }) export type MockUser = z.infer From 4f31cddaa2f1678efbbcc64572df92da45c6073c Mon Sep 17 00:00:00 2001 From: Github CI Date: Wed, 15 Jul 2026 13:38:23 +0000 Subject: [PATCH 8/8] CI: Release @digabi/user-management@0.6.0-fixUserForAuthentication.1 with tag fixUserForAuthentication --- package-lock.json | 2 +- packages/user-management/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 25db499..8532553 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18737,7 +18737,7 @@ }, "packages/user-management": { "name": "@digabi/user-management", - "version": "0.6.0-fixUserForAuthentication.0", + "version": "0.6.0-fixUserForAuthentication.1", "license": "EUPL-1.2", "dependencies": { "@digabi/validation": "^3.1.0", diff --git a/packages/user-management/package.json b/packages/user-management/package.json index 80c70d1..e1d4c17 100644 --- a/packages/user-management/package.json +++ b/packages/user-management/package.json @@ -1,6 +1,6 @@ { "name": "@digabi/user-management", - "version": "0.6.0-fixUserForAuthentication.0", + "version": "0.6.0-fixUserForAuthentication.1", "author": "Matriculation Examination Board, Finland", "license": "EUPL-1.2", "repository": {