From 25aeef24480c65262e48470ef81757b4ca4df870 Mon Sep 17 00:00:00 2001 From: Bright Date: Mon, 24 Feb 2025 09:29:24 +0700 Subject: [PATCH 1/3] reset password (test) --- .../OrganizationUnauthorizeController.ts | 16 +++++++++- src/keycloak/index.ts | 29 +++++++++++++++++-- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/src/controllers/OrganizationUnauthorizeController.ts b/src/controllers/OrganizationUnauthorizeController.ts index 871b6ec4..764b3b30 100644 --- a/src/controllers/OrganizationUnauthorizeController.ts +++ b/src/controllers/OrganizationUnauthorizeController.ts @@ -18,7 +18,7 @@ import { format } from "path"; import { viewProfileEvaluation } from "../entities/view/viewProfileEvaluation"; import { viewProfileEmployeeEvaluation } from "../entities/view/viewProfileEmployeeEvaluation"; import Extension from "../interfaces/extension"; - +import { resetPassword } from "../keycloak"; @Route("api/v1/org/unauthorize") @Tags("OrganizationUnauthorize") @Response( @@ -36,6 +36,20 @@ export class OrganizationUnauthorizeController extends Controller { viewProfileEmployeeEvaluation, ); + @Post("user/reset-password") + async forgetPassword( + @Body() + body: { + username: string; + }, + ) { + const result = await resetPassword(body.username); + if (!result) { + throw new Error("Failed. Cannot change password."); + } + return result; + } + /** * API รายชื่อราชการที่เลื่อนเงินเดือน (unauthorize) * diff --git a/src/keycloak/index.ts b/src/keycloak/index.ts index 26701940..fa82332c 100644 --- a/src/keycloak/index.ts +++ b/src/keycloak/index.ts @@ -4,6 +4,8 @@ const KC_URL = process.env.KC_URL; const KC_REALMS = process.env.KC_REALMS; const KC_CLIENT_ID = process.env.KC_SERVICE_ACCOUNT_CLIENT_ID; const KC_SECRET = process.env.KC_SERVICE_ACCOUNT_SECRET; +const AUTH_ACCOUNT_SECRET = process.env.AUTH_ACCOUNT_SECRET +const API_KEY = process.env.API_KEY let token: string | null = null; let decoded: DecodedJwt | null = null; @@ -765,9 +767,31 @@ export async function changeUserPassword(userId: string, newPassword: string) { // Function to reset password export async function resetPassword(username: string) { try { + if (!API_KEY || !AUTH_ACCOUNT_SECRET) { + throw new Error("KC_CLIENT_ID and KC_SECRET are required to used this feature."); + } + const body = new URLSearchParams(); + body.append("client_id", "gettoken"); + body.append("client_secret", AUTH_ACCOUNT_SECRET?.toString()); + body.append("grant_type", "client_credentials"); + const tokenResponse = await fetch(`${process.env.KC_URL}/realms/${process.env.KC_REALMS}/protocol/openid-connect/token`, { + method: "POST", + headers: { + "Content-Type": "application/x-www-form-urlencoded", + api_key: API_KEY, + }, + body: body + }); + if (!tokenResponse.ok) { + throw new Error("Failed to get admin token"); + } + const tokenData = await tokenResponse.json(); + const adminToken = tokenData.access_token; + const users = await fetch(`${KC_URL}/admin/realms/${KC_REALMS}/users?email=${encodeURIComponent(username)}`, { headers: { - "authorization": `Bearer ${await getToken()}`, + // "authorization": `Bearer ${await getToken()}`, + "authorization": `Bearer ${adminToken}`, "content-type": `application/json`, }, }); @@ -779,7 +803,8 @@ export async function resetPassword(username: string) { const resetResponse = await fetch(`${KC_URL}/admin/realms/${KC_REALMS}/users/${userId}/execute-actions-email`, { method: "PUT", headers: { - "Authorization": `Bearer ${await getToken()}`, + // "Authorization": `Bearer ${await getToken()}`, + "Authorization": `Bearer ${adminToken}`, "Content-Type": "application/json" }, body: JSON.stringify(["UPDATE_PASSWORD"]) From 0be55a03a92e0d0a11181b7e246d4c2a3acbdf61 Mon Sep 17 00:00:00 2001 From: Bright Date: Mon, 24 Feb 2025 09:55:51 +0700 Subject: [PATCH 2/3] reset password (test) --- src/keycloak/index.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/keycloak/index.ts b/src/keycloak/index.ts index fa82332c..d3c9611d 100644 --- a/src/keycloak/index.ts +++ b/src/keycloak/index.ts @@ -790,8 +790,8 @@ export async function resetPassword(username: string) { const users = await fetch(`${KC_URL}/admin/realms/${KC_REALMS}/users?email=${encodeURIComponent(username)}`, { headers: { - // "authorization": `Bearer ${await getToken()}`, - "authorization": `Bearer ${adminToken}`, + "authorization": `Bearer ${await getToken()}`, + // "authorization": `Bearer ${adminToken}`, "content-type": `application/json`, }, }); @@ -803,8 +803,8 @@ export async function resetPassword(username: string) { const resetResponse = await fetch(`${KC_URL}/admin/realms/${KC_REALMS}/users/${userId}/execute-actions-email`, { method: "PUT", headers: { - // "Authorization": `Bearer ${await getToken()}`, - "Authorization": `Bearer ${adminToken}`, + "Authorization": `Bearer ${await getToken()}`, + // "Authorization": `Bearer ${adminToken}`, "Content-Type": "application/json" }, body: JSON.stringify(["UPDATE_PASSWORD"]) From db9875a84b64ab60a995f5a35267e2981562f0d6 Mon Sep 17 00:00:00 2001 From: Bright Date: Mon, 24 Feb 2025 10:58:07 +0700 Subject: [PATCH 3/3] fix report & comment reset pass --- src/controllers/ReportController.ts | 212 ++++++++++++++-------------- src/controllers/UserController.ts | 14 -- src/keycloak/index.ts | 40 +++--- 3 files changed, 128 insertions(+), 138 deletions(-) diff --git a/src/controllers/ReportController.ts b/src/controllers/ReportController.ts index 299d67a6..9b117424 100644 --- a/src/controllers/ReportController.ts +++ b/src/controllers/ReportController.ts @@ -174,13 +174,13 @@ export class ReportController extends Controller { async registryOfficer( @Query() node?: number, @Query() nodeId?: string, - @Query() posTypeName?: string, - @Query() posLevelName?: string, + @Query() posType?: string, + @Query() posLevel?: string, @Query() position?: string, @Query() posExecutiveName?: string, @Query() gender?: string, - @Query() relationship?: string, - @Query() degree?: string, + @Query() status?: string, + @Query() education?: string, @Query() startDateAppoint?: Date, @Query() endDateAppoint?: Date, @Query() ageMin?: number, @@ -251,58 +251,60 @@ export class ReportController extends Controller { }) .andWhere(IsLeavecondition.join(" AND "), parameters) .andWhere( - new Brackets((qb) => { - qb.orWhere( - posTypeName != null && posTypeName != "" - ? "registryOfficer.posTypeName LIKE :posTypeName" - : "1=1", - { - posTypeName: `%${posTypeName}%`, - }, - ); - qb.orWhere( - posLevelName != null && posLevelName != "" - ? "registryOfficer.posLevelName LIKE :posLevelName" - : "1=1", - { - posLevelName: `%${posLevelName}%`, - }, - ); - qb.orWhere( - position != null && position != "" ? "registryOfficer.position LIKE :position" : "1=1", - { - position: `%${position}%`, - }, - ); - qb.orWhere( - posExecutiveName != null && posExecutiveName != "" - ? "registryOfficer.posExecutiveName LIKE :posExecutiveName" - : "1=1", - { - posExecutiveName: `%${posExecutiveName}%`, - }, - ); - qb.orWhere( - gender != null && gender != "" ? "registryOfficer.gender LIKE :gender" : "1=1", - { - gender: `%${gender}%`, - }, - ); - qb.orWhere( - relationship != null && relationship != "" - ? "registryOfficer.relationship LIKE :relationship" - : "1=1", - { - relationship: `%${relationship}%`, - }, - ); - qb.orWhere( - degree != null && degree != "" ? "registryOfficer.degree LIKE :degree" : "1=1", - { - degree: `%${degree}%`, - }, - ); - }), + posType != null && posType != "" + ? "registryOfficer.posTypeName LIKE :posTypeName" + : "1=1", + { + posTypeName: `%${posType}%`, + } + ) + .andWhere( + posLevel != null && posLevel != "" + ? "registryOfficer.posLevelName LIKE :posLevelName" + : "1=1", + { + posLevelName: `%${posLevel}%`, + } + ) + .andWhere( + position != null && position != "" + ? "registryOfficer.position LIKE :position" + : "1=1", + { + position: `%${position}%`, + } + ) + .andWhere( + posExecutiveName != null && posExecutiveName != "" + ? "registryOfficer.posExecutiveName LIKE :posExecutiveName" + : "1=1", + { + posExecutiveName: `%${posExecutiveName}%`, + } + ) + .andWhere( + gender != null && gender != "" + ? "registryOfficer.gender LIKE :gender" + : "1=1", + { + gender: `%${gender}%`, + } + ) + .andWhere( + status != null && status != "" + ? "registryOfficer.relationship LIKE :relationship" + : "1=1", + { + relationship: `%${status}%`, + } + ) + .andWhere( + education != null && education != "" + ? "registryOfficer.degree LIKE :degree" + : "1=1", + { + degree: `%${education}%`, + } ) .orderBy(`registryOfficer.${sortBy}`, sort) .getManyAndCount(); @@ -469,12 +471,12 @@ export class ReportController extends Controller { async registryEmployee( @Query() node?: number, @Query() nodeId?: string, - @Query() posTypeName?: string, - @Query() posLevelName?: string, + @Query() posType?: string, + @Query() posLevel?: string, @Query() position?: string, @Query() gender?: string, - @Query() relationship?: string, - @Query() degree?: string, + @Query() status?: string, + @Query() education?: string, @Query() startDateAppoint?: Date, @Query() endDateAppoint?: Date, @Query() isProbation?: boolean, @@ -545,50 +547,52 @@ export class ReportController extends Controller { .andWhere(IsLeavecondition.join(" AND "), parameters) .andWhere("registryEmployee.employeeClass = 'PERM'") .andWhere( - new Brackets((qb) => { - qb.orWhere( - posTypeName != null && posTypeName != "" - ? "registryEmployee.posTypeName LIKE :posTypeName" - : "1=1", - { - posTypeName: `%${posTypeName}%`, - }, - ); - qb.orWhere( - posLevelName != null && posLevelName != "" - ? "registryEmployee.posLevelName LIKE :posLevelName" - : "1=1", - { - posLevelName: `%${posLevelName}%`, - }, - ); - qb.orWhere( - position != null && position != "" ? "registryEmployee.position LIKE :position" : "1=1", - { - position: `%${position}%`, - }, - ); - qb.orWhere( - gender != null && gender != "" ? "registryEmployee.gender LIKE :gender" : "1=1", - { - gender: `%${gender}%`, - }, - ); - qb.orWhere( - relationship != null && relationship != "" - ? "registryEmployee.relationship LIKE :relationship" - : "1=1", - { - relationship: `%${relationship}%`, - }, - ); - qb.orWhere( - degree != null && degree != "" ? "registryEmployee.degree LIKE :degree" : "1=1", - { - degree: `%${degree}%`, - }, - ); - }), + posType != null && posType != "" + ? "registryOfficer.posTypeName LIKE :posTypeName" + : "1=1", + { + posTypeName: `%${posType}%`, + } + ) + .andWhere( + posLevel != null && posLevel != "" + ? "registryOfficer.posLevelName LIKE :posLevelName" + : "1=1", + { + posLevelName: `%${posLevel}%`, + } + ) + .andWhere( + position != null && position != "" + ? "registryOfficer.position LIKE :position" + : "1=1", + { + position: `%${position}%`, + } + ) + .andWhere( + gender != null && gender != "" + ? "registryOfficer.gender LIKE :gender" + : "1=1", + { + gender: `%${gender}%`, + } + ) + .andWhere( + status != null && status != "" + ? "registryOfficer.relationship LIKE :relationship" + : "1=1", + { + relationship: `%${status}%`, + } + ) + .andWhere( + education != null && education != "" + ? "registryOfficer.degree LIKE :degree" + : "1=1", + { + degree: `%${education}%`, + } ) .orderBy(`registryEmployee.${sortBy}`, sort) .getManyAndCount(); diff --git a/src/controllers/UserController.ts b/src/controllers/UserController.ts index be68be2a..4dd90dbf 100644 --- a/src/controllers/UserController.ts +++ b/src/controllers/UserController.ts @@ -830,18 +830,4 @@ export class KeycloakController extends Controller { return result; } - @Post("user/reset-password") - async forgetPassword( - @Request() request: { user: { sub: string; preferred_username: string } }, - @Body() - body: { - username: string; - }, - ) { - const result = await resetPassword(body.username); - if (!result) { - throw new Error("Failed. Cannot change password."); - } - return result; - } } diff --git a/src/keycloak/index.ts b/src/keycloak/index.ts index d3c9611d..1297b70f 100644 --- a/src/keycloak/index.ts +++ b/src/keycloak/index.ts @@ -767,26 +767,26 @@ export async function changeUserPassword(userId: string, newPassword: string) { // Function to reset password export async function resetPassword(username: string) { try { - if (!API_KEY || !AUTH_ACCOUNT_SECRET) { - throw new Error("KC_CLIENT_ID and KC_SECRET are required to used this feature."); - } - const body = new URLSearchParams(); - body.append("client_id", "gettoken"); - body.append("client_secret", AUTH_ACCOUNT_SECRET?.toString()); - body.append("grant_type", "client_credentials"); - const tokenResponse = await fetch(`${process.env.KC_URL}/realms/${process.env.KC_REALMS}/protocol/openid-connect/token`, { - method: "POST", - headers: { - "Content-Type": "application/x-www-form-urlencoded", - api_key: API_KEY, - }, - body: body - }); - if (!tokenResponse.ok) { - throw new Error("Failed to get admin token"); - } - const tokenData = await tokenResponse.json(); - const adminToken = tokenData.access_token; + // if (!API_KEY || !AUTH_ACCOUNT_SECRET) { + // throw new Error("KC_CLIENT_ID and KC_SECRET are required to used this feature."); + // } + // const body = new URLSearchParams(); + // body.append("client_id", "gettoken"); + // body.append("client_secret", AUTH_ACCOUNT_SECRET?.toString()); + // body.append("grant_type", "client_credentials"); + // const tokenResponse = await fetch(`${process.env.KC_URL}/realms/${process.env.KC_REALMS}/protocol/openid-connect/token`, { + // method: "POST", + // headers: { + // "Content-Type": "application/x-www-form-urlencoded", + // api_key: API_KEY, + // }, + // body: body + // }); + // if (!tokenResponse.ok) { + // throw new Error("Failed to get admin token"); + // } + // const tokenData = await tokenResponse.json(); + // const adminToken = tokenData.access_token; const users = await fetch(`${KC_URL}/admin/realms/${KC_REALMS}/users?email=${encodeURIComponent(username)}`, { headers: {