From 058b075db415857df401fcf28258c58b0bf18f95 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Mon, 2 Oct 2023 09:33:56 +0300 Subject: [PATCH 001/146] Creat the types --- types/organizationAdmin.ts | 11 +++++++++++ types/organizationProfile.ts | 10 ++++++++++ types/permission.ts | 9 +++++++++ types/role.ts | 17 +++++++++++++++++ types/skillTag.ts | 8 ++++++++ types/volunteer.ts | 35 +++++++++++++++++++++++++++++++++++ types/volunteryWork.ts | 22 ++++++++++++++++++++++ 7 files changed, 112 insertions(+) create mode 100644 types/organizationAdmin.ts create mode 100644 types/organizationProfile.ts create mode 100644 types/permission.ts create mode 100644 types/role.ts create mode 100644 types/skillTag.ts create mode 100644 types/volunteer.ts create mode 100644 types/volunteryWork.ts diff --git a/types/organizationAdmin.ts b/types/organizationAdmin.ts new file mode 100644 index 00000000..dd805114 --- /dev/null +++ b/types/organizationAdmin.ts @@ -0,0 +1,11 @@ +export namespace NSOrganizationAdmin { + + export interface Item { + id?: string; + name: string; + email: string; + password: string; + organizationId: string; + createdAt?: Date; + } +} diff --git a/types/organizationProfile.ts b/types/organizationProfile.ts new file mode 100644 index 00000000..f98b8da9 --- /dev/null +++ b/types/organizationProfile.ts @@ -0,0 +1,10 @@ +export namespace NSOrganizationProfile { + + export interface Item { + id?: string; + name: string; + email: string; + description:string; + createdAt?: Date; + } +} diff --git a/types/permission.ts b/types/permission.ts new file mode 100644 index 00000000..2de5ca37 --- /dev/null +++ b/types/permission.ts @@ -0,0 +1,9 @@ +export namespace NSPermission { + + export interface Item{ + id?: string, + name:string, + rolesIds?:string[], + createdAt?:Date + } +} \ No newline at end of file diff --git a/types/role.ts b/types/role.ts new file mode 100644 index 00000000..5494a499 --- /dev/null +++ b/types/role.ts @@ -0,0 +1,17 @@ +export namespace NSRole { + export enum Type { + root = 'root', + admin = 'admin', + normal = 'normal', + premium = 'premium' + } + + export interface Item { + id?: string, + name: Type, + createdAt?: Date, + permissionsId: string[], + volunteerId?: string[], + organizationAdmin?: string[] + } +} \ No newline at end of file diff --git a/types/skillTag.ts b/types/skillTag.ts new file mode 100644 index 00000000..54b26c09 --- /dev/null +++ b/types/skillTag.ts @@ -0,0 +1,8 @@ +export namespace NSSkillTag { + + export interface Item { + id?: string; + name: string; + createdAt?: Date; + } +} diff --git a/types/volunteer.ts b/types/volunteer.ts new file mode 100644 index 00000000..4186bbb8 --- /dev/null +++ b/types/volunteer.ts @@ -0,0 +1,35 @@ +export namespace NSVolunteer { + + export enum TypeVolunteer { + normal = "normal", + premium = "premium" + } + + export enum AvailableTime { + Morning = 'Morning', + Afternoon = 'Afternoon' + } + + export enum AvailableDays { + Sunday = 'Sunday', + Monday = 'Monday', + Tuesday = 'Tuesday', + Wednesday = 'Wednesday', + Thursday = 'Thursday', + Friday = 'Friday', + Saturday = 'Saturday', + } + + export interface Item { + id?: string; + name: string; + email: string; + password: string; + createdAt?: Date; + type: TypeVolunteer; + availableTime: [AvailableTime]; + availableLocation: string; + PreferredActivities: [string]; + availableDays: [AvailableDays]; + } +} diff --git a/types/volunteryWork.ts b/types/volunteryWork.ts new file mode 100644 index 00000000..0a454396 --- /dev/null +++ b/types/volunteryWork.ts @@ -0,0 +1,22 @@ +export namespace NSVoluntaryWork { + + export enum StatusType { + Pending = 'Pending', + InProgress = 'In Progress', + Finished = 'Finished', + Canceled = 'Canceled' + } + + export interface Item { + id?: string; + name: string; + description: string; + location: string; + time: string; + images: string; + rating: number; + feedback: string; + status: StatusType; + createdAt?: Date; + } +} From 406c2f9af6fb722d5369a7bc12e5e57a91a81685 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Mon, 2 Oct 2023 17:11:06 +0300 Subject: [PATCH 002/146] Edit the exiteing types and addind aditional attributes --- types/organizationProfile.ts | 2 +- types/permission.ts | 8 ++++---- types/volunteer.ts | 10 +++++----- types/volunteryWork.ts | 7 ++++++- 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/types/organizationProfile.ts b/types/organizationProfile.ts index f98b8da9..08f29839 100644 --- a/types/organizationProfile.ts +++ b/types/organizationProfile.ts @@ -4,7 +4,7 @@ export namespace NSOrganizationProfile { id?: string; name: string; email: string; - description:string; + description: string; createdAt?: Date; } } diff --git a/types/permission.ts b/types/permission.ts index 2de5ca37..5394b6a9 100644 --- a/types/permission.ts +++ b/types/permission.ts @@ -1,9 +1,9 @@ export namespace NSPermission { - export interface Item{ + export interface Item { id?: string, - name:string, - rolesIds?:string[], - createdAt?:Date + name: string, + rolesIds?: string[], + createdAt?: Date } } \ No newline at end of file diff --git a/types/volunteer.ts b/types/volunteer.ts index 4186bbb8..b19f4536 100644 --- a/types/volunteer.ts +++ b/types/volunteer.ts @@ -1,7 +1,7 @@ export namespace NSVolunteer { export enum TypeVolunteer { - normal = "normal", + volunteer = "volunteer", premium = "premium" } @@ -27,9 +27,9 @@ export namespace NSVolunteer { password: string; createdAt?: Date; type: TypeVolunteer; - availableTime: [AvailableTime]; + availableTime: AvailableTime[]; availableLocation: string; - PreferredActivities: [string]; - availableDays: [AvailableDays]; + PreferredActivities: string[]; + availableDays: AvailableDays[]; } -} +} \ No newline at end of file diff --git a/types/volunteryWork.ts b/types/volunteryWork.ts index 0a454396..9063fb19 100644 --- a/types/volunteryWork.ts +++ b/types/volunteryWork.ts @@ -1,3 +1,5 @@ +import { NSVolunteer } from "./volunteer.js"; + export namespace NSVoluntaryWork { export enum StatusType { @@ -12,11 +14,14 @@ export namespace NSVoluntaryWork { name: string; description: string; location: string; - time: string; + time: NSVolunteer.AvailableTime[]; images: string; rating: number; feedback: string; status: StatusType; createdAt?: Date; + days: NSVolunteer.AvailableDays[]; + startedDate: Date; + finishedDate: Date; } } From 9a16488f67472326e6fb18787bcccac6f2f5acec Mon Sep 17 00:00:00 2001 From: TarteelTamimi Date: Tue, 3 Oct 2023 05:10:02 +0300 Subject: [PATCH 003/146] add entities --- src/db/dataSource.ts | 13 +++-- src/db/entities/OrganizationAdmin.ts | 38 +++++++++++++ src/db/entities/OrganizationProfile.ts | 23 ++++++++ src/db/entities/Permission.ts | 21 ++++++++ src/db/entities/Role.ts | 34 ++++++++++++ src/db/entities/SkillTag.ts | 26 +++++++++ src/db/entities/VoluntaryWork.ts | 75 ++++++++++++++++++++++++++ src/db/entities/Volunteer.ts | 46 ++++++++++++++++ src/db/entities/VolunteerProfile.ts | 43 +++++++++++++++ 9 files changed, 316 insertions(+), 3 deletions(-) create mode 100644 src/db/entities/OrganizationAdmin.ts create mode 100644 src/db/entities/OrganizationProfile.ts create mode 100644 src/db/entities/Permission.ts create mode 100644 src/db/entities/Role.ts create mode 100644 src/db/entities/SkillTag.ts create mode 100644 src/db/entities/VoluntaryWork.ts create mode 100644 src/db/entities/Volunteer.ts create mode 100644 src/db/entities/VolunteerProfile.ts diff --git a/src/db/dataSource.ts b/src/db/dataSource.ts index f107c65e..f62be3d5 100644 --- a/src/db/dataSource.ts +++ b/src/db/dataSource.ts @@ -1,4 +1,12 @@ import { DataSource } from "typeorm"; +import { OrganizationAdmin } from "./entities/OrganizationAdmin.js"; +import { OrganizationProfile } from "./entities/OrganizationProfile.js"; +import { Permission } from "./entities/Permission.js"; +import { Role } from "./entities/Role.js"; +import { SkillTag } from "./entities/SkillTag.js"; +import { VoluntartyWork } from "./entities/VoluntaryWork.js"; +import { Volunteer } from "./entities/Volunteer.js"; +import { VolunteerProfile } from "./entities/VolunteerProfile.js"; const dataSource = new DataSource({ type: 'mysql', @@ -7,9 +15,8 @@ const dataSource = new DataSource({ username: process.env.DB_USERNAME, password: process.env.DB_PASSWORD, database: process.env.DB_NAME, - entities: [ - - ], + entities: [OrganizationAdmin, OrganizationProfile, Permission, + Role, SkillTag, VoluntartyWork, Volunteer, VolunteerProfile], migrations: ['./**/migration/*.ts'], synchronize: true, logging: false diff --git a/src/db/entities/OrganizationAdmin.ts b/src/db/entities/OrganizationAdmin.ts new file mode 100644 index 00000000..0258219c --- /dev/null +++ b/src/db/entities/OrganizationAdmin.ts @@ -0,0 +1,38 @@ +import { BaseEntity, BeforeInsert, Column, CreateDateColumn, Entity, JoinColumn, ManyToOne, OneToOne, PrimaryGeneratedColumn } from "typeorm"; +import bcrypt from 'bcrypt'; +import { Role } from "./Role.js"; +import { OrganizationProfile } from "./OrganizationProfile.js"; + +@Entity() +export class OrganizationAdmin extends BaseEntity { + @PrimaryGeneratedColumn('uuid') + id: string; + + @Column({ length: 255, nullable: false }) + name: string; + + @Column({ nullable: false }) + email: string; + + @BeforeInsert() + async hashPassword() { + if (this.password) { + this.password = await bcrypt.hash(this.password, 10) + } + } + @Column({ nullable: false }) + password: string; + + @OneToOne(() => OrganizationProfile, {cascade: true, onDelete:"CASCADE"}) + @JoinColumn() + orgProfile: OrganizationProfile; + + @ManyToOne(() => Role, role => role.orgAdmins) + roles: Role; + + @CreateDateColumn({ + type: 'timestamp', + default: () => "CURRENT_TIMESTAMP(6)" + }) + createdAt: Date; +} \ No newline at end of file diff --git a/src/db/entities/OrganizationProfile.ts b/src/db/entities/OrganizationProfile.ts new file mode 100644 index 00000000..080390ae --- /dev/null +++ b/src/db/entities/OrganizationProfile.ts @@ -0,0 +1,23 @@ +import { BaseEntity, Column, CreateDateColumn, Entity, OneToMany, PrimaryGeneratedColumn } from "typeorm"; +import { VoluntartyWork } from "./VoluntaryWork.js"; + +@Entity() +export class OrganizationProfile extends BaseEntity { + @PrimaryGeneratedColumn('uuid') + id: string; + + @Column({ length: 255, nullable: false }) + name: string; + + @Column({nullable: false}) + description: string; + + @OneToMany(() => VoluntartyWork, voluntartyWork => voluntartyWork.orgProfiles) + voluntaryWork: VoluntartyWork[]; + + @CreateDateColumn({ + type: 'timestamp', + default: () => "CURRENT_TIMESTAMP(6)" + }) + createdAt: Date; +} \ No newline at end of file diff --git a/src/db/entities/Permission.ts b/src/db/entities/Permission.ts new file mode 100644 index 00000000..b0177c43 --- /dev/null +++ b/src/db/entities/Permission.ts @@ -0,0 +1,21 @@ +import { BaseEntity, Column, CreateDateColumn, Entity, JoinTable, ManyToMany, PrimaryGeneratedColumn } from "typeorm"; +import { Role } from "./Role.js"; + +@Entity() +export class Permission extends BaseEntity { + @PrimaryGeneratedColumn('increment') + id: number; + + @Column({ unique: true }) + name: string; + + @ManyToMany(() => Role) + @JoinTable() + roles: Role[]; + + @CreateDateColumn({ + type: 'timestamp', + default: () => "CURRENT_TIMESTAMP(6)" + }) + createdAt: Date; +} \ No newline at end of file diff --git a/src/db/entities/Role.ts b/src/db/entities/Role.ts new file mode 100644 index 00000000..3e37a782 --- /dev/null +++ b/src/db/entities/Role.ts @@ -0,0 +1,34 @@ +import { BaseEntity, Column, CreateDateColumn, Entity, JoinTable, ManyToMany, OneToMany, PrimaryGeneratedColumn } from "typeorm"; +import { Permission } from "./Permission.js"; +import { Volunteer } from "./Volunteer.js"; +import { OrganizationAdmin } from "./OrganizationAdmin.js"; + +@Entity() +export class Role extends BaseEntity { + @PrimaryGeneratedColumn('increment') + id: number; + + @Column({ + type: 'enum', + enum: ['root', 'admin', 'volunteer', 'premium'], + default: 'volunteer' + }) + name: 'root' | 'admin' | 'volunteer' | 'premium'; + + @ManyToMany(() => Volunteer) + @JoinTable() + volunteers: Volunteer[]; + + @ManyToMany(() => Permission) + @JoinTable() + permissions: Permission[]; + + @OneToMany(() => OrganizationAdmin, organizationAdmin => organizationAdmin.roles) + orgAdmins: OrganizationAdmin[]; + + @CreateDateColumn({ + type: 'timestamp', + default: () => "CURRENT_TIMESTAMP(6)" + }) + createdAt: Date; +} \ No newline at end of file diff --git a/src/db/entities/SkillTag.ts b/src/db/entities/SkillTag.ts new file mode 100644 index 00000000..6b0cb260 --- /dev/null +++ b/src/db/entities/SkillTag.ts @@ -0,0 +1,26 @@ +import { BaseEntity, Column, CreateDateColumn, Entity, JoinTable, ManyToMany, PrimaryGeneratedColumn } from "typeorm"; +import { VolunteerProfile } from "./VolunteerProfile.js"; +import { VoluntartyWork } from "./VoluntaryWork.js"; + +@Entity() +export class SkillTag extends BaseEntity { + @PrimaryGeneratedColumn('increment') + id: number; + + @Column({ unique: true }) + name: string; + + @ManyToMany(() => VolunteerProfile) + @JoinTable() + volunteerProfiles: VolunteerProfile[]; + + @ManyToMany(() => VoluntartyWork) + @JoinTable() + roles: VoluntartyWork[]; + + @CreateDateColumn({ + type: 'timestamp', + default: () => "CURRENT_TIMESTAMP(6)" + }) + createdAt: Date; +} \ No newline at end of file diff --git a/src/db/entities/VoluntaryWork.ts b/src/db/entities/VoluntaryWork.ts new file mode 100644 index 00000000..7e54d536 --- /dev/null +++ b/src/db/entities/VoluntaryWork.ts @@ -0,0 +1,75 @@ +import { BaseEntity, Column, CreateDateColumn, Entity, JoinTable, ManyToMany, ManyToOne, PrimaryGeneratedColumn } from "typeorm"; +import { SkillTag } from "./SkillTag.js"; +import { VolunteerProfile } from "./VolunteerProfile.js"; +import { OrganizationProfile } from "./OrganizationProfile.js"; + +@Entity() +export class VoluntartyWork extends BaseEntity { + @PrimaryGeneratedColumn('increment') + id: number; + + @Column({ unique: true, nullable: false }) + name: string; + + @Column({ nullable: false }) + description: string; + + @Column({ + type: 'enum', + enum: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], + nullable: false + }) + day: 'Sunday' | 'Monday' | 'Tuesday' | 'Wednesday' | 'Thursday' | 'Friday' | 'Saturday'; + + @Column({ + type: 'enum', + enum: ['Morning', 'Afternoon'], + nullable: false + }) + time: 'Morning' | 'Afternoon'; + + @Column({ nullable: false }) + location: string; + + @CreateDateColumn({ type: 'timestamp', nullable: false }) + startedDate: Date; + + @CreateDateColumn({ type: 'timestamp', nullable: false }) + finishedDate: Date; + + @Column({ + type: 'enum', + enum: ['Pending', 'In Progress', 'Finished', 'Canceled'], + nullable: false + }) + status: 'Pending' | 'In Progress' | 'Finished' | 'Canceled'; + + @Column() + images: string; + + @Column() + rating: number; + + @Column() + feedback: string; + + @Column() + capacity: number; + + @ManyToMany(() => SkillTag) + @JoinTable() + skilltags: SkillTag[]; + + @ManyToMany(() => VolunteerProfile) + @JoinTable() + volunteerProfiles: VolunteerProfile[]; + + @ManyToOne(() => OrganizationProfile, organizationProfile => organizationProfile.voluntaryWork) + orgProfiles: OrganizationProfile; + + @CreateDateColumn({ + type: 'timestamp', + default: () => "CURRENT_TIMESTAMP(6)" + }) + createdAt: Date; +} \ No newline at end of file diff --git a/src/db/entities/Volunteer.ts b/src/db/entities/Volunteer.ts new file mode 100644 index 00000000..0e24acb0 --- /dev/null +++ b/src/db/entities/Volunteer.ts @@ -0,0 +1,46 @@ +import { BaseEntity, BeforeInsert, Column, CreateDateColumn, Entity, JoinColumn, JoinTable, ManyToMany, OneToOne, PrimaryGeneratedColumn } from "typeorm"; +import bcrypt from 'bcrypt'; +import { Role } from "./Role.js"; +import { VolunteerProfile } from "./VolunteerProfile.js"; + +@Entity() +export class Volunteer extends BaseEntity { + @PrimaryGeneratedColumn('uuid') + id: string; + + @Column({ length: 255, nullable: false }) + name: string; + + @Column({ nullable: false }) + email: string; + + @BeforeInsert() + async hashPassword() { + if (this.password) { + this.password = await bcrypt.hash(this.password, 10) + } + } + @Column({ nullable: false }) + password: string; + + @Column({ + type: 'enum', + enum: ['volunteer', 'premium'], + default: 'volunteer' + }) + type: 'volunteer' | 'premium'; + + @ManyToMany(() => Role) + @JoinTable() + roles: Role[]; + + @OneToOne(() => VolunteerProfile, {cascade: true, onDelete:"CASCADE"}) + @JoinColumn() + volunteerProfile: VolunteerProfile + + @CreateDateColumn({ + type: 'timestamp', + default: () => "CURRENT_TIMESTAMP(6)" + }) + createdAt: Date; +} \ No newline at end of file diff --git a/src/db/entities/VolunteerProfile.ts b/src/db/entities/VolunteerProfile.ts new file mode 100644 index 00000000..842ccbe2 --- /dev/null +++ b/src/db/entities/VolunteerProfile.ts @@ -0,0 +1,43 @@ +import { BaseEntity, Column, CreateDateColumn, Entity, JoinTable, ManyToMany, PrimaryGeneratedColumn } from "typeorm"; +import { SkillTag } from "./SkillTag.js"; +import { VoluntartyWork } from "./VoluntaryWork.js"; + +@Entity() +export class VolunteerProfile extends BaseEntity { + @PrimaryGeneratedColumn('uuid') + id: string; + + @Column({ + type: 'enum', + enum: ['Morning', 'Afternoon'], + nullable: false + }) + availableTime: 'Morning' | 'Afternoon'; + + @Column({ + type: 'enum', + enum: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], + nullable: false + }) + availableDays: 'Sunday' | 'Monday' | 'Tuesday' | 'Wednesday' | 'Thursday' | 'Friday' | 'Saturday'; + + @Column({ nullable: false }) + availableLocation: string; + + @Column({ nullable: false }) + preferredActivities: string; + + @ManyToMany(() => SkillTag) + @JoinTable() + skillTags: SkillTag[]; + + @ManyToMany(() => VoluntartyWork) + @JoinTable() + roles: VoluntartyWork[]; + + @CreateDateColumn({ + type: 'timestamp', + default: () => "CURRENT_TIMESTAMP(6)" + }) + createdAt: Date; +} \ No newline at end of file From 8c51b59f4ebdd7d8cd3da345eb4b6a8db4ac2c75 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Tue, 3 Oct 2023 06:01:41 +0300 Subject: [PATCH 004/146] edit the types, the id become a number --- types/permission.ts | 4 ++-- types/role.ts | 6 +++--- types/volunteryWork.ts | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/types/permission.ts b/types/permission.ts index 5394b6a9..f5650dbc 100644 --- a/types/permission.ts +++ b/types/permission.ts @@ -1,9 +1,9 @@ export namespace NSPermission { export interface Item { - id?: string, + id?: number, name: string, - rolesIds?: string[], + rolesIds?: number[], createdAt?: Date } } \ No newline at end of file diff --git a/types/role.ts b/types/role.ts index 5494a499..a0dfb166 100644 --- a/types/role.ts +++ b/types/role.ts @@ -2,15 +2,15 @@ export namespace NSRole { export enum Type { root = 'root', admin = 'admin', - normal = 'normal', + volunteer = 'volunteer', premium = 'premium' } export interface Item { - id?: string, + id?: number, name: Type, createdAt?: Date, - permissionsId: string[], + permissionsId: number[], volunteerId?: string[], organizationAdmin?: string[] } diff --git a/types/volunteryWork.ts b/types/volunteryWork.ts index 9063fb19..43b11f09 100644 --- a/types/volunteryWork.ts +++ b/types/volunteryWork.ts @@ -10,12 +10,12 @@ export namespace NSVoluntaryWork { } export interface Item { - id?: string; + id?: number; name: string; description: string; location: string; time: NSVolunteer.AvailableTime[]; - images: string; + images: string[]; rating: number; feedback: string; status: StatusType; From 035dea5cd2e989fbaa772810a676e379510d1c9b Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Tue, 3 Oct 2023 06:09:56 +0300 Subject: [PATCH 005/146] last editing for types --- types/volunteer.ts | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/types/volunteer.ts b/types/volunteer.ts index b19f4536..4555c690 100644 --- a/types/volunteer.ts +++ b/types/volunteer.ts @@ -1,15 +1,5 @@ export namespace NSVolunteer { - export enum TypeVolunteer { - volunteer = "volunteer", - premium = "premium" - } - - export enum AvailableTime { - Morning = 'Morning', - Afternoon = 'Afternoon' - } - export enum AvailableDays { Sunday = 'Sunday', Monday = 'Monday', @@ -20,6 +10,16 @@ export namespace NSVolunteer { Saturday = 'Saturday', } + export enum AvailableTime { + Morning = 'Morning', + Afternoon = 'Afternoon' + } + + export enum TypeVolunteer { + volunteer = "volunteer", + premium = "premium" + } + export interface Item { id?: string; name: string; From 1a39743f6f214f268cfff7f70712d11486e1982e Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Tue, 3 Oct 2023 06:24:54 +0300 Subject: [PATCH 006/146] edit some sttributes and entity --- src/db/dataSource.ts | 4 ++-- src/db/entities/OrganizationProfile.ts | 6 +++--- src/db/entities/SkillTag.ts | 6 +++--- src/db/entities/VoluntaryWork.ts | 4 ++-- src/db/entities/VolunteerProfile.ts | 6 +++--- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/db/dataSource.ts b/src/db/dataSource.ts index f62be3d5..8cebbb57 100644 --- a/src/db/dataSource.ts +++ b/src/db/dataSource.ts @@ -4,7 +4,7 @@ import { OrganizationProfile } from "./entities/OrganizationProfile.js"; import { Permission } from "./entities/Permission.js"; import { Role } from "./entities/Role.js"; import { SkillTag } from "./entities/SkillTag.js"; -import { VoluntartyWork } from "./entities/VoluntaryWork.js"; +import { VoluntaryWork } from "./entities/VoluntaryWork.js"; import { Volunteer } from "./entities/Volunteer.js"; import { VolunteerProfile } from "./entities/VolunteerProfile.js"; @@ -16,7 +16,7 @@ const dataSource = new DataSource({ password: process.env.DB_PASSWORD, database: process.env.DB_NAME, entities: [OrganizationAdmin, OrganizationProfile, Permission, - Role, SkillTag, VoluntartyWork, Volunteer, VolunteerProfile], + Role, SkillTag, VoluntaryWork, Volunteer, VolunteerProfile], migrations: ['./**/migration/*.ts'], synchronize: true, logging: false diff --git a/src/db/entities/OrganizationProfile.ts b/src/db/entities/OrganizationProfile.ts index 080390ae..5472a892 100644 --- a/src/db/entities/OrganizationProfile.ts +++ b/src/db/entities/OrganizationProfile.ts @@ -1,5 +1,5 @@ import { BaseEntity, Column, CreateDateColumn, Entity, OneToMany, PrimaryGeneratedColumn } from "typeorm"; -import { VoluntartyWork } from "./VoluntaryWork.js"; +import { VoluntaryWork } from "./VoluntaryWork.js"; @Entity() export class OrganizationProfile extends BaseEntity { @@ -12,8 +12,8 @@ export class OrganizationProfile extends BaseEntity { @Column({nullable: false}) description: string; - @OneToMany(() => VoluntartyWork, voluntartyWork => voluntartyWork.orgProfiles) - voluntaryWork: VoluntartyWork[]; + @OneToMany(() => VoluntaryWork, voluntaryWork => voluntaryWork.orgProfiles) + voluntaryWork: VoluntaryWork[]; @CreateDateColumn({ type: 'timestamp', diff --git a/src/db/entities/SkillTag.ts b/src/db/entities/SkillTag.ts index 6b0cb260..554e0f1f 100644 --- a/src/db/entities/SkillTag.ts +++ b/src/db/entities/SkillTag.ts @@ -1,6 +1,6 @@ import { BaseEntity, Column, CreateDateColumn, Entity, JoinTable, ManyToMany, PrimaryGeneratedColumn } from "typeorm"; import { VolunteerProfile } from "./VolunteerProfile.js"; -import { VoluntartyWork } from "./VoluntaryWork.js"; +import { VoluntaryWork } from "./VoluntaryWork.js"; @Entity() export class SkillTag extends BaseEntity { @@ -14,9 +14,9 @@ export class SkillTag extends BaseEntity { @JoinTable() volunteerProfiles: VolunteerProfile[]; - @ManyToMany(() => VoluntartyWork) + @ManyToMany(() => VoluntaryWork) @JoinTable() - roles: VoluntartyWork[]; + roles: VoluntaryWork[]; @CreateDateColumn({ type: 'timestamp', diff --git a/src/db/entities/VoluntaryWork.ts b/src/db/entities/VoluntaryWork.ts index 7e54d536..52b45d32 100644 --- a/src/db/entities/VoluntaryWork.ts +++ b/src/db/entities/VoluntaryWork.ts @@ -4,7 +4,7 @@ import { VolunteerProfile } from "./VolunteerProfile.js"; import { OrganizationProfile } from "./OrganizationProfile.js"; @Entity() -export class VoluntartyWork extends BaseEntity { +export class VoluntaryWork extends BaseEntity { @PrimaryGeneratedColumn('increment') id: number; @@ -58,7 +58,7 @@ export class VoluntartyWork extends BaseEntity { @ManyToMany(() => SkillTag) @JoinTable() - skilltags: SkillTag[]; + skillTags: SkillTag[]; @ManyToMany(() => VolunteerProfile) @JoinTable() diff --git a/src/db/entities/VolunteerProfile.ts b/src/db/entities/VolunteerProfile.ts index 842ccbe2..08b1a7d9 100644 --- a/src/db/entities/VolunteerProfile.ts +++ b/src/db/entities/VolunteerProfile.ts @@ -1,6 +1,6 @@ import { BaseEntity, Column, CreateDateColumn, Entity, JoinTable, ManyToMany, PrimaryGeneratedColumn } from "typeorm"; import { SkillTag } from "./SkillTag.js"; -import { VoluntartyWork } from "./VoluntaryWork.js"; +import { VoluntaryWork } from "./VoluntaryWork.js"; @Entity() export class VolunteerProfile extends BaseEntity { @@ -31,9 +31,9 @@ export class VolunteerProfile extends BaseEntity { @JoinTable() skillTags: SkillTag[]; - @ManyToMany(() => VoluntartyWork) + @ManyToMany(() => VoluntaryWork) @JoinTable() - roles: VoluntartyWork[]; + roles: VoluntaryWork[]; @CreateDateColumn({ type: 'timestamp', From 95bc810716674e218d26528ba817d1e8cae2cf8a Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Tue, 3 Oct 2023 06:38:18 +0300 Subject: [PATCH 007/146] add capacity attribute for v.w --- types/volunteryWork.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/types/volunteryWork.ts b/types/volunteryWork.ts index 43b11f09..f8bf449e 100644 --- a/types/volunteryWork.ts +++ b/types/volunteryWork.ts @@ -23,5 +23,6 @@ export namespace NSVoluntaryWork { days: NSVolunteer.AvailableDays[]; startedDate: Date; finishedDate: Date; + capacity:number; } } From be7403806f8422bb1fc93519372ff975a011f41c Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Tue, 3 Oct 2023 10:15:02 +0300 Subject: [PATCH 008/146] Creat a createPermission function --- src/controllers/permission.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/controllers/permission.ts diff --git a/src/controllers/permission.ts b/src/controllers/permission.ts new file mode 100644 index 00000000..7632f330 --- /dev/null +++ b/src/controllers/permission.ts @@ -0,0 +1,14 @@ +import { NSPermission } from "../../types/permission.js"; +import { Permission } from "../db/entities/Permission.js" + +const createPermission = async (payload: NSPermission.Item) => { + try { + const newPermission = Permission.create(payload) + return newPermission.save(); + } + catch (error){ + console.log(error); + } +} + +export { createPermission } \ No newline at end of file From 3073fd79769f237d2ff6492ca0d3b1110adca458 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Tue, 3 Oct 2023 10:20:14 +0300 Subject: [PATCH 009/146] creat simple router to test creatPermission --- app.ts | 2 ++ src/routes/permission.ts | 16 ++++++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 src/routes/permission.ts diff --git a/app.ts b/app.ts index ff680ec4..7291f5e7 100644 --- a/app.ts +++ b/app.ts @@ -6,6 +6,7 @@ import dataSource from './src/db/dataSource.js' import logger from 'morgan' import indexRouter from "./src/routes/index.js" +import permissionRouter from "./src/routes/permission.js" const app = express(); dotenv.config(); @@ -15,6 +16,7 @@ app.use(express.json()); app.use(express.urlencoded({ extended: false })); app.use('/', indexRouter); +app.use('/permission',permissionRouter); // app.use('/users', usersRouter); // catch 404 and forward to error handler diff --git a/src/routes/permission.ts b/src/routes/permission.ts new file mode 100644 index 00000000..bb192c5d --- /dev/null +++ b/src/routes/permission.ts @@ -0,0 +1,16 @@ +import express from 'express'; +import { createPermission } from '../controllers/permission.js'; + +var router = express.Router(); + +router.post('/', (req, res, next) => { + createPermission(req.body).then(() => { + res.status(201).send("Permission created successfully!!") + }).catch(err => { + console.error(err); + res.status(500).send(err); + }); +}); + +export default router; + From 610f15cf2c328ae7131e92992e57c8550c415d6e Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Tue, 3 Oct 2023 10:57:26 +0300 Subject: [PATCH 010/146] creat a function to delete a permission --- app.ts | 1 + src/controllers/permission.ts | 32 ++++++++++++++++++++++++++++++-- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/app.ts b/app.ts index 7291f5e7..cd60247a 100644 --- a/app.ts +++ b/app.ts @@ -7,6 +7,7 @@ import logger from 'morgan' import indexRouter from "./src/routes/index.js" import permissionRouter from "./src/routes/permission.js" +import { Role } from "./src/db/entities/Role.js" const app = express(); dotenv.config(); diff --git a/src/controllers/permission.ts b/src/controllers/permission.ts index 7632f330..015fe2a1 100644 --- a/src/controllers/permission.ts +++ b/src/controllers/permission.ts @@ -1,14 +1,42 @@ import { NSPermission } from "../../types/permission.js"; +import { OrganizationAdmin } from "../db/entities/OrganizationAdmin.js"; import { Permission } from "../db/entities/Permission.js" +import { Volunteer } from "../db/entities/Volunteer.js"; const createPermission = async (payload: NSPermission.Item) => { try { const newPermission = Permission.create(payload) return newPermission.save(); } - catch (error){ + catch (error) { console.log(error); } } -export { createPermission } \ No newline at end of file +const deletePermission = async (permissionId: number, sender: OrganizationAdmin | Volunteer) => { + const roles = sender?.roles; + let hasDeletePermission: boolean = false; + let typeName: string = ""; + + if (sender instanceof OrganizationAdmin) { + if (!Array.isArray(roles)) { + typeName = "organizationAdmin"; + hasDeletePermission = roles.permissions.some(permission => permission.name === `DELETE_${typeName}`); + } + } else { + if (Array.isArray(roles)) { + typeName = sender?.type; + hasDeletePermission = roles?.some(role => + role.permissions.some(permission => permission.name === `DELETE_${typeName}`)) + } + } + + if (!hasDeletePermission) { + return `You don't have a permission to delete ${typeName}` + } + + return Permission.delete(permissionId); + +} + +export { createPermission, deletePermission } \ No newline at end of file From 13479b348ddee005a2d94f9b47ad234409678f39 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Tue, 3 Oct 2023 11:06:08 +0300 Subject: [PATCH 011/146] creat delete permission end point --- src/routes/permission.ts | 41 ++++++++++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/src/routes/permission.ts b/src/routes/permission.ts index bb192c5d..e4c74899 100644 --- a/src/routes/permission.ts +++ b/src/routes/permission.ts @@ -1,16 +1,45 @@ import express from 'express'; -import { createPermission } from '../controllers/permission.js'; +import { createPermission, deletePermission } from '../controllers/permission.js'; +import { OrganizationAdmin } from '../db/entities/OrganizationAdmin.js'; +import { Volunteer } from '../db/entities/Volunteer.js'; var router = express.Router(); router.post('/', (req, res, next) => { createPermission(req.body).then(() => { - res.status(201).send("Permission created successfully!!") - }).catch(err => { - console.error(err); - res.status(500).send(err); - }); + res.status(201).send("Permission created successfully!!") + }).catch(err => { + console.error(err); + res.status(500).send(err); + }); }); +router.delete('/:id', async (req, res) => { + const id = Number(req.params.id?.toString()) ; + let sender: OrganizationAdmin | Volunteer = new Volunteer(); + if (res.locals.organizationAdmin) { + sender = await OrganizationAdmin.findOne({ + where: { + name: res.locals.user.name, email: res.locals?.user.email + }, relations: ["roles", "roles.permissions"] + }) || new OrganizationAdmin(); + }else if(res.locals.volunteer){ + sender = await Volunteer.findOne({ + where: { + name: res.locals.user.name, email: res.locals?.user.email + }, relations: ["roles", "roles.permissions"] + }) || new Volunteer(); + } + + deletePermission(id, sender) + .then(data => { + res.send(data); + }) + .catch(error => { + console.error(error); + res.status(500).send('Something went wrong'); + }); +}) + export default router; From 0ba44c89af13f0ffb6a01877900b08b9b3203d11 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Tue, 3 Oct 2023 11:30:18 +0300 Subject: [PATCH 012/146] edit res.locals --- src/routes/permission.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/routes/permission.ts b/src/routes/permission.ts index e4c74899..e9840b03 100644 --- a/src/routes/permission.ts +++ b/src/routes/permission.ts @@ -20,13 +20,13 @@ router.delete('/:id', async (req, res) => { if (res.locals.organizationAdmin) { sender = await OrganizationAdmin.findOne({ where: { - name: res.locals.user.name, email: res.locals?.user.email + name: res.locals.organizationAdmin.name, email: res.locals?.organizationAdmin.email }, relations: ["roles", "roles.permissions"] }) || new OrganizationAdmin(); }else if(res.locals.volunteer){ sender = await Volunteer.findOne({ where: { - name: res.locals.user.name, email: res.locals?.user.email + name: res.locals.volunteer.name, email: res.locals?.volunteer.email }, relations: ["roles", "roles.permissions"] }) || new Volunteer(); } From 91fb30b92c657e95b9aa7104bb461524312b70f9 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Tue, 3 Oct 2023 11:55:07 +0300 Subject: [PATCH 013/146] creat a function to edit the name of permission --- src/controllers/permission.ts | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/src/controllers/permission.ts b/src/controllers/permission.ts index 015fe2a1..ed0bb140 100644 --- a/src/controllers/permission.ts +++ b/src/controllers/permission.ts @@ -39,4 +39,36 @@ const deletePermission = async (permissionId: number, sender: OrganizationAdmin } -export { createPermission, deletePermission } \ No newline at end of file +const editPermission = async (payload: {name:string, id:number}, sender:Volunteer|OrganizationAdmin ) => { + const roles = sender.roles; + let hasEditPermission: boolean = false; + let typeName: string = ""; + + if (sender instanceof OrganizationAdmin) { + if (!Array.isArray(roles)) { + typeName = "organizationAdmin"; + hasEditPermission = roles.permissions.some(permission => permission.name === `EDIT_${typeName}`); + } + } else { + if (Array.isArray(roles)) { + typeName = sender?.type; + hasEditPermission = roles?.some(role => + role.permissions.some(permission => permission.name === `DELETE_${typeName}`)) + } + } + + // if (!hasEditPermission) { + // return `You don't have a permission to delete ${typeName}` + // } + + const permission = await Permission.findOne({where:{id: payload.id}}); + + if (permission) { + permission.name =payload.name; + return permission.save(); + } else { + return "Permission not found :("; + } + } + +export { createPermission, deletePermission, editPermission } \ No newline at end of file From 303799e96193997536190bf3b61dc698118a71a0 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Tue, 3 Oct 2023 12:05:45 +0300 Subject: [PATCH 014/146] creat getSender function --- src/controllers/index.ts | 23 +++++++++++++++++++++++ src/routes/permission.ts | 18 ++---------------- 2 files changed, 25 insertions(+), 16 deletions(-) create mode 100644 src/controllers/index.ts diff --git a/src/controllers/index.ts b/src/controllers/index.ts new file mode 100644 index 00000000..39096aa4 --- /dev/null +++ b/src/controllers/index.ts @@ -0,0 +1,23 @@ +import express from 'express' +import { OrganizationAdmin } from '../db/entities/OrganizationAdmin.js'; +import { Volunteer } from '../db/entities/Volunteer.js'; + +const getSender =async (res:express.Response)=>{ + let sender: OrganizationAdmin | Volunteer = new Volunteer(); + if (res.locals.organizationAdmin) { + sender = await OrganizationAdmin.findOne({ + where: { + name: res.locals.organizationAdmin.name, email: res.locals?.organizationAdmin.email + }, relations: ["roles", "roles.permissions"] + }) || new OrganizationAdmin(); + }else if(res.locals.volunteer){ + sender = await Volunteer.findOne({ + where: { + name: res.locals.volunteer.name, email: res.locals?.volunteer.email + }, relations: ["roles", "roles.permissions"] + }) || new Volunteer(); + } + return sender; +} + +export {getSender}; \ No newline at end of file diff --git a/src/routes/permission.ts b/src/routes/permission.ts index e9840b03..e6ba4d38 100644 --- a/src/routes/permission.ts +++ b/src/routes/permission.ts @@ -1,7 +1,6 @@ import express from 'express'; import { createPermission, deletePermission } from '../controllers/permission.js'; -import { OrganizationAdmin } from '../db/entities/OrganizationAdmin.js'; -import { Volunteer } from '../db/entities/Volunteer.js'; +import { getSender } from '../controllers/index.js'; var router = express.Router(); @@ -16,20 +15,7 @@ router.post('/', (req, res, next) => { router.delete('/:id', async (req, res) => { const id = Number(req.params.id?.toString()) ; - let sender: OrganizationAdmin | Volunteer = new Volunteer(); - if (res.locals.organizationAdmin) { - sender = await OrganizationAdmin.findOne({ - where: { - name: res.locals.organizationAdmin.name, email: res.locals?.organizationAdmin.email - }, relations: ["roles", "roles.permissions"] - }) || new OrganizationAdmin(); - }else if(res.locals.volunteer){ - sender = await Volunteer.findOne({ - where: { - name: res.locals.volunteer.name, email: res.locals?.volunteer.email - }, relations: ["roles", "roles.permissions"] - }) || new Volunteer(); - } + const sender = await getSender(res); deletePermission(id, sender) .then(data => { From 537b335435577afcfd9994cde166e02440de7daf Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Tue, 3 Oct 2023 12:14:47 +0300 Subject: [PATCH 015/146] creat edit permission end point --- src/controllers/permission.ts | 10 +++++----- src/routes/permission.ts | 13 ++++++++++++- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/controllers/permission.ts b/src/controllers/permission.ts index ed0bb140..a48e2d9f 100644 --- a/src/controllers/permission.ts +++ b/src/controllers/permission.ts @@ -57,17 +57,17 @@ const editPermission = async (payload: {name:string, id:number}, sender:Voluntee } } - // if (!hasEditPermission) { - // return `You don't have a permission to delete ${typeName}` - // } + if (!hasEditPermission) { + return `You don't have a permission to delete ${typeName}` + } const permission = await Permission.findOne({where:{id: payload.id}}); - + if (permission) { permission.name =payload.name; return permission.save(); } else { - return "Permission not found :("; + throw "Permission not found :("; } } diff --git a/src/routes/permission.ts b/src/routes/permission.ts index e6ba4d38..85deab43 100644 --- a/src/routes/permission.ts +++ b/src/routes/permission.ts @@ -1,5 +1,5 @@ import express from 'express'; -import { createPermission, deletePermission } from '../controllers/permission.js'; +import { createPermission, deletePermission, editPermission } from '../controllers/permission.js'; import { getSender } from '../controllers/index.js'; var router = express.Router(); @@ -27,5 +27,16 @@ router.delete('/:id', async (req, res) => { }); }) +router.put("/", async (req, res, next) => { + const sender = await getSender(res); + + editPermission(req.body,sender).then(() => { + res.status(201).send("Permission edited successfully!!") + }).catch(err => { + console.error(err); + res.status(500).send(err); + }); + }); + export default router; From 827068e00bb5dc705acfa94fc53fbd76967f4453 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Tue, 3 Oct 2023 12:24:06 +0300 Subject: [PATCH 016/146] creat get permission and get permissions functions --- src/controllers/permission.ts | 110 +++++++++++++++++++++------------- 1 file changed, 69 insertions(+), 41 deletions(-) diff --git a/src/controllers/permission.ts b/src/controllers/permission.ts index a48e2d9f..54f099f7 100644 --- a/src/controllers/permission.ts +++ b/src/controllers/permission.ts @@ -14,61 +14,89 @@ const createPermission = async (payload: NSPermission.Item) => { } const deletePermission = async (permissionId: number, sender: OrganizationAdmin | Volunteer) => { - const roles = sender?.roles; - let hasDeletePermission: boolean = false; - let typeName: string = ""; + // const roles = sender?.roles; + // let hasDeletePermission: boolean = false; + // let typeName: string = ""; - if (sender instanceof OrganizationAdmin) { - if (!Array.isArray(roles)) { - typeName = "organizationAdmin"; - hasDeletePermission = roles.permissions.some(permission => permission.name === `DELETE_${typeName}`); - } - } else { - if (Array.isArray(roles)) { - typeName = sender?.type; - hasDeletePermission = roles?.some(role => - role.permissions.some(permission => permission.name === `DELETE_${typeName}`)) - } - } + // if (sender instanceof OrganizationAdmin) { + // if (!Array.isArray(roles)) { + // typeName = "organizationAdmin"; + // hasDeletePermission = roles.permissions.some(permission => permission.name === `DELETE_${typeName}`); + // } + // } else { + // if (Array.isArray(roles)) { + // typeName = sender?.type; + // hasDeletePermission = roles?.some(role => + // role.permissions.some(permission => permission.name === `DELETE_${typeName}`)) + // } + // } - if (!hasDeletePermission) { - return `You don't have a permission to delete ${typeName}` - } + // if (!hasDeletePermission) { + // return `You don't have a permission to delete ${typeName}` + // } return Permission.delete(permissionId); } -const editPermission = async (payload: {name:string, id:number}, sender:Volunteer|OrganizationAdmin ) => { - const roles = sender.roles; - let hasEditPermission: boolean = false; - let typeName: string = ""; +const editPermission = async (payload: { name: string, id: number }, sender: Volunteer | OrganizationAdmin) => { + // const roles = sender.roles; + // let hasEditPermission: boolean = false; + // let typeName: string = ""; - if (sender instanceof OrganizationAdmin) { - if (!Array.isArray(roles)) { - typeName = "organizationAdmin"; - hasEditPermission = roles.permissions.some(permission => permission.name === `EDIT_${typeName}`); - } - } else { - if (Array.isArray(roles)) { - typeName = sender?.type; - hasEditPermission = roles?.some(role => - role.permissions.some(permission => permission.name === `DELETE_${typeName}`)) - } - } + // if (sender instanceof OrganizationAdmin) { + // if (!Array.isArray(roles)) { + // typeName = "organizationAdmin"; + // hasEditPermission = roles.permissions.some(permission => permission.name === `EDIT_${typeName}`); + // } + // } else { + // if (Array.isArray(roles)) { + // typeName = sender?.type; + // hasEditPermission = roles?.some(role => + // role.permissions.some(permission => permission.name === `DELETE_${typeName}`)) + // } + // } - if (!hasEditPermission) { - return `You don't have a permission to delete ${typeName}` - } + // if (!hasEditPermission) { + // return `You don't have a permission to delete ${typeName}` + // } - const permission = await Permission.findOne({where:{id: payload.id}}); + const permission = await Permission.findOne({ where: { id: payload.id } }); if (permission) { - permission.name =payload.name; + permission.name = payload.name; return permission.save(); } else { - throw "Permission not found :("; + throw "Permission not found :("; } +} + +const getPermission = (payload: { id: number }) => { + return Permission.findOne({ where: { id: payload.id } }) +} + +const getPermissions = async (payload: { + page: string, + pageSize: string + }) => { + + const page = parseInt(payload.page); + const pageSize = parseInt(payload.pageSize); + + const [permissions, total] = await Permission.findAndCount({ + skip: pageSize * (page - 1), + take: pageSize, + order: { + createdAt: 'ASC' + } + }) + + return { + page, + pageSize: permissions.length, + total, + permissions + }; } -export { createPermission, deletePermission, editPermission } \ No newline at end of file +export { createPermission, deletePermission, editPermission, getPermission, getPermissions } \ No newline at end of file From 1bf6ca1a87df56ebd3a7ea431a4c8aa91ff78337 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Tue, 3 Oct 2023 12:33:11 +0300 Subject: [PATCH 017/146] creat 2 end point to get user by id and all users --- src/routes/permission.ts | 45 ++++++++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/src/routes/permission.ts b/src/routes/permission.ts index 85deab43..a587ca0f 100644 --- a/src/routes/permission.ts +++ b/src/routes/permission.ts @@ -1,5 +1,5 @@ import express from 'express'; -import { createPermission, deletePermission, editPermission } from '../controllers/permission.js'; +import { createPermission, deletePermission, editPermission, getPermission, getPermissions } from '../controllers/permission.js'; import { getSender } from '../controllers/index.js'; var router = express.Router(); @@ -14,8 +14,8 @@ router.post('/', (req, res, next) => { }); router.delete('/:id', async (req, res) => { - const id = Number(req.params.id?.toString()) ; - const sender = await getSender(res); + const id = Number(req.params.id?.toString()); + const sender = await getSender(res); deletePermission(id, sender) .then(data => { @@ -29,14 +29,41 @@ router.delete('/:id', async (req, res) => { router.put("/", async (req, res, next) => { const sender = await getSender(res); - - editPermission(req.body,sender).then(() => { - res.status(201).send("Permission edited successfully!!") + + editPermission(req.body, sender).then(() => { + res.status(201).send("Permission edited successfully!!") }).catch(err => { - console.error(err); - res.status(500).send(err); + console.error(err); + res.status(500).send(err); }); - }); +}); + +router.get("/:id", async (req, res) => { + const id = Number(req.params.id) + + const permission = await getPermission({ id }); + if (permission) { + res.status(201).send(permission); + } else { + res.status(404).send("Permission not found :("); + } +}) + +router.get('/', async (req, res, next) => { + const payload = { + page: req.query.page?.toString() || '1', + pageSize: req.query.pageSize?.toString() || '10' + }; + + getPermissions(payload) + .then(data => { + res.send(data); + }) + .catch(error => { + console.error(error); + res.status(500).send('Something went wrong'); + }); +}); export default router; From f648b2b57830928458f4fb79e661a50548348c0c Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Tue, 3 Oct 2023 12:36:05 +0300 Subject: [PATCH 018/146] remove the sender --- src/controllers/permission.ts | 4 ++-- src/routes/permission.ts | 7 ++----- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/controllers/permission.ts b/src/controllers/permission.ts index 54f099f7..4feac698 100644 --- a/src/controllers/permission.ts +++ b/src/controllers/permission.ts @@ -13,7 +13,7 @@ const createPermission = async (payload: NSPermission.Item) => { } } -const deletePermission = async (permissionId: number, sender: OrganizationAdmin | Volunteer) => { +const deletePermission = async (permissionId: number) => { // const roles = sender?.roles; // let hasDeletePermission: boolean = false; // let typeName: string = ""; @@ -39,7 +39,7 @@ const deletePermission = async (permissionId: number, sender: OrganizationAdmin } -const editPermission = async (payload: { name: string, id: number }, sender: Volunteer | OrganizationAdmin) => { +const editPermission = async (payload: { name: string, id: number }) => { // const roles = sender.roles; // let hasEditPermission: boolean = false; // let typeName: string = ""; diff --git a/src/routes/permission.ts b/src/routes/permission.ts index a587ca0f..25df55e7 100644 --- a/src/routes/permission.ts +++ b/src/routes/permission.ts @@ -15,9 +15,8 @@ router.post('/', (req, res, next) => { router.delete('/:id', async (req, res) => { const id = Number(req.params.id?.toString()); - const sender = await getSender(res); - deletePermission(id, sender) + deletePermission(id) .then(data => { res.send(data); }) @@ -28,9 +27,7 @@ router.delete('/:id', async (req, res) => { }) router.put("/", async (req, res, next) => { - const sender = await getSender(res); - - editPermission(req.body, sender).then(() => { + editPermission(req.body).then(() => { res.status(201).send("Permission edited successfully!!") }).catch(err => { console.error(err); From 28428749897018798748863971c74772b0b5d465 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Tue, 3 Oct 2023 12:52:50 +0300 Subject: [PATCH 019/146] creat all role controller functions --- src/controllers/role.ts | 58 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 src/controllers/role.ts diff --git a/src/controllers/role.ts b/src/controllers/role.ts new file mode 100644 index 00000000..dc96ef2d --- /dev/null +++ b/src/controllers/role.ts @@ -0,0 +1,58 @@ +import { NSRole } from "../../types/role.js"; +import { Role } from "../db/entities/Role.js"; + +const createRole = async (payload: NSRole.Item) => { + try { + const newRole = Role.create(payload) + return newRole.save(); + } + catch (error) { + console.log(error); + } +} + +const deleteRole = async (roleId: number) => { + return Role.delete(roleId); +} + +const editRole = async (payload: { name: NSRole.Type, id: number }) => { + const role = await Role.findOne({ where: { id: payload.id } }); + // need validation + if (role) { + role.name = payload.name; + return role.save(); + + } else { + throw "Role not found :("; + } +} + +const getRole = (payload: { id: number }) => { + return Role.findOne({ where: { id: payload.id } }) +} + +const getRoles = async (payload: { + page: string, + pageSize: string +}) => { + + const page = parseInt(payload.page); + const pageSize = parseInt(payload.pageSize); + + const [roles, total] = await Role.findAndCount({ + skip: pageSize * (page - 1), + take: pageSize, + order: { + createdAt: 'ASC' + } + }) + + return { + page, + pageSize: roles.length, + total, + roles + }; +} + +export { createRole, editRole, getRole, getRoles, deleteRole } \ No newline at end of file From e5c42d42b5bbf63050f253324579a88e8a5847da Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Tue, 3 Oct 2023 13:14:03 +0300 Subject: [PATCH 020/146] creat a router for role end points --- app.ts | 3 +- src/controllers/role.ts | 9 +++++- src/db/entities/Role.ts | 3 +- src/routes/role.ts | 65 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 77 insertions(+), 3 deletions(-) create mode 100644 src/routes/role.ts diff --git a/app.ts b/app.ts index cd60247a..920175ce 100644 --- a/app.ts +++ b/app.ts @@ -7,7 +7,7 @@ import logger from 'morgan' import indexRouter from "./src/routes/index.js" import permissionRouter from "./src/routes/permission.js" -import { Role } from "./src/db/entities/Role.js" +import roleRouter from "./src/routes/role.js" const app = express(); dotenv.config(); @@ -18,6 +18,7 @@ app.use(express.urlencoded({ extended: false })); app.use('/', indexRouter); app.use('/permission',permissionRouter); +app.use('/role',roleRouter); // app.use('/users', usersRouter); // catch 404 and forward to error handler diff --git a/src/controllers/role.ts b/src/controllers/role.ts index dc96ef2d..05b65502 100644 --- a/src/controllers/role.ts +++ b/src/controllers/role.ts @@ -1,9 +1,16 @@ +import { In } from "typeorm"; import { NSRole } from "../../types/role.js"; +import { Permission } from "../db/entities/Permission.js"; import { Role } from "../db/entities/Role.js"; const createRole = async (payload: NSRole.Item) => { try { - const newRole = Role.create(payload) + const newRole = Role.create(payload); + const permissions = await Permission.find({ + where: { id: In(payload.permissionsId) }, + }); + + newRole.permissions =permissions return newRole.save(); } catch (error) { diff --git a/src/db/entities/Role.ts b/src/db/entities/Role.ts index 3e37a782..240eec4a 100644 --- a/src/db/entities/Role.ts +++ b/src/db/entities/Role.ts @@ -11,7 +11,8 @@ export class Role extends BaseEntity { @Column({ type: 'enum', enum: ['root', 'admin', 'volunteer', 'premium'], - default: 'volunteer' + default: 'volunteer', + unique:true }) name: 'root' | 'admin' | 'volunteer' | 'premium'; diff --git a/src/routes/role.ts b/src/routes/role.ts new file mode 100644 index 00000000..96e80dcb --- /dev/null +++ b/src/routes/role.ts @@ -0,0 +1,65 @@ +import express from 'express'; +import { createRole, deleteRole, editRole, getRole, getRoles } from '../controllers/role.js'; + +var router = express.Router(); + +router.post('/', (req, res, next) => { + createRole(req.body).then(() => { + res.status(201).send("Role created successfully!!") + }).catch(err => { + console.error(err); + res.status(500).send(err); + }); +}); + +router.delete('/:id', async (req, res) => { + const id = Number(req.params.id?.toString()); + + deleteRole(id) + .then(data => { + res.send(data); + }) + .catch(error => { + console.error(error); + res.status(500).send('Something went wrong'); + }); +}) + +router.put("/", async (req, res, next) => { + editRole(req.body).then(() => { + res.status(201).send("Role edited successfully!!") + }).catch(err => { + console.error(err); + res.status(500).send(err); + }); +}); + +router.get("/:id", async (req, res) => { + const id = Number(req.params.id) + + const role = await getRole({ id }); + if (role) { + res.status(201).send(role); + } else { + res.status(404).send("Role not found :("); + } +}) + +router.get('/', async (req, res, next) => { + const payload = { + page: req.query.page?.toString() || '1', + pageSize: req.query.pageSize?.toString() || '10' + }; + + getRoles(payload) + .then(data => { + res.send(data); + }) + .catch(error => { + console.error(error); + res.status(500).send('Something went wrong'); + }); +}); + +export default router; + From f464abce2d676afbb4a19e7bd5eb9954065de4ee Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Tue, 3 Oct 2023 13:50:13 +0300 Subject: [PATCH 021/146] Creat get, edit, creat, delete, get all v.w functions --- src/controllers/voluntaryWork.ts | 63 ++++++++++++++++++++++++++++++++ src/db/entities/VoluntaryWork.ts | 6 +-- types/volunteryWork.ts | 22 ++++++++++- 3 files changed, 87 insertions(+), 4 deletions(-) create mode 100644 src/controllers/voluntaryWork.ts diff --git a/src/controllers/voluntaryWork.ts b/src/controllers/voluntaryWork.ts new file mode 100644 index 00000000..35f80203 --- /dev/null +++ b/src/controllers/voluntaryWork.ts @@ -0,0 +1,63 @@ +import { In } from "typeorm"; +import { NSVoluntaryWork } from "../../types/volunteryWork.js"; +import { SkillTag } from "../db/entities/SkillTag.js"; +import { VoluntaryWork } from "../db/entities/VoluntaryWork.js"; + +const createVoluntaryWork = async (payload: NSVoluntaryWork.Item) => { + try { + const newVoluntaryWork = VoluntaryWork.create(payload); + const skillTags = await SkillTag.find({ + where: { id: In(payload.skillTagIds) }, + }); + newVoluntaryWork.skillTags = skillTags; + return newVoluntaryWork.save(); + } + catch (error) { + console.log(error); + } +} + +const deleteVoluntaryWork = async (voluntaryWorkId: number) => { + return VoluntaryWork.delete(voluntaryWorkId); +} + +const editVoluntaryWork = async (payload: NSVoluntaryWork.Edit) => { + let voluntaryWork = await VoluntaryWork.findOne({ where: { id: payload.id } }); + if (voluntaryWork) { + voluntaryWork = Object.assign(voluntaryWork, payload); + return voluntaryWork?.save(); + + } else { + throw "VoluntaryWork not found :("; + } +} + +const getVoluntaryWork = (payload: { id: number }) => { + return VoluntaryWork.findOne({ where: { id: payload.id } }) +} + +const getVoluntaryWorks = async (payload: { + page: string, + pageSize: string +}) => { + + const page = parseInt(payload.page); + const pageSize = parseInt(payload.pageSize); + + const [VoluntaryWorks, total] = await VoluntaryWork.findAndCount({ + skip: pageSize * (page - 1), + take: pageSize, + order: { + createdAt: 'ASC' + } + }) + + return { + page, + pageSize: VoluntaryWorks.length, + total, + VoluntaryWorks + }; +} + +export { createVoluntaryWork, editVoluntaryWork, getVoluntaryWork, getVoluntaryWorks, deleteVoluntaryWork } \ No newline at end of file diff --git a/src/db/entities/VoluntaryWork.ts b/src/db/entities/VoluntaryWork.ts index 52b45d32..e3052309 100644 --- a/src/db/entities/VoluntaryWork.ts +++ b/src/db/entities/VoluntaryWork.ts @@ -19,14 +19,14 @@ export class VoluntaryWork extends BaseEntity { enum: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], nullable: false }) - day: 'Sunday' | 'Monday' | 'Tuesday' | 'Wednesday' | 'Thursday' | 'Friday' | 'Saturday'; + days: ('Sunday' | 'Monday' | 'Tuesday' | 'Wednesday' | 'Thursday' | 'Friday' | 'Saturday')[]; @Column({ type: 'enum', enum: ['Morning', 'Afternoon'], nullable: false }) - time: 'Morning' | 'Afternoon'; + time: ('Morning' | 'Afternoon')[]; @Column({ nullable: false }) location: string; @@ -45,7 +45,7 @@ export class VoluntaryWork extends BaseEntity { status: 'Pending' | 'In Progress' | 'Finished' | 'Canceled'; @Column() - images: string; + images: string[]; @Column() rating: number; diff --git a/types/volunteryWork.ts b/types/volunteryWork.ts index f8bf449e..a01b62de 100644 --- a/types/volunteryWork.ts +++ b/types/volunteryWork.ts @@ -9,6 +9,25 @@ export namespace NSVoluntaryWork { Canceled = 'Canceled' } + export interface Edit { + id: number; + name?: string; + description?: string; + location?: string; + time?: NSVolunteer.AvailableTime[]; + images?: string[]; + rating?: number; + feedback?: string; + status?: StatusType; + days?: NSVolunteer.AvailableDays[]; + startedDate?: Date; + finishedDate?: Date; + capacity?: number; + skillTagIds?: number[]; + createdAt?: Date; + + } + export interface Item { id?: number; name: string; @@ -23,6 +42,7 @@ export namespace NSVoluntaryWork { days: NSVolunteer.AvailableDays[]; startedDate: Date; finishedDate: Date; - capacity:number; + capacity: number; + skillTagIds: number[]; } } From e7270339949207817d1d3611c9659d0f9f625de3 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Tue, 3 Oct 2023 14:45:15 +0300 Subject: [PATCH 022/146] creat the router for v.w --- app.ts | 2 + src/db/entities/VoluntaryWork.ts | 2 +- src/routes/voluntaryWork.ts | 65 ++++++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 src/routes/voluntaryWork.ts diff --git a/app.ts b/app.ts index 920175ce..2c4f1082 100644 --- a/app.ts +++ b/app.ts @@ -8,6 +8,7 @@ import logger from 'morgan' import indexRouter from "./src/routes/index.js" import permissionRouter from "./src/routes/permission.js" import roleRouter from "./src/routes/role.js" +import voluntaryWorkRouter from "./src/routes/voluntaryWork.js" const app = express(); dotenv.config(); @@ -19,6 +20,7 @@ app.use(express.urlencoded({ extended: false })); app.use('/', indexRouter); app.use('/permission',permissionRouter); app.use('/role',roleRouter); +app.use('/voluntaryWork',voluntaryWorkRouter) // app.use('/users', usersRouter); // catch 404 and forward to error handler diff --git a/src/db/entities/VoluntaryWork.ts b/src/db/entities/VoluntaryWork.ts index e3052309..6552db1d 100644 --- a/src/db/entities/VoluntaryWork.ts +++ b/src/db/entities/VoluntaryWork.ts @@ -44,7 +44,7 @@ export class VoluntaryWork extends BaseEntity { }) status: 'Pending' | 'In Progress' | 'Finished' | 'Canceled'; - @Column() + @Column({ type: 'text', nullable: false, transformer: { to: (value) => JSON.stringify(value), from: (value) => JSON.parse(value) } }) images: string[]; @Column() diff --git a/src/routes/voluntaryWork.ts b/src/routes/voluntaryWork.ts new file mode 100644 index 00000000..2ce4e3e8 --- /dev/null +++ b/src/routes/voluntaryWork.ts @@ -0,0 +1,65 @@ +import express from 'express'; +import { createVoluntaryWork, deleteVoluntaryWork, editVoluntaryWork, getVoluntaryWork, getVoluntaryWorks } from '../controllers/voluntaryWork.js'; + +var router = express.Router(); + +router.post('/', (req, res, next) => { + createVoluntaryWork(req.body).then(() => { + res.status(201).send("VoluntaryWork created successfully!!") + }).catch(err => { + console.error(err); + res.status(500).send(err); + }); +}); + +router.delete('/:id', async (req, res) => { + const id = Number(req.params.id?.toString()); + + deleteVoluntaryWork(id) + .then(data => { + res.send(data); + }) + .catch(error => { + console.error(error); + res.status(500).send('Something went wrong'); + }); +}) + +router.put("/", async (req, res, next) => { + editVoluntaryWork(req.body).then(() => { + res.status(201).send("VoluntaryWork edited successfully!!") + }).catch(err => { + console.error(err); + res.status(500).send(err); + }); +}); + +router.get("/:id", async (req, res) => { + const id = Number(req.params.id) + + const voluntaryWork = await getVoluntaryWork({ id }); + if (voluntaryWork) { + res.status(201).send(voluntaryWork); + } else { + res.status(404).send("VoluntaryWork not found :("); + } +}) + +router.get('/', async (req, res, next) => { + const payload = { + page: req.query.page?.toString() || '1', + pageSize: req.query.pageSize?.toString() || '10' + }; + + getVoluntaryWorks(payload) + .then(data => { + res.send(data); + }) + .catch(error => { + console.error(error); + res.status(500).send('Something went wrong'); + }); +}); + +export default router; + From 76a6ab883c4322dad7eb2c9b6c841aa8bf59908c Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Tue, 3 Oct 2023 18:03:44 +0300 Subject: [PATCH 023/146] edit get permission to get by name , id and all permissions --- src/controllers/permission.ts | 176 ++++++++++--------- src/controllers/voluntaryWork.ts | 2 +- src/routes/permission.ts | 27 +-- types/{volunteryWork.ts => voluntaryWork.ts} | 0 4 files changed, 110 insertions(+), 95 deletions(-) rename types/{volunteryWork.ts => voluntaryWork.ts} (100%) diff --git a/src/controllers/permission.ts b/src/controllers/permission.ts index 4feac698..d161630c 100644 --- a/src/controllers/permission.ts +++ b/src/controllers/permission.ts @@ -4,99 +4,109 @@ import { Permission } from "../db/entities/Permission.js" import { Volunteer } from "../db/entities/Volunteer.js"; const createPermission = async (payload: NSPermission.Item) => { - try { - const newPermission = Permission.create(payload) - return newPermission.save(); - } - catch (error) { - console.log(error); - } + try { + const newPermission = Permission.create(payload) + return newPermission.save(); + } + catch (error) { + console.log(error); + } } const deletePermission = async (permissionId: number) => { - // const roles = sender?.roles; - // let hasDeletePermission: boolean = false; - // let typeName: string = ""; - - // if (sender instanceof OrganizationAdmin) { - // if (!Array.isArray(roles)) { - // typeName = "organizationAdmin"; - // hasDeletePermission = roles.permissions.some(permission => permission.name === `DELETE_${typeName}`); - // } - // } else { - // if (Array.isArray(roles)) { - // typeName = sender?.type; - // hasDeletePermission = roles?.some(role => - // role.permissions.some(permission => permission.name === `DELETE_${typeName}`)) - // } - // } - - // if (!hasDeletePermission) { - // return `You don't have a permission to delete ${typeName}` - // } - - return Permission.delete(permissionId); + // const roles = sender?.roles; + // let hasDeletePermission: boolean = false; + // let typeName: string = ""; + + // if (sender instanceof OrganizationAdmin) { + // if (!Array.isArray(roles)) { + // typeName = "organizationAdmin"; + // hasDeletePermission = roles.permissions.some(permission => permission.name === `DELETE_${typeName}`); + // } + // } else { + // if (Array.isArray(roles)) { + // typeName = sender?.type; + // hasDeletePermission = roles?.some(role => + // role.permissions.some(permission => permission.name === `DELETE_${typeName}`)) + // } + // } + + // if (!hasDeletePermission) { + // return `You don't have a permission to delete ${typeName}` + // } + + return Permission.delete(permissionId); } const editPermission = async (payload: { name: string, id: number }) => { - // const roles = sender.roles; - // let hasEditPermission: boolean = false; - // let typeName: string = ""; - - // if (sender instanceof OrganizationAdmin) { - // if (!Array.isArray(roles)) { - // typeName = "organizationAdmin"; - // hasEditPermission = roles.permissions.some(permission => permission.name === `EDIT_${typeName}`); - // } - // } else { - // if (Array.isArray(roles)) { - // typeName = sender?.type; - // hasEditPermission = roles?.some(role => - // role.permissions.some(permission => permission.name === `DELETE_${typeName}`)) - // } - // } - - // if (!hasEditPermission) { - // return `You don't have a permission to delete ${typeName}` - // } - - const permission = await Permission.findOne({ where: { id: payload.id } }); - - if (permission) { - permission.name = payload.name; - return permission.save(); - } else { - throw "Permission not found :("; - } -} + // const roles = sender.roles; + // let hasEditPermission: boolean = false; + // let typeName: string = ""; -const getPermission = (payload: { id: number }) => { - return Permission.findOne({ where: { id: payload.id } }) + // if (sender instanceof OrganizationAdmin) { + // if (!Array.isArray(roles)) { + // typeName = "organizationAdmin"; + // hasEditPermission = roles.permissions.some(permission => permission.name === `EDIT_${typeName}`); + // } + // } else { + // if (Array.isArray(roles)) { + // typeName = sender?.type; + // hasEditPermission = roles?.some(role => + // role.permissions.some(permission => permission.name === `DELETE_${typeName}`)) + // } + // } + + // if (!hasEditPermission) { + // return `You don't have a permission to delete ${typeName}` + // } + + const permission = await Permission.findOne({ where: { id: payload.id } }); + + if (permission) { + permission.name = payload.name; + return permission.save(); + } else { + throw "Permission not found :("; + } } +// const getPermissionById = (payload: { id: number }) => { +// return Permission.findOne({ where: { id: payload.id } }) +// } + const getPermissions = async (payload: { - page: string, - pageSize: string - }) => { - - const page = parseInt(payload.page); - const pageSize = parseInt(payload.pageSize); - - const [permissions, total] = await Permission.findAndCount({ - skip: pageSize * (page - 1), - take: pageSize, - order: { - createdAt: 'ASC' - } - }) - - return { - page, - pageSize: permissions.length, - total, - permissions - }; + page: string, + pageSize: string, + id: number, + name: string +}) => { + + const page = parseInt(payload.page); + const pageSize = parseInt(payload.pageSize); + + if (payload.id){ + return Permission.findOne({ where: { id: payload.id } }) } -export { createPermission, deletePermission, editPermission, getPermission, getPermissions } \ No newline at end of file + if (payload.name){ + return Permission.findOne({ where: { name: payload.name } }) + } + + const [permissions, total] = await Permission.findAndCount({ + skip: pageSize * (page - 1), + take: pageSize, + order: { + createdAt: 'ASC' + } + }) + + return { + page, + pageSize: permissions.length, + total, + permissions + }; +} + +export { createPermission, deletePermission, editPermission, getPermissions } \ No newline at end of file diff --git a/src/controllers/voluntaryWork.ts b/src/controllers/voluntaryWork.ts index 35f80203..16386c49 100644 --- a/src/controllers/voluntaryWork.ts +++ b/src/controllers/voluntaryWork.ts @@ -1,5 +1,5 @@ import { In } from "typeorm"; -import { NSVoluntaryWork } from "../../types/volunteryWork.js"; +import { NSVoluntaryWork } from "../../types/voluntaryWork.js"; import { SkillTag } from "../db/entities/SkillTag.js"; import { VoluntaryWork } from "../db/entities/VoluntaryWork.js"; diff --git a/src/routes/permission.ts b/src/routes/permission.ts index 25df55e7..f7488fc0 100644 --- a/src/routes/permission.ts +++ b/src/routes/permission.ts @@ -1,5 +1,5 @@ import express from 'express'; -import { createPermission, deletePermission, editPermission, getPermission, getPermissions } from '../controllers/permission.js'; +import { createPermission, deletePermission, editPermission, getPermissions } from '../controllers/permission.js'; import { getSender } from '../controllers/index.js'; var router = express.Router(); @@ -35,23 +35,28 @@ router.put("/", async (req, res, next) => { }); }); -router.get("/:id", async (req, res) => { - const id = Number(req.params.id) +// router.get("/:id", async (req, res) => { +// const id = Number(req.params.id) - const permission = await getPermission({ id }); - if (permission) { - res.status(201).send(permission); - } else { - res.status(404).send("Permission not found :("); - } -}) +// const permission = await getPermissionById({ id }); +// if (permission) { +// res.status(201).send(permission); +// } else { +// res.status(404).send("Permission not found :("); +// } +// }) router.get('/', async (req, res, next) => { const payload = { page: req.query.page?.toString() || '1', - pageSize: req.query.pageSize?.toString() || '10' + pageSize: req.query.pageSize?.toString() || '10', + id: Number(req.query.id ) || 0, + name: req.query.name?.toString() || "" }; + console.log(req.query); + + getPermissions(payload) .then(data => { res.send(data); diff --git a/types/volunteryWork.ts b/types/voluntaryWork.ts similarity index 100% rename from types/volunteryWork.ts rename to types/voluntaryWork.ts From 64b9224a5e88aed1b12b1582d9790e139a47e324 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Tue, 3 Oct 2023 18:13:21 +0300 Subject: [PATCH 024/146] edit get roles to bring according to id , name and al of them --- src/controllers/permission.ts | 4 --- src/controllers/role.ts | 46 ++++++++++++++++++++--------------- src/routes/permission.ts | 12 --------- src/routes/role.ts | 18 ++++---------- 4 files changed, 31 insertions(+), 49 deletions(-) diff --git a/src/controllers/permission.ts b/src/controllers/permission.ts index d161630c..62402d03 100644 --- a/src/controllers/permission.ts +++ b/src/controllers/permission.ts @@ -71,10 +71,6 @@ const editPermission = async (payload: { name: string, id: number }) => { } } -// const getPermissionById = (payload: { id: number }) => { -// return Permission.findOne({ where: { id: payload.id } }) -// } - const getPermissions = async (payload: { page: string, pageSize: string, diff --git a/src/controllers/role.ts b/src/controllers/role.ts index 05b65502..c50259a1 100644 --- a/src/controllers/role.ts +++ b/src/controllers/role.ts @@ -34,32 +34,38 @@ const editRole = async (payload: { name: NSRole.Type, id: number }) => { } } -const getRole = (payload: { id: number }) => { - return Role.findOne({ where: { id: payload.id } }) -} - const getRoles = async (payload: { page: string, - pageSize: string -}) => { - + pageSize: string, + id: number, + name: NSRole.Type + }) => { + const page = parseInt(payload.page); const pageSize = parseInt(payload.pageSize); - + + if (payload.id){ + return Role.findOne({ where: { id: payload.id } }) + } + + if (payload.name){ + return Role.findOne({ where: { name: payload.name } }) + } + const [roles, total] = await Role.findAndCount({ - skip: pageSize * (page - 1), - take: pageSize, - order: { - createdAt: 'ASC' - } + skip: pageSize * (page - 1), + take: pageSize, + order: { + createdAt: 'ASC' + } }) - + return { - page, - pageSize: roles.length, - total, - roles + page, + pageSize: roles.length, + total, + roles }; -} + } -export { createRole, editRole, getRole, getRoles, deleteRole } \ No newline at end of file +export { createRole, editRole, getRoles, deleteRole } \ No newline at end of file diff --git a/src/routes/permission.ts b/src/routes/permission.ts index f7488fc0..3fd75cf3 100644 --- a/src/routes/permission.ts +++ b/src/routes/permission.ts @@ -1,6 +1,5 @@ import express from 'express'; import { createPermission, deletePermission, editPermission, getPermissions } from '../controllers/permission.js'; -import { getSender } from '../controllers/index.js'; var router = express.Router(); @@ -35,17 +34,6 @@ router.put("/", async (req, res, next) => { }); }); -// router.get("/:id", async (req, res) => { -// const id = Number(req.params.id) - -// const permission = await getPermissionById({ id }); -// if (permission) { -// res.status(201).send(permission); -// } else { -// res.status(404).send("Permission not found :("); -// } -// }) - router.get('/', async (req, res, next) => { const payload = { page: req.query.page?.toString() || '1', diff --git a/src/routes/role.ts b/src/routes/role.ts index 96e80dcb..5606823f 100644 --- a/src/routes/role.ts +++ b/src/routes/role.ts @@ -1,5 +1,6 @@ import express from 'express'; -import { createRole, deleteRole, editRole, getRole, getRoles } from '../controllers/role.js'; +import { createRole, deleteRole, editRole, getRoles } from '../controllers/role.js'; +import { NSRole } from '../../types/role.js'; var router = express.Router(); @@ -34,21 +35,12 @@ router.put("/", async (req, res, next) => { }); }); -router.get("/:id", async (req, res) => { - const id = Number(req.params.id) - - const role = await getRole({ id }); - if (role) { - res.status(201).send(role); - } else { - res.status(404).send("Role not found :("); - } -}) - router.get('/', async (req, res, next) => { const payload = { page: req.query.page?.toString() || '1', - pageSize: req.query.pageSize?.toString() || '10' + pageSize: req.query.pageSize?.toString() || '10', + id: Number(req.query.id ) || 0, + name: req.query.name?.toString() as NSRole.Type }; getRoles(payload) From cbcabddb173e2d3f07106631283e14188f114f7e Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Tue, 3 Oct 2023 19:33:31 +0300 Subject: [PATCH 025/146] creat advanced search for voluntary work --- src/controllers/voluntaryWork.ts | 57 +++++++++++++++++++++++++++----- src/routes/permission.ts | 3 -- src/routes/voluntaryWork.ts | 28 ++++++++-------- t.js | 0 4 files changed, 63 insertions(+), 25 deletions(-) create mode 100644 t.js diff --git a/src/controllers/voluntaryWork.ts b/src/controllers/voluntaryWork.ts index 16386c49..826d1539 100644 --- a/src/controllers/voluntaryWork.ts +++ b/src/controllers/voluntaryWork.ts @@ -1,7 +1,8 @@ -import { In } from "typeorm"; +import { FindOperator, In } from "typeorm"; import { NSVoluntaryWork } from "../../types/voluntaryWork.js"; import { SkillTag } from "../db/entities/SkillTag.js"; import { VoluntaryWork } from "../db/entities/VoluntaryWork.js"; +import { NSVolunteer } from "../../types/volunteer.js"; const createVoluntaryWork = async (payload: NSVoluntaryWork.Item) => { try { @@ -38,26 +39,66 @@ const getVoluntaryWork = (payload: { id: number }) => { const getVoluntaryWorks = async (payload: { page: string, - pageSize: string + pageSize: string, + id: number, + name: string, + time: NSVolunteer.AvailableTime[], + location: string, + days: NSVolunteer.AvailableDays[], + rating: number, + status: NSVoluntaryWork.StatusType, + skills: string[] }) => { - const page = parseInt(payload.page); const pageSize = parseInt(payload.pageSize); + const conditions = []; - const [VoluntaryWorks, total] = await VoluntaryWork.findAndCount({ + if (payload.id) { + return VoluntaryWork.findOne({ where: { id: payload.id } }) + } + if (payload.name) { + return VoluntaryWork.findOne({ where: { name: payload.name } }) + } + if (payload.time.length>0) { + conditions.push({ time: In(payload.time) }); + } + if (payload.location) { + conditions.push({ location: payload.location }); + } + if (payload.rating) { + conditions.push({ rating: payload.rating }); + } + if (payload.status) { + conditions.push({ status: payload.status }); + } + if (payload.days.length>0) { + conditions.push({ days: In(payload.days) }); + } + if (payload.skills.length>0) { + conditions.push({ skillTags: { name: In(payload.skills) } }); + } + + const query = { + where: conditions.length > 0 ? conditions : {}, + }; + + const [voluntaryWorks, total] = await VoluntaryWork.findAndCount({ + where: conditions.length > 0 ? conditions : {}, skip: pageSize * (page - 1), take: pageSize, order: { createdAt: 'ASC' - } - }) + }, + relations: ['skillTags'] // Include the skillTags relationship + }); return { page, - pageSize: VoluntaryWorks.length, + pageSize: voluntaryWorks.length, total, - VoluntaryWorks + voluntaryWorks }; } + export { createVoluntaryWork, editVoluntaryWork, getVoluntaryWork, getVoluntaryWorks, deleteVoluntaryWork } \ No newline at end of file diff --git a/src/routes/permission.ts b/src/routes/permission.ts index 3fd75cf3..cff1f18f 100644 --- a/src/routes/permission.ts +++ b/src/routes/permission.ts @@ -42,9 +42,6 @@ router.get('/', async (req, res, next) => { name: req.query.name?.toString() || "" }; - console.log(req.query); - - getPermissions(payload) .then(data => { res.send(data); diff --git a/src/routes/voluntaryWork.ts b/src/routes/voluntaryWork.ts index 2ce4e3e8..f8d8be89 100644 --- a/src/routes/voluntaryWork.ts +++ b/src/routes/voluntaryWork.ts @@ -1,11 +1,13 @@ import express from 'express'; import { createVoluntaryWork, deleteVoluntaryWork, editVoluntaryWork, getVoluntaryWork, getVoluntaryWorks } from '../controllers/voluntaryWork.js'; +import { NSVolunteer } from '../../types/volunteer.js'; +import { NSVoluntaryWork } from '../../types/voluntaryWork.js'; var router = express.Router(); router.post('/', (req, res, next) => { createVoluntaryWork(req.body).then(() => { - res.status(201).send("VoluntaryWork created successfully!!") + res.status(201).send("Voluntary work created successfully!!") }).catch(err => { console.error(err); res.status(500).send(err); @@ -34,23 +36,21 @@ router.put("/", async (req, res, next) => { }); }); -router.get("/:id", async (req, res) => { - const id = Number(req.params.id) - - const voluntaryWork = await getVoluntaryWork({ id }); - if (voluntaryWork) { - res.status(201).send(voluntaryWork); - } else { - res.status(404).send("VoluntaryWork not found :("); - } -}) - router.get('/', async (req, res, next) => { + const payload = { page: req.query.page?.toString() || '1', - pageSize: req.query.pageSize?.toString() || '10' + pageSize: req.query.pageSize?.toString() || '10', + id: Number(req.query.id) || 0, + name: req.query.name?.toString() || '', + time: ((Array.isArray(req.query.time) ? req.query.time : [req.query.time]).filter(Boolean)) as NSVolunteer.AvailableTime[], + location: (typeof req.query.location === 'string' ? req.query.location : ''), + days: (Array.isArray(req.query.days) ? req.query.days : [req.query.days]).filter(Boolean) as NSVolunteer.AvailableDays[], + rating: Number(req.query.rating) || 0, + status: req.query.status as NSVoluntaryWork.StatusType, + skills: (Array.isArray(req.query.skills) ? req.query.skills : [req.query.skills]).filter(Boolean) as string[], }; - + getVoluntaryWorks(payload) .then(data => { res.send(data); diff --git a/t.js b/t.js new file mode 100644 index 00000000..e69de29b From 59558870d370220e8d8416ddb6e368a0ddd3c184 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Tue, 3 Oct 2023 20:34:32 +0300 Subject: [PATCH 026/146] add capacity --- src/controllers/voluntaryWork.ts | 82 ++++++++++++++++++++++++++++++-- src/routes/voluntaryWork.ts | 3 ++ t.js | 0 3 files changed, 81 insertions(+), 4 deletions(-) delete mode 100644 t.js diff --git a/src/controllers/voluntaryWork.ts b/src/controllers/voluntaryWork.ts index 826d1539..128c3bdf 100644 --- a/src/controllers/voluntaryWork.ts +++ b/src/controllers/voluntaryWork.ts @@ -37,6 +37,68 @@ const getVoluntaryWork = (payload: { id: number }) => { return VoluntaryWork.findOne({ where: { id: payload.id } }) } +// const getVoluntaryWorks = async (payload: { +// page: string, +// pageSize: string, +// id: number, +// name: string, +// time: NSVolunteer.AvailableTime[], +// location: string, +// days: NSVolunteer.AvailableDays[], +// rating: number, +// status: NSVoluntaryWork.StatusType, +// skills: string[] +// }) => { +// const page = parseInt(payload.page); +// const pageSize = parseInt(payload.pageSize); +// const conditions = []; + +// if (payload.id) { +// return VoluntaryWork.findOne({ where: { id: payload.id } }) +// } +// if (payload.name) { +// return VoluntaryWork.findOne({ where: { name: payload.name } }) +// } +// if (payload.time.length>0) { +// conditions.push({ time: In(payload.time) }); +// } +// if (payload.location) { +// conditions.push({ location: payload.location }); +// } +// if (payload.rating) { +// conditions.push({ rating: payload.rating }); +// } +// if (payload.status) { +// conditions.push({ status: payload.status }); +// } +// if (payload.days.length>0) { +// conditions.push({ days: In(payload.days) }); +// } +// if (payload.skills.length>0) { +// conditions.push({ skillTags: { name: In(payload.skills) } }); +// } + +// const query = { +// where: conditions.length > 0 ? conditions : {}, +// }; + +// const [voluntaryWorks, total] = await VoluntaryWork.findAndCount({ +// where: conditions.length > 0 ? conditions : {}, +// skip: pageSize * (page - 1), +// take: pageSize, +// order: { +// createdAt: 'ASC' +// }, +// relations: ['skillTags'] // Include the skillTags relationship +// }); + +// return { +// page, +// pageSize: voluntaryWorks.length, +// total, +// voluntaryWorks +// }; +// } const getVoluntaryWorks = async (payload: { page: string, pageSize: string, @@ -47,7 +109,10 @@ const getVoluntaryWorks = async (payload: { days: NSVolunteer.AvailableDays[], rating: number, status: NSVoluntaryWork.StatusType, - skills: string[] + skills: string[], + // startedDate: Date; // Add the startedDate property + // finishedDate: Date; // Add the finishedDate property + capacity: number; }) => { const page = parseInt(payload.page); const pageSize = parseInt(payload.pageSize); @@ -59,7 +124,7 @@ const getVoluntaryWorks = async (payload: { if (payload.name) { return VoluntaryWork.findOne({ where: { name: payload.name } }) } - if (payload.time.length>0) { + if (payload.time.length > 0) { conditions.push({ time: In(payload.time) }); } if (payload.location) { @@ -71,12 +136,21 @@ const getVoluntaryWorks = async (payload: { if (payload.status) { conditions.push({ status: payload.status }); } - if (payload.days.length>0) { + if (payload.days.length > 0) { conditions.push({ days: In(payload.days) }); } - if (payload.skills.length>0) { + if (payload.skills.length > 0) { conditions.push({ skillTags: { name: In(payload.skills) } }); } + // if (payload.startedDate) { + // conditions.push({ startedDate: payload.startedDate }); // Add startedDate condition + // } + // if (payload.finishedDate) { + // conditions.push({ finishedDate: payload.finishedDate }); // Add finishedDate condition + // } + if (payload.capacity) { + conditions.push({ capacity: payload.capacity }); // Add capacity condition + } const query = { where: conditions.length > 0 ? conditions : {}, diff --git a/src/routes/voluntaryWork.ts b/src/routes/voluntaryWork.ts index f8d8be89..778dfa52 100644 --- a/src/routes/voluntaryWork.ts +++ b/src/routes/voluntaryWork.ts @@ -49,6 +49,9 @@ router.get('/', async (req, res, next) => { rating: Number(req.query.rating) || 0, status: req.query.status as NSVoluntaryWork.StatusType, skills: (Array.isArray(req.query.skills) ? req.query.skills : [req.query.skills]).filter(Boolean) as string[], + // startedDate: req.query.startedDate || new Date(2023, 1, 30) , + // finishedDate: req.query.finishedDate || new Date(2023, 1, 30), + capacity: Number(req.query.capacity) || 0 }; getVoluntaryWorks(payload) diff --git a/t.js b/t.js deleted file mode 100644 index e69de29b..00000000 From eaea9e2b0d9ce5383d397bdf9f9902f9884d2f79 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Tue, 3 Oct 2023 20:56:36 +0300 Subject: [PATCH 027/146] edit the types of dates to be string --- src/controllers/voluntaryWork.ts | 16 ++++++++-------- src/db/entities/VoluntaryWork.ts | 8 ++++---- src/routes/voluntaryWork.ts | 4 ++-- types/voluntaryWork.ts | 8 ++++---- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/controllers/voluntaryWork.ts b/src/controllers/voluntaryWork.ts index 128c3bdf..c091a24f 100644 --- a/src/controllers/voluntaryWork.ts +++ b/src/controllers/voluntaryWork.ts @@ -110,8 +110,8 @@ const getVoluntaryWorks = async (payload: { rating: number, status: NSVoluntaryWork.StatusType, skills: string[], - // startedDate: Date; // Add the startedDate property - // finishedDate: Date; // Add the finishedDate property + startedDate: string; + finishedDate: string; capacity: number; }) => { const page = parseInt(payload.page); @@ -142,12 +142,12 @@ const getVoluntaryWorks = async (payload: { if (payload.skills.length > 0) { conditions.push({ skillTags: { name: In(payload.skills) } }); } - // if (payload.startedDate) { - // conditions.push({ startedDate: payload.startedDate }); // Add startedDate condition - // } - // if (payload.finishedDate) { - // conditions.push({ finishedDate: payload.finishedDate }); // Add finishedDate condition - // } + if (payload.startedDate) { + conditions.push({ startedDate: payload.startedDate }); // Add startedDate condition + } + if (payload.finishedDate) { + conditions.push({ finishedDate: payload.finishedDate }); // Add finishedDate condition + } if (payload.capacity) { conditions.push({ capacity: payload.capacity }); // Add capacity condition } diff --git a/src/db/entities/VoluntaryWork.ts b/src/db/entities/VoluntaryWork.ts index 6552db1d..72f7beec 100644 --- a/src/db/entities/VoluntaryWork.ts +++ b/src/db/entities/VoluntaryWork.ts @@ -31,11 +31,11 @@ export class VoluntaryWork extends BaseEntity { @Column({ nullable: false }) location: string; - @CreateDateColumn({ type: 'timestamp', nullable: false }) - startedDate: Date; + @CreateDateColumn({nullable: false }) + startedDate: string; - @CreateDateColumn({ type: 'timestamp', nullable: false }) - finishedDate: Date; + @CreateDateColumn({nullable: false }) + finishedDate: string; @Column({ type: 'enum', diff --git a/src/routes/voluntaryWork.ts b/src/routes/voluntaryWork.ts index 778dfa52..3270659b 100644 --- a/src/routes/voluntaryWork.ts +++ b/src/routes/voluntaryWork.ts @@ -49,8 +49,8 @@ router.get('/', async (req, res, next) => { rating: Number(req.query.rating) || 0, status: req.query.status as NSVoluntaryWork.StatusType, skills: (Array.isArray(req.query.skills) ? req.query.skills : [req.query.skills]).filter(Boolean) as string[], - // startedDate: req.query.startedDate || new Date(2023, 1, 30) , - // finishedDate: req.query.finishedDate || new Date(2023, 1, 30), + startedDate: req.query.startedDate?.toString() || "", + finishedDate: req.query.finishedDate ?.toString() ||"", capacity: Number(req.query.capacity) || 0 }; diff --git a/types/voluntaryWork.ts b/types/voluntaryWork.ts index a01b62de..17c1220b 100644 --- a/types/voluntaryWork.ts +++ b/types/voluntaryWork.ts @@ -20,8 +20,8 @@ export namespace NSVoluntaryWork { feedback?: string; status?: StatusType; days?: NSVolunteer.AvailableDays[]; - startedDate?: Date; - finishedDate?: Date; + startedDate?: string; + finishedDate?: string; capacity?: number; skillTagIds?: number[]; createdAt?: Date; @@ -40,8 +40,8 @@ export namespace NSVoluntaryWork { status: StatusType; createdAt?: Date; days: NSVolunteer.AvailableDays[]; - startedDate: Date; - finishedDate: Date; + startedDate: string; + finishedDate: string; capacity: number; skillTagIds: number[]; } From c96e0f5bdd5dd828a0c90713a2be5f51aae06852 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Tue, 3 Oct 2023 21:03:45 +0300 Subject: [PATCH 028/146] adding started and finished date to adances search --- src/db/entities/VoluntaryWork.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/db/entities/VoluntaryWork.ts b/src/db/entities/VoluntaryWork.ts index 72f7beec..6973fe4e 100644 --- a/src/db/entities/VoluntaryWork.ts +++ b/src/db/entities/VoluntaryWork.ts @@ -31,10 +31,10 @@ export class VoluntaryWork extends BaseEntity { @Column({ nullable: false }) location: string; - @CreateDateColumn({nullable: false }) + @Column({nullable: false }) startedDate: string; - @CreateDateColumn({nullable: false }) + @Column({nullable: false }) finishedDate: string; @Column({ From ce779fc47964c081c4681807691a300bd8cda9bd Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Wed, 4 Oct 2023 10:02:35 +0300 Subject: [PATCH 029/146] edit the voluntary work type --- src/controllers/voluntaryWork.ts | 66 -------------------------------- src/db/entities/VoluntaryWork.ts | 6 +-- types/voluntaryWork.ts | 7 ++-- 3 files changed, 7 insertions(+), 72 deletions(-) diff --git a/src/controllers/voluntaryWork.ts b/src/controllers/voluntaryWork.ts index c091a24f..c0cadbb6 100644 --- a/src/controllers/voluntaryWork.ts +++ b/src/controllers/voluntaryWork.ts @@ -37,68 +37,6 @@ const getVoluntaryWork = (payload: { id: number }) => { return VoluntaryWork.findOne({ where: { id: payload.id } }) } -// const getVoluntaryWorks = async (payload: { -// page: string, -// pageSize: string, -// id: number, -// name: string, -// time: NSVolunteer.AvailableTime[], -// location: string, -// days: NSVolunteer.AvailableDays[], -// rating: number, -// status: NSVoluntaryWork.StatusType, -// skills: string[] -// }) => { -// const page = parseInt(payload.page); -// const pageSize = parseInt(payload.pageSize); -// const conditions = []; - -// if (payload.id) { -// return VoluntaryWork.findOne({ where: { id: payload.id } }) -// } -// if (payload.name) { -// return VoluntaryWork.findOne({ where: { name: payload.name } }) -// } -// if (payload.time.length>0) { -// conditions.push({ time: In(payload.time) }); -// } -// if (payload.location) { -// conditions.push({ location: payload.location }); -// } -// if (payload.rating) { -// conditions.push({ rating: payload.rating }); -// } -// if (payload.status) { -// conditions.push({ status: payload.status }); -// } -// if (payload.days.length>0) { -// conditions.push({ days: In(payload.days) }); -// } -// if (payload.skills.length>0) { -// conditions.push({ skillTags: { name: In(payload.skills) } }); -// } - -// const query = { -// where: conditions.length > 0 ? conditions : {}, -// }; - -// const [voluntaryWorks, total] = await VoluntaryWork.findAndCount({ -// where: conditions.length > 0 ? conditions : {}, -// skip: pageSize * (page - 1), -// take: pageSize, -// order: { -// createdAt: 'ASC' -// }, -// relations: ['skillTags'] // Include the skillTags relationship -// }); - -// return { -// page, -// pageSize: voluntaryWorks.length, -// total, -// voluntaryWorks -// }; -// } const getVoluntaryWorks = async (payload: { page: string, pageSize: string, @@ -152,10 +90,6 @@ const getVoluntaryWorks = async (payload: { conditions.push({ capacity: payload.capacity }); // Add capacity condition } - const query = { - where: conditions.length > 0 ? conditions : {}, - }; - const [voluntaryWorks, total] = await VoluntaryWork.findAndCount({ where: conditions.length > 0 ? conditions : {}, skip: pageSize * (page - 1), diff --git a/src/db/entities/VoluntaryWork.ts b/src/db/entities/VoluntaryWork.ts index 6973fe4e..cdb65c9a 100644 --- a/src/db/entities/VoluntaryWork.ts +++ b/src/db/entities/VoluntaryWork.ts @@ -44,13 +44,13 @@ export class VoluntaryWork extends BaseEntity { }) status: 'Pending' | 'In Progress' | 'Finished' | 'Canceled'; - @Column({ type: 'text', nullable: false, transformer: { to: (value) => JSON.stringify(value), from: (value) => JSON.parse(value) } }) + @Column({ type: 'text', nullable: true, transformer: { to: (value) => JSON.stringify(value), from: (value) => JSON.parse(value) } }) images: string[]; - @Column() + @Column({nullable:true}) rating: number; - @Column() + @Column({nullable:true}) feedback: string; @Column() diff --git a/types/voluntaryWork.ts b/types/voluntaryWork.ts index 17c1220b..bc4aed7b 100644 --- a/types/voluntaryWork.ts +++ b/types/voluntaryWork.ts @@ -34,9 +34,9 @@ export namespace NSVoluntaryWork { description: string; location: string; time: NSVolunteer.AvailableTime[]; - images: string[]; - rating: number; - feedback: string; + images?: string[]; + rating?: number; + feedback?: string; status: StatusType; createdAt?: Date; days: NSVolunteer.AvailableDays[]; @@ -46,3 +46,4 @@ export namespace NSVoluntaryWork { skillTagIds: number[]; } } +//edit From f6acfd203dcba37e0849805a1509c7ad20049a8a Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Wed, 4 Oct 2023 10:23:25 +0300 Subject: [PATCH 030/146] added search by started and finished date --- src/controllers/voluntaryWork.ts | 16 +++++++++++++--- src/routes/voluntaryWork.ts | 6 +++++- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/controllers/voluntaryWork.ts b/src/controllers/voluntaryWork.ts index c0cadbb6..ba54fb1b 100644 --- a/src/controllers/voluntaryWork.ts +++ b/src/controllers/voluntaryWork.ts @@ -51,6 +51,10 @@ const getVoluntaryWorks = async (payload: { startedDate: string; finishedDate: string; capacity: number; + finishedAfter:string; + finishedBefore:string; + startedAfter:string; + startedBefore:string; }) => { const page = parseInt(payload.page); const pageSize = parseInt(payload.pageSize); @@ -81,13 +85,19 @@ const getVoluntaryWorks = async (payload: { conditions.push({ skillTags: { name: In(payload.skills) } }); } if (payload.startedDate) { - conditions.push({ startedDate: payload.startedDate }); // Add startedDate condition + conditions.push({ startedDate: payload.startedDate }); } if (payload.finishedDate) { - conditions.push({ finishedDate: payload.finishedDate }); // Add finishedDate condition + conditions.push({ finishedDate: payload.finishedDate }); } if (payload.capacity) { - conditions.push({ capacity: payload.capacity }); // Add capacity condition + conditions.push({ capacity: payload.capacity }); + } + if(payload.finishedDate){ + conditions.push({ finishedDate: payload.finishedDate }); + } + if(payload.startedDate){ + conditions.push({ startedDate: payload.startedDate }); } const [voluntaryWorks, total] = await VoluntaryWork.findAndCount({ diff --git a/src/routes/voluntaryWork.ts b/src/routes/voluntaryWork.ts index 3270659b..5b21b006 100644 --- a/src/routes/voluntaryWork.ts +++ b/src/routes/voluntaryWork.ts @@ -51,7 +51,11 @@ router.get('/', async (req, res, next) => { skills: (Array.isArray(req.query.skills) ? req.query.skills : [req.query.skills]).filter(Boolean) as string[], startedDate: req.query.startedDate?.toString() || "", finishedDate: req.query.finishedDate ?.toString() ||"", - capacity: Number(req.query.capacity) || 0 + capacity: Number(req.query.capacity) || 0, + finishedAfter: req.query.finishedDate ?.toString() ||"", + finishedBefore:req.query.finishedBefore?.toString() || "", + startedAfter:req.query.startedAfter?.toString() || "", + startedBefore: req.query.startedBefore?.toString() || "" }; getVoluntaryWorks(payload) From 0be8b4f711c449803339d58cb4fe021d12b0f7fe Mon Sep 17 00:00:00 2001 From: TarteelTamimi Date: Wed, 4 Oct 2023 21:14:49 +0300 Subject: [PATCH 031/146] add org. admin & org. profile controllers --- app.ts | 5 +- src/controllers/OrganizationProfile .ts | 78 ++++++++++++++++++ src/controllers/organizationAdmin.ts | 102 ++++++++++++++++++++++++ src/controllers/volunteer.ts | 23 ++++++ src/routes/organizationAdmin.ts | 17 ++++ 5 files changed, 224 insertions(+), 1 deletion(-) create mode 100644 src/controllers/OrganizationProfile .ts create mode 100644 src/controllers/organizationAdmin.ts create mode 100644 src/controllers/volunteer.ts create mode 100644 src/routes/organizationAdmin.ts diff --git a/app.ts b/app.ts index 2c4f1082..072c6413 100644 --- a/app.ts +++ b/app.ts @@ -9,6 +9,7 @@ import indexRouter from "./src/routes/index.js" import permissionRouter from "./src/routes/permission.js" import roleRouter from "./src/routes/role.js" import voluntaryWorkRouter from "./src/routes/voluntaryWork.js" +import organizationAdminRouter from "./src/routes/organizationAdmin.js" const app = express(); dotenv.config(); @@ -20,7 +21,9 @@ app.use(express.urlencoded({ extended: false })); app.use('/', indexRouter); app.use('/permission',permissionRouter); app.use('/role',roleRouter); -app.use('/voluntaryWork',voluntaryWorkRouter) +app.use('/voluntaryWork',voluntaryWorkRouter); +app.use('/organivationAdmin',organizationAdminRouter); + // app.use('/users', usersRouter); // catch 404 and forward to error handler diff --git a/src/controllers/OrganizationProfile .ts b/src/controllers/OrganizationProfile .ts new file mode 100644 index 00000000..5f255b5d --- /dev/null +++ b/src/controllers/OrganizationProfile .ts @@ -0,0 +1,78 @@ +import { NSOrganizationProfile } from "../../types/organizationProfile.js"; +import { OrganizationAdmin } from "../db/entities/OrganizationAdmin.js"; +import { OrganizationProfile } from "../db/entities/OrganizationProfile.js"; + +const creatOrganizationProfile = async (payload: NSOrganizationProfile.Item) => { + + const newOrganizationProfile = OrganizationProfile.create(payload); + return newOrganizationProfile.save(); +} + +const editOrganizationProfile = async (payload: { id: string, name: string, description: string }) => { + let profile = await OrganizationProfile.findOne({ where: { id: payload.id } }); + + if (profile) { + + profile = Object.assign(profile, payload); + return profile.save(); + } else { + throw "Organization profile not found :("; + } +} + +const deleteOrganizationProfile = async (profileId: number) => { + return OrganizationProfile.delete(profileId); +} + +const getOrganizationProfile = async (payload: { + page: string, + pageSize: string, + id: string, + name: string, + adminName: string +}) => { + + const page = parseInt(payload.page); + const pageSize = parseInt(payload.pageSize); + + if (payload.id) { + return OrganizationProfile.findOne({ where: { id: payload.id } }) + } + + if (payload.name) { + return OrganizationProfile.findOne({ where: { name: payload.name } }) + } + + if (payload.adminName) { + const admin = await OrganizationAdmin.findOne({ where: { name: payload.name } }); + + // if (admin) { + + // return await OrganizationProfile.findOne({ where: { orgProfile: { id: admin.id } } }); + // } else { + // throw "Admin name not found :("; + // } + + //get OrganizationProfile by organizationAdmin + + + } + + const [orgs, total] = await OrganizationProfile.findAndCount({ + skip: pageSize * (page - 1), + take: pageSize, + order: { + createdAt: 'ASC' + } + }) + + return { + page, + pageSize: orgs.length, + total, + orgs + }; +} + + +export { creatOrganizationProfile, editOrganizationProfile, deleteOrganizationProfile, getOrganizationProfile } \ No newline at end of file diff --git a/src/controllers/organizationAdmin.ts b/src/controllers/organizationAdmin.ts new file mode 100644 index 00000000..33e50096 --- /dev/null +++ b/src/controllers/organizationAdmin.ts @@ -0,0 +1,102 @@ +import { NSOrganizationAdmin } from "../../types/organizationAdmin.js"; +import { OrganizationAdmin } from "../db/entities/OrganizationAdmin.js"; +import { OrganizationProfile } from "../db/entities/OrganizationProfile.js"; +import bcrypt from 'bcrypt'; + +const creatOrganizationAdmin = async (payload: NSOrganizationAdmin.Item) => { + + const newOrganizationAdmin = OrganizationAdmin.create(payload); + + const organization = await OrganizationProfile.findOne({ + where: { id: payload.organizationId }, + }); + + if (organization) { + newOrganizationAdmin.orgProfile = organization; + return newOrganizationAdmin.save(); + } else { + throw "Organization not found :("; + } +} + +const getOrganizationAdmins = async (payload: { + page: string, + pageSize: string, + id: string, + name: string, + email: string, + organizationName: string +}) => { + const page = parseInt(payload.page); + const pageSize = parseInt(payload.pageSize); + + if (payload.id) { + return OrganizationAdmin.findOne({ where: { id: payload.id } }) + } + if (payload.name) { + return OrganizationAdmin.findOne({ where: { name: payload.name } }) + } + if (payload.email) { + return OrganizationAdmin.findOne({ where: { email: payload.email } }) + } + if (payload.organizationName) { + const organization = await OrganizationProfile.findOne({ where: { name: payload.name } }); + if (organization) { + + return await OrganizationAdmin.findOne({ where: { orgProfile: { id: organization.id } } }); + } else { + throw "Organization name not found :("; + } + } + + const [admins, total] = await OrganizationAdmin.findAndCount({ + skip: pageSize * (page - 1), + take: pageSize, + order: { + createdAt: 'ASC' + } + }) + + return { + page, + pageSize: admins.length, + total, + admins + }; +} + +const deleteOrganizationAdmin = async (adminId: number) => { + return OrganizationAdmin.delete(adminId); +} + +const editOrganizationAdmin = async (payload: { id: string, name: string, email: string, password: string, organizationName: string }) => { + + const admin = await OrganizationAdmin.findOne({ where: { id: payload.id } }); + + if (admin) { + if (payload.name) + admin.name = payload.name; + + if (payload.email) + admin.email = payload.email; + + if (payload.password) { + admin.password = await bcrypt.hash(payload.password, 10); + + if (payload.organizationName) { + + const profile = await OrganizationProfile.findOne({ where: { name: payload.organizationName } }); + if (profile) { + admin.orgProfile = profile; + } + } + return admin.save(); + } + + } else { + throw "Organization admin not found :("; + } +} + + +export { creatOrganizationAdmin, deleteOrganizationAdmin, editOrganizationAdmin, getOrganizationAdmins } \ No newline at end of file diff --git a/src/controllers/volunteer.ts b/src/controllers/volunteer.ts new file mode 100644 index 00000000..c91a3877 --- /dev/null +++ b/src/controllers/volunteer.ts @@ -0,0 +1,23 @@ +// import { NSVolunteer } from "../../types/volunteer.js"; +// import dataSource from "../db/dataSource.js"; +// import { Role } from "../db/entities/Role.js"; +// import { VolunteerProfile } from "../db/entities/VolunteerProfile.js"; + +// const createVolunteer = async (payload: NSVolunteer.Item) => { +// return dataSource.manager.transaction(async (transaction) => { +// const [firstName, ...lastName] = payload.name.split(" ") +// const profile = VolunteerProfile.create({ +// firstName, +// lastName: lastName.join(" "), +// dateOfBirth: payload.dateOfBirth || '', +// status: payload?.status +// }) +// await transaction.save(profile) +// const newUser = User.create(payload); +// const roles = await Role.find({ where: { name: newUser?.type || 'user' } }) +// newUser.roles = roles; +// newUser.profile = profile; +// await transaction.save(newUser); +// }); +// }; + diff --git a/src/routes/organizationAdmin.ts b/src/routes/organizationAdmin.ts new file mode 100644 index 00000000..9287bfe7 --- /dev/null +++ b/src/routes/organizationAdmin.ts @@ -0,0 +1,17 @@ +import express from "express"; +import { creatOrganizationAdmin } from "../controllers/organizationAdmin.js"; + +var router = express.Router(); + +router.post('/', (req, res, next) => { + creatOrganizationAdmin(req.body).then((data) => { + console.log(data); + + res.status(201).send("Organization Admin created successfully!!") + }).catch(err => { + console.error(err); + res.status(500).send(err); + }); +}); + +export default router; \ No newline at end of file From 4f130909498714dd60e7716ec56a146e36ea0833 Mon Sep 17 00:00:00 2001 From: TarteelTamimi Date: Wed, 4 Oct 2023 22:04:32 +0300 Subject: [PATCH 032/146] add routers for org. admin & org. profile --- src/controllers/OrganizationProfile .ts | 19 ++++---- src/routes/organizationAdmin.ts | 52 +++++++++++++++++++--- src/routes/organizationProfile.ts | 58 +++++++++++++++++++++++++ 3 files changed, 114 insertions(+), 15 deletions(-) create mode 100644 src/routes/organizationProfile.ts diff --git a/src/controllers/OrganizationProfile .ts b/src/controllers/OrganizationProfile .ts index 5f255b5d..bce039f1 100644 --- a/src/controllers/OrganizationProfile .ts +++ b/src/controllers/OrganizationProfile .ts @@ -43,20 +43,19 @@ const getOrganizationProfile = async (payload: { return OrganizationProfile.findOne({ where: { name: payload.name } }) } - if (payload.adminName) { - const admin = await OrganizationAdmin.findOne({ where: { name: payload.name } }); + // //get OrganizationProfile by organizationAdmin - // if (admin) { + // if (payload.adminName) { + // const admin = await OrganizationAdmin.findOne({ where: { name: payload.name } }); - // return await OrganizationProfile.findOne({ where: { orgProfile: { id: admin.id } } }); - // } else { - // throw "Admin name not found :("; - // } + // if (admin) { - //get OrganizationProfile by organizationAdmin + // return await OrganizationProfile.findOne({ where: { orgProfile: { id: admin.id } } }); + // } else { + // throw "Admin name not found :("; + // } - - } + // } const [orgs, total] = await OrganizationProfile.findAndCount({ skip: pageSize * (page - 1), diff --git a/src/routes/organizationAdmin.ts b/src/routes/organizationAdmin.ts index 9287bfe7..cf7482ca 100644 --- a/src/routes/organizationAdmin.ts +++ b/src/routes/organizationAdmin.ts @@ -1,12 +1,10 @@ import express from "express"; -import { creatOrganizationAdmin } from "../controllers/organizationAdmin.js"; +import { creatOrganizationAdmin, deleteOrganizationAdmin, editOrganizationAdmin, getOrganizationAdmins } from "../controllers/organizationAdmin.js"; -var router = express.Router(); +const router = express.Router(); router.post('/', (req, res, next) => { - creatOrganizationAdmin(req.body).then((data) => { - console.log(data); - + creatOrganizationAdmin(req.body).then(() => { res.status(201).send("Organization Admin created successfully!!") }).catch(err => { console.error(err); @@ -14,4 +12,48 @@ router.post('/', (req, res, next) => { }); }); +router.delete('/:id', async (req, res) => { + const id = Number(req.params.id?.toString()); + + deleteOrganizationAdmin(id) + .then(data => { + res.send(data); + }) + .catch(error => { + console.error(error); + res.status(500).send('Something went wrong'); + }); +}); + +router.put("/", async (req, res, next) => { + editOrganizationAdmin(req.body).then(() => { + res.status(201).send("Organization Admin edited successfully!!") + }).catch(err => { + console.error(err); + res.status(500).send(err); + }); +}); + +router.get('/', async (req, res, next) => { + const payload = { + page: req.query.page?.toString() || '1', + pageSize: req.query.pageSize?.toString() || '10', + id: req.query.id?.toString() || '', + name: req.query.name?.toString() || '', + email: req.query.eamil?.toString() || '', + organizationName: req.query.organizationName?.toString() || '' + }; + + getOrganizationAdmins(payload) + .then(data => { + res.send(data); + }) + .catch(error => { + console.error(error); + res.status(500).send('Something went wrong'); + }); +}); + + + export default router; \ No newline at end of file diff --git a/src/routes/organizationProfile.ts b/src/routes/organizationProfile.ts new file mode 100644 index 00000000..e8635f79 --- /dev/null +++ b/src/routes/organizationProfile.ts @@ -0,0 +1,58 @@ +import express from "express"; +import { creatOrganizationProfile, deleteOrganizationProfile, editOrganizationProfile, getOrganizationProfile } from "../controllers/OrganizationProfile .js"; + +const router = express.Router(); + +router.post('/', (req, res, next) => { + creatOrganizationProfile(req.body).then(() => { + res.status(201).send("Organization Profile created successfully!!") + }).catch(err => { + console.error(err); + res.status(500).send(err); + }); +}); + +router.delete('/:id', async (req, res) => { + const id = Number(req.params.id?.toString()); + + deleteOrganizationProfile(id) + .then(data => { + res.send(data); + }) + .catch(error => { + console.error(error); + res.status(500).send('Something went wrong'); + }); +}); + +router.put("/", async (req, res, next) => { + editOrganizationProfile(req.body).then(() => { + res.status(201).send("Organization Profile edited successfully!!") + }).catch(err => { + console.error(err); + res.status(500).send(err); + }); +}); + +router.get('/', async (req, res, next) => { + const payload = { + page: req.query.page?.toString() || '1', + pageSize: req.query.pageSize?.toString() || '10', + id: req.query.id?.toString() || '', + name: req.query.name?.toString() || '', + adminName: req.query.adminName?.toString() || '' + }; + + getOrganizationProfile(payload) + .then(data => { + res.send(data); + }) + .catch(error => { + console.error(error); + res.status(500).send('Something went wrong'); + }); +}); + + + +export default router; \ No newline at end of file From 346d9c1299f6d09157bb307150b3f9624f2ca1f2 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Thu, 5 Oct 2023 10:23:59 +0300 Subject: [PATCH 033/146] Edit the entites and v.w types and creat v.w to match the started and finished date type --- .j.js | 4 ++ src/controllers/index.ts | 8 +++- src/controllers/voluntaryWork.ts | 57 +++++++++++++------------- src/db/entities/OrganizationAdmin.ts | 2 +- src/db/entities/OrganizationProfile.ts | 4 +- src/db/entities/Role.ts | 2 +- src/db/entities/VoluntaryWork.ts | 13 +++--- src/routes/voluntaryWork.ts | 20 ++++----- types/voluntaryWork.ts | 9 +++- 9 files changed, 67 insertions(+), 52 deletions(-) create mode 100644 .j.js diff --git a/.j.js b/.j.js new file mode 100644 index 00000000..b5e1de40 --- /dev/null +++ b/.j.js @@ -0,0 +1,4 @@ +let x = "2023-10-7".split('-').map( (str) =>{return parseInt(str, 10);}); + + +console.log(x); \ No newline at end of file diff --git a/src/controllers/index.ts b/src/controllers/index.ts index 39096aa4..978b6953 100644 --- a/src/controllers/index.ts +++ b/src/controllers/index.ts @@ -1,6 +1,7 @@ import express from 'express' import { OrganizationAdmin } from '../db/entities/OrganizationAdmin.js'; import { Volunteer } from '../db/entities/Volunteer.js'; +import { NSVoluntaryWork } from '../../types/voluntaryWork.js'; const getSender =async (res:express.Response)=>{ let sender: OrganizationAdmin | Volunteer = new Volunteer(); @@ -20,4 +21,9 @@ const getSender =async (res:express.Response)=>{ return sender; } -export {getSender}; \ No newline at end of file +const getDate = (date:string): Date | Date=>{ + let [year, month, day] =date.split('-').map( (str) =>{return parseInt(str, 10);}); + return new Date(year,month,day,0,0,0,0); +} + +export {getSender, getDate}; \ No newline at end of file diff --git a/src/controllers/voluntaryWork.ts b/src/controllers/voluntaryWork.ts index ba54fb1b..d8758ec4 100644 --- a/src/controllers/voluntaryWork.ts +++ b/src/controllers/voluntaryWork.ts @@ -1,23 +1,22 @@ -import { FindOperator, In } from "typeorm"; +import { DeepPartial, FindOperator, In } from "typeorm"; import { NSVoluntaryWork } from "../../types/voluntaryWork.js"; import { SkillTag } from "../db/entities/SkillTag.js"; import { VoluntaryWork } from "../db/entities/VoluntaryWork.js"; import { NSVolunteer } from "../../types/volunteer.js"; +import { getDate } from "./index.js"; const createVoluntaryWork = async (payload: NSVoluntaryWork.Item) => { - try { - const newVoluntaryWork = VoluntaryWork.create(payload); - const skillTags = await SkillTag.find({ - where: { id: In(payload.skillTagIds) }, - }); - newVoluntaryWork.skillTags = skillTags; - return newVoluntaryWork.save(); - } - catch (error) { - console.log(error); - } + let payload2 = { ...payload, startedDate: getDate(payload.startedDate), finishedDate: getDate(payload.finishedDate) }; + + let newVoluntaryWork = VoluntaryWork.create(payload2 as DeepPartial); + const skillTags = await SkillTag.find({ + where: { id: In(payload.skillTagIds) }, + }); + newVoluntaryWork.skillTags = skillTags; + return newVoluntaryWork.save(); } + const deleteVoluntaryWork = async (voluntaryWorkId: number) => { return VoluntaryWork.delete(voluntaryWorkId); } @@ -48,13 +47,13 @@ const getVoluntaryWorks = async (payload: { rating: number, status: NSVoluntaryWork.StatusType, skills: string[], - startedDate: string; - finishedDate: string; - capacity: number; - finishedAfter:string; - finishedBefore:string; - startedAfter:string; - startedBefore:string; + startedDate: string; + finishedDate: string; + capacity: number; + finishedAfter: string; + finishedBefore: string; + startedAfter: string; + startedBefore: string; }) => { const page = parseInt(payload.page); const pageSize = parseInt(payload.pageSize); @@ -84,24 +83,24 @@ const getVoluntaryWorks = async (payload: { if (payload.skills.length > 0) { conditions.push({ skillTags: { name: In(payload.skills) } }); } - if (payload.startedDate) { - conditions.push({ startedDate: payload.startedDate }); - } - if (payload.finishedDate) { - conditions.push({ finishedDate: payload.finishedDate }); - } + // if (payload.startedDate) { + // conditions.push({ startedDate: payload.startedDate }); + // } + // if (payload.finishedDate) { + // conditions.push({ finishedDate: payload.finishedDate }); + // } if (payload.capacity) { - conditions.push({ capacity: payload.capacity }); + conditions.push({ capacity: payload.capacity }); } - if(payload.finishedDate){ + if (payload.finishedDate) { conditions.push({ finishedDate: payload.finishedDate }); } - if(payload.startedDate){ + if (payload.startedDate) { conditions.push({ startedDate: payload.startedDate }); } const [voluntaryWorks, total] = await VoluntaryWork.findAndCount({ - where: conditions.length > 0 ? conditions : {}, + //where: conditions.length > 0 ? conditions : {}, skip: pageSize * (page - 1), take: pageSize, order: { diff --git a/src/db/entities/OrganizationAdmin.ts b/src/db/entities/OrganizationAdmin.ts index 0258219c..e539f424 100644 --- a/src/db/entities/OrganizationAdmin.ts +++ b/src/db/entities/OrganizationAdmin.ts @@ -23,7 +23,7 @@ export class OrganizationAdmin extends BaseEntity { @Column({ nullable: false }) password: string; - @OneToOne(() => OrganizationProfile, {cascade: true, onDelete:"CASCADE"}) + @OneToOne(() => OrganizationProfile, {cascade: true, onDelete:"SET NULL", onUpdate:"CASCADE"}) @JoinColumn() orgProfile: OrganizationProfile; diff --git a/src/db/entities/OrganizationProfile.ts b/src/db/entities/OrganizationProfile.ts index 5472a892..2b47e217 100644 --- a/src/db/entities/OrganizationProfile.ts +++ b/src/db/entities/OrganizationProfile.ts @@ -6,13 +6,13 @@ export class OrganizationProfile extends BaseEntity { @PrimaryGeneratedColumn('uuid') id: string; - @Column({ length: 255, nullable: false }) + @Column({ length: 255, nullable: false, unique:true }) name: string; @Column({nullable: false}) description: string; - @OneToMany(() => VoluntaryWork, voluntaryWork => voluntaryWork.orgProfiles) + @OneToMany(() => VoluntaryWork, voluntaryWork => voluntaryWork.orgProfiles, {cascade:true, onDelete:"SET NULL", onUpdate:"CASCADE"}) voluntaryWork: VoluntaryWork[]; @CreateDateColumn({ diff --git a/src/db/entities/Role.ts b/src/db/entities/Role.ts index 240eec4a..39945699 100644 --- a/src/db/entities/Role.ts +++ b/src/db/entities/Role.ts @@ -20,7 +20,7 @@ export class Role extends BaseEntity { @JoinTable() volunteers: Volunteer[]; - @ManyToMany(() => Permission) + @ManyToMany(() => Permission, {cascade:true, onUpdate:"CASCADE"}) @JoinTable() permissions: Permission[]; diff --git a/src/db/entities/VoluntaryWork.ts b/src/db/entities/VoluntaryWork.ts index cdb65c9a..7cc92bbc 100644 --- a/src/db/entities/VoluntaryWork.ts +++ b/src/db/entities/VoluntaryWork.ts @@ -2,6 +2,7 @@ import { BaseEntity, Column, CreateDateColumn, Entity, JoinTable, ManyToMany, Ma import { SkillTag } from "./SkillTag.js"; import { VolunteerProfile } from "./VolunteerProfile.js"; import { OrganizationProfile } from "./OrganizationProfile.js"; +import { NSVoluntaryWork } from "../../../types/voluntaryWork.js"; @Entity() export class VoluntaryWork extends BaseEntity { @@ -31,11 +32,11 @@ export class VoluntaryWork extends BaseEntity { @Column({ nullable: false }) location: string; - @Column({nullable: false }) - startedDate: string; + @Column({ nullable: false, type: "timestamp" }) + startedDate: Date; - @Column({nullable: false }) - finishedDate: string; + @Column({ nullable: false, type: "timestamp" }) + finishedDate: Date; @Column({ type: 'enum', @@ -47,10 +48,10 @@ export class VoluntaryWork extends BaseEntity { @Column({ type: 'text', nullable: true, transformer: { to: (value) => JSON.stringify(value), from: (value) => JSON.parse(value) } }) images: string[]; - @Column({nullable:true}) + @Column({ nullable: true }) rating: number; - @Column({nullable:true}) + @Column({ nullable: true }) feedback: string; @Column() diff --git a/src/routes/voluntaryWork.ts b/src/routes/voluntaryWork.ts index 5b21b006..a6d13b5e 100644 --- a/src/routes/voluntaryWork.ts +++ b/src/routes/voluntaryWork.ts @@ -49,8 +49,8 @@ router.get('/', async (req, res, next) => { rating: Number(req.query.rating) || 0, status: req.query.status as NSVoluntaryWork.StatusType, skills: (Array.isArray(req.query.skills) ? req.query.skills : [req.query.skills]).filter(Boolean) as string[], - startedDate: req.query.startedDate?.toString() || "", - finishedDate: req.query.finishedDate ?.toString() ||"", + startedDate: req.query.startedDate?.toString ||"", + finishedDate: req.query.finishedDate?.toString ||"" , capacity: Number(req.query.capacity) || 0, finishedAfter: req.query.finishedDate ?.toString() ||"", finishedBefore:req.query.finishedBefore?.toString() || "", @@ -58,14 +58,14 @@ router.get('/', async (req, res, next) => { startedBefore: req.query.startedBefore?.toString() || "" }; - getVoluntaryWorks(payload) - .then(data => { - res.send(data); - }) - .catch(error => { - console.error(error); - res.status(500).send('Something went wrong'); - }); + // getVoluntaryWorks(payload) + // .then(data => { + // res.send(data); + // }) + // .catch(error => { + // console.error(error); + // res.status(500).send('Something went wrong'); + // }); }); export default router; diff --git a/types/voluntaryWork.ts b/types/voluntaryWork.ts index bc4aed7b..c3ef7b2b 100644 --- a/types/voluntaryWork.ts +++ b/types/voluntaryWork.ts @@ -20,7 +20,7 @@ export namespace NSVoluntaryWork { feedback?: string; status?: StatusType; days?: NSVolunteer.AvailableDays[]; - startedDate?: string; + startedDate?:string; finishedDate?: string; capacity?: number; skillTagIds?: number[]; @@ -28,6 +28,12 @@ export namespace NSVoluntaryWork { } + export interface Date { + year: number; + month: number; + day: number; + }; + export interface Item { id?: number; name: string; @@ -46,4 +52,3 @@ export namespace NSVoluntaryWork { skillTagIds: number[]; } } -//edit From 9902f0bed5f6298e4bdef834aaa329a27e5171eb Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Thu, 5 Oct 2023 12:47:22 +0300 Subject: [PATCH 034/146] Edit the creat v.w and edit v.w functions --- .j.js | 7 +++++-- src/controllers/index.ts | 7 ++++--- src/controllers/voluntaryWork.ts | 34 ++++++++++++++++++++++++++------ src/db/entities/VoluntaryWork.ts | 11 +++++------ src/routes/voluntaryWork.ts | 7 +++---- types/voluntaryWork.ts | 12 +++++------ 6 files changed, 51 insertions(+), 27 deletions(-) diff --git a/.j.js b/.j.js index b5e1de40..53576ae6 100644 --- a/.j.js +++ b/.j.js @@ -1,4 +1,7 @@ -let x = "2023-10-7".split('-').map( (str) =>{return parseInt(str, 10);}); +const year = 2023; // Replace with your desired year +const month = 9; // Replace with your desired month (0 for January, 11 for December) +const day = 5; // Replace with your desired day +const date = new Date(year, month, day, 0,0,0,0); -console.log(x); \ No newline at end of file +console.log(date); \ No newline at end of file diff --git a/src/controllers/index.ts b/src/controllers/index.ts index 978b6953..79d82fee 100644 --- a/src/controllers/index.ts +++ b/src/controllers/index.ts @@ -1,7 +1,6 @@ import express from 'express' import { OrganizationAdmin } from '../db/entities/OrganizationAdmin.js'; import { Volunteer } from '../db/entities/Volunteer.js'; -import { NSVoluntaryWork } from '../../types/voluntaryWork.js'; const getSender =async (res:express.Response)=>{ let sender: OrganizationAdmin | Volunteer = new Volunteer(); @@ -21,9 +20,11 @@ const getSender =async (res:express.Response)=>{ return sender; } -const getDate = (date:string): Date | Date=>{ +const getDate = (date:string): Date =>{ let [year, month, day] =date.split('-').map( (str) =>{return parseInt(str, 10);}); - return new Date(year,month,day,0,0,0,0); + console.log(`y:${year}, m:${month}, d:${day}`); + + return new Date(year,month-1,day,0,0,0,0); } export {getSender, getDate}; \ No newline at end of file diff --git a/src/controllers/voluntaryWork.ts b/src/controllers/voluntaryWork.ts index d8758ec4..a0b89d5f 100644 --- a/src/controllers/voluntaryWork.ts +++ b/src/controllers/voluntaryWork.ts @@ -6,9 +6,9 @@ import { NSVolunteer } from "../../types/volunteer.js"; import { getDate } from "./index.js"; const createVoluntaryWork = async (payload: NSVoluntaryWork.Item) => { - let payload2 = { ...payload, startedDate: getDate(payload.startedDate), finishedDate: getDate(payload.finishedDate) }; + let payloadDate = { ...payload, startedDate: getDate(payload.startedDate), finishedDate: getDate(payload.finishedDate) }; - let newVoluntaryWork = VoluntaryWork.create(payload2 as DeepPartial); + let newVoluntaryWork = VoluntaryWork.create(payloadDate as DeepPartial); const skillTags = await SkillTag.find({ where: { id: In(payload.skillTagIds) }, }); @@ -21,12 +21,34 @@ const deleteVoluntaryWork = async (voluntaryWorkId: number) => { return VoluntaryWork.delete(voluntaryWorkId); } -const editVoluntaryWork = async (payload: NSVoluntaryWork.Edit) => { - let voluntaryWork = await VoluntaryWork.findOne({ where: { id: payload.id } }); +const editVoluntaryWork = async (payload: NSVoluntaryWork.Edit) => { + const id = Number(payload.id) || 0; + let voluntaryWork = await VoluntaryWork.findOne({ where: { id } }); + if (voluntaryWork) { - voluntaryWork = Object.assign(voluntaryWork, payload); - return voluntaryWork?.save(); + voluntaryWork.name = payload.name || voluntaryWork.name; + voluntaryWork.description = payload.description || voluntaryWork.description; + voluntaryWork.location = payload.location || voluntaryWork.location; + voluntaryWork.capacity = payload.capacity || voluntaryWork.capacity; + voluntaryWork.days = payload.days || voluntaryWork.days; + voluntaryWork.images = payload.images || voluntaryWork.images; + voluntaryWork.time = payload.time || voluntaryWork.time; + voluntaryWork.status = payload.status || voluntaryWork.status; + + if (payload.skillTagIds) { + const skillTags = await SkillTag.find({ + where: { id: In(payload.skillTagIds) }, + }); + voluntaryWork.skillTags = skillTags; + } + if (payload.startedDate) { + voluntaryWork.startedDate = getDate(payload.startedDate); + } + if (payload.finishedDate) { + voluntaryWork.finishedDate = getDate(payload.finishedDate); + } + return voluntaryWork.save(); } else { throw "VoluntaryWork not found :("; } diff --git a/src/db/entities/VoluntaryWork.ts b/src/db/entities/VoluntaryWork.ts index 7cc92bbc..22dd0a67 100644 --- a/src/db/entities/VoluntaryWork.ts +++ b/src/db/entities/VoluntaryWork.ts @@ -2,7 +2,6 @@ import { BaseEntity, Column, CreateDateColumn, Entity, JoinTable, ManyToMany, Ma import { SkillTag } from "./SkillTag.js"; import { VolunteerProfile } from "./VolunteerProfile.js"; import { OrganizationProfile } from "./OrganizationProfile.js"; -import { NSVoluntaryWork } from "../../../types/voluntaryWork.js"; @Entity() export class VoluntaryWork extends BaseEntity { @@ -45,14 +44,14 @@ export class VoluntaryWork extends BaseEntity { }) status: 'Pending' | 'In Progress' | 'Finished' | 'Canceled'; - @Column({ type: 'text', nullable: true, transformer: { to: (value) => JSON.stringify(value), from: (value) => JSON.parse(value) } }) + @Column({ type: 'json', nullable: true }) images: string[]; - @Column({ nullable: true }) - rating: number; + @Column({ type: 'json', nullable: true }) + rating: (1|2|3|4|5)[]; - @Column({ nullable: true }) - feedback: string; + @Column({ type: 'json', nullable: true }) + feedback: string[]; @Column() capacity: number; diff --git a/src/routes/voluntaryWork.ts b/src/routes/voluntaryWork.ts index a6d13b5e..67caa1ad 100644 --- a/src/routes/voluntaryWork.ts +++ b/src/routes/voluntaryWork.ts @@ -22,14 +22,13 @@ router.delete('/:id', async (req, res) => { res.send(data); }) .catch(error => { - console.error(error); res.status(500).send('Something went wrong'); }); }) -router.put("/", async (req, res, next) => { - editVoluntaryWork(req.body).then(() => { - res.status(201).send("VoluntaryWork edited successfully!!") +router.put("/", async (req, res, next) => { + editVoluntaryWork({...req.body, id: req.query.id?.toString() }).then(() => { + res.status(201).send("Voluntary Work edited successfully!!") }).catch(err => { console.error(err); res.status(500).send(err); diff --git a/types/voluntaryWork.ts b/types/voluntaryWork.ts index c3ef7b2b..9848662f 100644 --- a/types/voluntaryWork.ts +++ b/types/voluntaryWork.ts @@ -10,14 +10,14 @@ export namespace NSVoluntaryWork { } export interface Edit { - id: number; + id: string; name?: string; description?: string; location?: string; time?: NSVolunteer.AvailableTime[]; images?: string[]; - rating?: number; - feedback?: string; + rating?: number[]; + feedback?: string[]; status?: StatusType; days?: NSVolunteer.AvailableDays[]; startedDate?:string; @@ -35,14 +35,14 @@ export namespace NSVoluntaryWork { }; export interface Item { - id?: number; + id?: string; name: string; description: string; location: string; time: NSVolunteer.AvailableTime[]; images?: string[]; - rating?: number; - feedback?: string; + rating?: number[]; + feedback?: string[]; status: StatusType; createdAt?: Date; days: NSVolunteer.AvailableDays[]; From 66e2c1d32a61fd7550a8f982517c42e1d0f0a022 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Thu, 5 Oct 2023 13:21:34 +0300 Subject: [PATCH 035/146] edit v.w rout and controller --- .j.js | 7 ------- src/controllers/voluntaryWork.ts | 28 +++++++++++--------------- src/db/entities/VoluntaryWork.ts | 4 ++-- src/routes/voluntaryWork.ts | 34 ++++++++++++++++---------------- 4 files changed, 31 insertions(+), 42 deletions(-) delete mode 100644 .j.js diff --git a/.j.js b/.j.js deleted file mode 100644 index 53576ae6..00000000 --- a/.j.js +++ /dev/null @@ -1,7 +0,0 @@ -const year = 2023; // Replace with your desired year -const month = 9; // Replace with your desired month (0 for January, 11 for December) -const day = 5; // Replace with your desired day - -const date = new Date(year, month, day, 0,0,0,0); - -console.log(date); \ No newline at end of file diff --git a/src/controllers/voluntaryWork.ts b/src/controllers/voluntaryWork.ts index a0b89d5f..19142f2d 100644 --- a/src/controllers/voluntaryWork.ts +++ b/src/controllers/voluntaryWork.ts @@ -1,4 +1,4 @@ -import { DeepPartial, FindOperator, In } from "typeorm"; +import { DeepPartial, FindOperator, FindOptionsWhere, In } from "typeorm"; import { NSVoluntaryWork } from "../../types/voluntaryWork.js"; import { SkillTag } from "../db/entities/SkillTag.js"; import { VoluntaryWork } from "../db/entities/VoluntaryWork.js"; @@ -21,7 +21,7 @@ const deleteVoluntaryWork = async (voluntaryWorkId: number) => { return VoluntaryWork.delete(voluntaryWorkId); } -const editVoluntaryWork = async (payload: NSVoluntaryWork.Edit) => { +const editVoluntaryWork = async (payload: NSVoluntaryWork.Edit) => { const id = Number(payload.id) || 0; let voluntaryWork = await VoluntaryWork.findOne({ where: { id } }); @@ -41,7 +41,7 @@ const editVoluntaryWork = async (payload: NSVoluntaryWork.Edit) => { }); voluntaryWork.skillTags = skillTags; } - if (payload.startedDate) { + if (payload.startedDate) { voluntaryWork.startedDate = getDate(payload.startedDate); } if (payload.finishedDate) { @@ -105,30 +105,26 @@ const getVoluntaryWorks = async (payload: { if (payload.skills.length > 0) { conditions.push({ skillTags: { name: In(payload.skills) } }); } - // if (payload.startedDate) { - // conditions.push({ startedDate: payload.startedDate }); - // } - // if (payload.finishedDate) { - // conditions.push({ finishedDate: payload.finishedDate }); - // } - if (payload.capacity) { - conditions.push({ capacity: payload.capacity }); + if (payload.startedDate) { + let startedDate = getDate(payload.startedDate); + conditions.push({ startedDate: startedDate }); } if (payload.finishedDate) { - conditions.push({ finishedDate: payload.finishedDate }); + let finishedDate = getDate(payload.finishedDate); + conditions.push({ finishedDate: finishedDate }); } - if (payload.startedDate) { - conditions.push({ startedDate: payload.startedDate }); + if (payload.capacity) { + conditions.push({ capacity: payload.capacity }); } const [voluntaryWorks, total] = await VoluntaryWork.findAndCount({ - //where: conditions.length > 0 ? conditions : {}, + where: conditions.length > 0 ? conditions : {}, skip: pageSize * (page - 1), take: pageSize, order: { createdAt: 'ASC' }, - relations: ['skillTags'] // Include the skillTags relationship + relations: ['skillTags'] }); return { diff --git a/src/db/entities/VoluntaryWork.ts b/src/db/entities/VoluntaryWork.ts index 22dd0a67..4c52a28b 100644 --- a/src/db/entities/VoluntaryWork.ts +++ b/src/db/entities/VoluntaryWork.ts @@ -47,8 +47,8 @@ export class VoluntaryWork extends BaseEntity { @Column({ type: 'json', nullable: true }) images: string[]; - @Column({ type: 'json', nullable: true }) - rating: (1|2|3|4|5)[]; + @Column({ nullable: true }) + rating: number; @Column({ type: 'json', nullable: true }) feedback: string[]; diff --git a/src/routes/voluntaryWork.ts b/src/routes/voluntaryWork.ts index 67caa1ad..2d316bea 100644 --- a/src/routes/voluntaryWork.ts +++ b/src/routes/voluntaryWork.ts @@ -26,8 +26,8 @@ router.delete('/:id', async (req, res) => { }); }) -router.put("/", async (req, res, next) => { - editVoluntaryWork({...req.body, id: req.query.id?.toString() }).then(() => { +router.put("/", async (req, res, next) => { + editVoluntaryWork({ ...req.body, id: req.query.id?.toString() }).then(() => { res.status(201).send("Voluntary Work edited successfully!!") }).catch(err => { console.error(err); @@ -43,28 +43,28 @@ router.get('/', async (req, res, next) => { id: Number(req.query.id) || 0, name: req.query.name?.toString() || '', time: ((Array.isArray(req.query.time) ? req.query.time : [req.query.time]).filter(Boolean)) as NSVolunteer.AvailableTime[], - location: (typeof req.query.location === 'string' ? req.query.location : ''), + location: (typeof req.query.location === 'string' ? req.query.location : ''), days: (Array.isArray(req.query.days) ? req.query.days : [req.query.days]).filter(Boolean) as NSVolunteer.AvailableDays[], rating: Number(req.query.rating) || 0, status: req.query.status as NSVoluntaryWork.StatusType, skills: (Array.isArray(req.query.skills) ? req.query.skills : [req.query.skills]).filter(Boolean) as string[], - startedDate: req.query.startedDate?.toString ||"", - finishedDate: req.query.finishedDate?.toString ||"" , + startedDate: req.query.startedDate?.toString() || "", + finishedDate: req.query.finishedDate?.toString() || "", capacity: Number(req.query.capacity) || 0, - finishedAfter: req.query.finishedDate ?.toString() ||"", - finishedBefore:req.query.finishedBefore?.toString() || "", - startedAfter:req.query.startedAfter?.toString() || "", + finishedAfter: req.query.finishedDate?.toString() || "", + finishedBefore: req.query.finishedBefore?.toString() || "", + startedAfter: req.query.startedAfter?.toString() || "", startedBefore: req.query.startedBefore?.toString() || "" }; - - // getVoluntaryWorks(payload) - // .then(data => { - // res.send(data); - // }) - // .catch(error => { - // console.error(error); - // res.status(500).send('Something went wrong'); - // }); + + getVoluntaryWorks(payload) + .then(data => { + res.send(data); + }) + .catch(error => { + console.error(error); + res.status(500).send('Something went wrong'); + }); }); export default router; From b5de950b34cca2c8443a170c8481870591b442bf Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Thu, 5 Oct 2023 13:31:39 +0300 Subject: [PATCH 036/146] add started and finished before and after date to advanced search --- src/controllers/voluntaryWork.ts | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/controllers/voluntaryWork.ts b/src/controllers/voluntaryWork.ts index 19142f2d..a9c282b9 100644 --- a/src/controllers/voluntaryWork.ts +++ b/src/controllers/voluntaryWork.ts @@ -1,4 +1,4 @@ -import { DeepPartial, FindOperator, FindOptionsWhere, In } from "typeorm"; +import { DeepPartial, FindOperator, FindOptionsWhere, In, LessThan, MoreThan } from "typeorm"; import { NSVoluntaryWork } from "../../types/voluntaryWork.js"; import { SkillTag } from "../db/entities/SkillTag.js"; import { VoluntaryWork } from "../db/entities/VoluntaryWork.js"; @@ -117,6 +117,26 @@ const getVoluntaryWorks = async (payload: { conditions.push({ capacity: payload.capacity }); } + if (payload.startedAfter) { + const startedAfterDate = getDate(payload.startedAfter); + conditions.push({ startedDate: MoreThan(startedAfterDate) }); + } + + if (payload.startedBefore) { + const startedBeforeDate = getDate(payload.startedBefore); + conditions.push({ startedDate: LessThan(startedBeforeDate) }); + } + + if (payload.finishedAfter) { + const finishedAfterDate = getDate(payload.finishedAfter); + conditions.push({ finishedDate: MoreThan(finishedAfterDate) }); + } + + if (payload.finishedBefore) { + const finishedBeforeDate = getDate(payload.finishedBefore); + conditions.push({ finishedDate: LessThan(finishedBeforeDate) }); + } + const [voluntaryWorks, total] = await VoluntaryWork.findAndCount({ where: conditions.length > 0 ? conditions : {}, skip: pageSize * (page - 1), From 2acd7d9e947aeecca287c2d439d87a4a069775ba Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Thu, 5 Oct 2023 13:41:36 +0300 Subject: [PATCH 037/146] creat rating more or less to advanced search --- src/controllers/voluntaryWork.ts | 30 ++++++++++-------------------- src/routes/voluntaryWork.ts | 7 +++++-- types/voluntaryWork.ts | 22 ++++++++++++++++++++++ 3 files changed, 37 insertions(+), 22 deletions(-) diff --git a/src/controllers/voluntaryWork.ts b/src/controllers/voluntaryWork.ts index a9c282b9..682bc65e 100644 --- a/src/controllers/voluntaryWork.ts +++ b/src/controllers/voluntaryWork.ts @@ -1,4 +1,4 @@ -import { DeepPartial, FindOperator, FindOptionsWhere, In, LessThan, MoreThan } from "typeorm"; +import { DeepPartial, FindOperator, FindOptionsWhere, In, LessThan, LessThanOrEqual, MoreThan, MoreThanOrEqual } from "typeorm"; import { NSVoluntaryWork } from "../../types/voluntaryWork.js"; import { SkillTag } from "../db/entities/SkillTag.js"; import { VoluntaryWork } from "../db/entities/VoluntaryWork.js"; @@ -58,25 +58,7 @@ const getVoluntaryWork = (payload: { id: number }) => { return VoluntaryWork.findOne({ where: { id: payload.id } }) } -const getVoluntaryWorks = async (payload: { - page: string, - pageSize: string, - id: number, - name: string, - time: NSVolunteer.AvailableTime[], - location: string, - days: NSVolunteer.AvailableDays[], - rating: number, - status: NSVoluntaryWork.StatusType, - skills: string[], - startedDate: string; - finishedDate: string; - capacity: number; - finishedAfter: string; - finishedBefore: string; - startedAfter: string; - startedBefore: string; -}) => { +const getVoluntaryWorks = async (payload:NSVoluntaryWork.GetVoluntaryWorks ) => { const page = parseInt(payload.page); const pageSize = parseInt(payload.pageSize); const conditions = []; @@ -137,6 +119,14 @@ const getVoluntaryWorks = async (payload: { conditions.push({ finishedDate: LessThan(finishedBeforeDate) }); } + if (payload.ratingMore) { + conditions.push({ rating: MoreThanOrEqual(payload.ratingMore) }); + } + + if (payload.ratingLess ) { + conditions.push({ rating: LessThanOrEqual(payload.ratingLess) }); + } + const [voluntaryWorks, total] = await VoluntaryWork.findAndCount({ where: conditions.length > 0 ? conditions : {}, skip: pageSize * (page - 1), diff --git a/src/routes/voluntaryWork.ts b/src/routes/voluntaryWork.ts index 2d316bea..d29ced8c 100644 --- a/src/routes/voluntaryWork.ts +++ b/src/routes/voluntaryWork.ts @@ -54,9 +54,12 @@ router.get('/', async (req, res, next) => { finishedAfter: req.query.finishedDate?.toString() || "", finishedBefore: req.query.finishedBefore?.toString() || "", startedAfter: req.query.startedAfter?.toString() || "", - startedBefore: req.query.startedBefore?.toString() || "" + startedBefore: req.query.startedBefore?.toString() || "", + ratingMore:Number(req.query.ratingMore) || 0, + ratingLess:Number(req.query.ratingLess) || 0, + }; - + getVoluntaryWorks(payload) .then(data => { res.send(data); diff --git a/types/voluntaryWork.ts b/types/voluntaryWork.ts index 9848662f..909626e8 100644 --- a/types/voluntaryWork.ts +++ b/types/voluntaryWork.ts @@ -28,6 +28,28 @@ export namespace NSVoluntaryWork { } + export interface GetVoluntaryWorks { + page: string, + pageSize: string, + id: number, + name: string, + time: NSVolunteer.AvailableTime[], + location: string, + days: NSVolunteer.AvailableDays[], + rating: number, + status: NSVoluntaryWork.StatusType, + skills: string[], + startedDate: string; + finishedDate: string; + capacity: number; + finishedAfter: string; + finishedBefore: string; + startedAfter: string; + startedBefore: string; + ratingMore:number; + ratingLess:number; + } + export interface Date { year: number; month: number; From 44a10c6801cbd25d4dc78e7b8cbc294f777ba855 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Thu, 5 Oct 2023 14:01:11 +0300 Subject: [PATCH 038/146] edit the put end points to send the id in the params --- src/controllers/voluntaryWork.ts | 18 ++++++++++++++---- src/routes/permission.ts | 4 ++-- src/routes/role.ts | 4 ++-- src/routes/voluntaryWork.ts | 15 ++++++++++++--- 4 files changed, 30 insertions(+), 11 deletions(-) diff --git a/src/controllers/voluntaryWork.ts b/src/controllers/voluntaryWork.ts index 682bc65e..f20ecde8 100644 --- a/src/controllers/voluntaryWork.ts +++ b/src/controllers/voluntaryWork.ts @@ -58,7 +58,7 @@ const getVoluntaryWork = (payload: { id: number }) => { return VoluntaryWork.findOne({ where: { id: payload.id } }) } -const getVoluntaryWorks = async (payload:NSVoluntaryWork.GetVoluntaryWorks ) => { +const getVoluntaryWorks = async (payload: NSVoluntaryWork.GetVoluntaryWorks) => { const page = parseInt(payload.page); const pageSize = parseInt(payload.pageSize); const conditions = []; @@ -123,7 +123,7 @@ const getVoluntaryWorks = async (payload:NSVoluntaryWork.GetVoluntaryWorks ) => conditions.push({ rating: MoreThanOrEqual(payload.ratingMore) }); } - if (payload.ratingLess ) { + if (payload.ratingLess) { conditions.push({ rating: LessThanOrEqual(payload.ratingLess) }); } @@ -134,7 +134,7 @@ const getVoluntaryWorks = async (payload:NSVoluntaryWork.GetVoluntaryWorks ) => order: { createdAt: 'ASC' }, - relations: ['skillTags'] + relations: ['skillTags'] }); return { @@ -145,5 +145,15 @@ const getVoluntaryWorks = async (payload:NSVoluntaryWork.GetVoluntaryWorks ) => }; } +const putRating = async(id: number, rating:number) => { + let voluntaryWork = await VoluntaryWork.findOne({ where: { id } }); + if(voluntaryWork){ + voluntaryWork.rating+=rating; + voluntaryWork.rating/=2; + return voluntaryWork.save(); + }else{ + throw "VoluntaryWork not found :("; + } +} -export { createVoluntaryWork, editVoluntaryWork, getVoluntaryWork, getVoluntaryWorks, deleteVoluntaryWork } \ No newline at end of file +export { createVoluntaryWork, editVoluntaryWork, putRating,getVoluntaryWork, getVoluntaryWorks, deleteVoluntaryWork } \ No newline at end of file diff --git a/src/routes/permission.ts b/src/routes/permission.ts index cff1f18f..130406d2 100644 --- a/src/routes/permission.ts +++ b/src/routes/permission.ts @@ -25,8 +25,8 @@ router.delete('/:id', async (req, res) => { }); }) -router.put("/", async (req, res, next) => { - editPermission(req.body).then(() => { +router.put("/:id", async (req, res, next) => { + editPermission({...req.body, id: req.params.id?.toString()}).then(() => { res.status(201).send("Permission edited successfully!!") }).catch(err => { console.error(err); diff --git a/src/routes/role.ts b/src/routes/role.ts index 5606823f..ddb05bdc 100644 --- a/src/routes/role.ts +++ b/src/routes/role.ts @@ -26,8 +26,8 @@ router.delete('/:id', async (req, res) => { }); }) -router.put("/", async (req, res, next) => { - editRole(req.body).then(() => { +router.put("/:id", async (req, res, next) => { + editRole({...req.body,id: req.params.id?.toString()}).then(() => { res.status(201).send("Role edited successfully!!") }).catch(err => { console.error(err); diff --git a/src/routes/voluntaryWork.ts b/src/routes/voluntaryWork.ts index d29ced8c..ec2cd947 100644 --- a/src/routes/voluntaryWork.ts +++ b/src/routes/voluntaryWork.ts @@ -1,5 +1,5 @@ import express from 'express'; -import { createVoluntaryWork, deleteVoluntaryWork, editVoluntaryWork, getVoluntaryWork, getVoluntaryWorks } from '../controllers/voluntaryWork.js'; +import { createVoluntaryWork, deleteVoluntaryWork, editVoluntaryWork, getVoluntaryWork, getVoluntaryWorks, putRating } from '../controllers/voluntaryWork.js'; import { NSVolunteer } from '../../types/volunteer.js'; import { NSVoluntaryWork } from '../../types/voluntaryWork.js'; @@ -26,8 +26,8 @@ router.delete('/:id', async (req, res) => { }); }) -router.put("/", async (req, res, next) => { - editVoluntaryWork({ ...req.body, id: req.query.id?.toString() }).then(() => { +router.put("/:id", async (req, res, next) => { + editVoluntaryWork({ ...req.body, id: req.params.id?.toString() }).then(() => { res.status(201).send("Voluntary Work edited successfully!!") }).catch(err => { console.error(err); @@ -70,5 +70,14 @@ router.get('/', async (req, res, next) => { }); }); +router.put("/rating/:id", async (req, res, next) => { + putRating( Number(req.params.id?.toString()),Number(req.body.rating?.tostring()) ).then(() => { + res.status(201).send("Voluntary Work edited successfully!!") + }).catch(err => { + console.error(err); + res.status(500).send(err); + }); +}); + export default router; From e7089a88d0dca9520d6b5e40fbfcc37c7f83e80e Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Thu, 5 Oct 2023 14:07:55 +0300 Subject: [PATCH 039/146] creat put rating function --- src/controllers/voluntaryWork.ts | 2 ++ src/routes/voluntaryWork.ts | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/controllers/voluntaryWork.ts b/src/controllers/voluntaryWork.ts index f20ecde8..d79bdeaa 100644 --- a/src/controllers/voluntaryWork.ts +++ b/src/controllers/voluntaryWork.ts @@ -147,6 +147,8 @@ const getVoluntaryWorks = async (payload: NSVoluntaryWork.GetVoluntaryWorks) => const putRating = async(id: number, rating:number) => { let voluntaryWork = await VoluntaryWork.findOne({ where: { id } }); + console.log("!!!!!!!!!!!11"); + if(voluntaryWork){ voluntaryWork.rating+=rating; voluntaryWork.rating/=2; diff --git a/src/routes/voluntaryWork.ts b/src/routes/voluntaryWork.ts index ec2cd947..178b623e 100644 --- a/src/routes/voluntaryWork.ts +++ b/src/routes/voluntaryWork.ts @@ -71,8 +71,8 @@ router.get('/', async (req, res, next) => { }); router.put("/rating/:id", async (req, res, next) => { - putRating( Number(req.params.id?.toString()),Number(req.body.rating?.tostring()) ).then(() => { - res.status(201).send("Voluntary Work edited successfully!!") + putRating( Number(req.params.id),Number(req.body.rating) ).then(() => { + res.status(201).send("Rating added successfully!!") }).catch(err => { console.error(err); res.status(500).send(err); From 1691665067d53dbc144d81e5bcadd87c4180b0bf Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Thu, 5 Oct 2023 14:58:57 +0300 Subject: [PATCH 040/146] creat add feedback function --- src/controllers/index.ts | 4 +--- src/controllers/voluntaryWork.ts | 24 +++++++++++++++++------- src/db/entities/VolunteerProfile.ts | 8 ++++---- src/routes/voluntaryWork.ts | 11 ++++++++++- 4 files changed, 32 insertions(+), 15 deletions(-) diff --git a/src/controllers/index.ts b/src/controllers/index.ts index 79d82fee..1214fd3c 100644 --- a/src/controllers/index.ts +++ b/src/controllers/index.ts @@ -22,9 +22,7 @@ const getSender =async (res:express.Response)=>{ const getDate = (date:string): Date =>{ let [year, month, day] =date.split('-').map( (str) =>{return parseInt(str, 10);}); - console.log(`y:${year}, m:${month}, d:${day}`); - - return new Date(year,month-1,day,0,0,0,0); + return new Date(year,month-1,day,0,0,0,0); } export {getSender, getDate}; \ No newline at end of file diff --git a/src/controllers/voluntaryWork.ts b/src/controllers/voluntaryWork.ts index d79bdeaa..8cdb821e 100644 --- a/src/controllers/voluntaryWork.ts +++ b/src/controllers/voluntaryWork.ts @@ -13,6 +13,8 @@ const createVoluntaryWork = async (payload: NSVoluntaryWork.Item) => { where: { id: In(payload.skillTagIds) }, }); newVoluntaryWork.skillTags = skillTags; + newVoluntaryWork.feedback=[]; + newVoluntaryWork.images=[]; return newVoluntaryWork.save(); } @@ -145,17 +147,25 @@ const getVoluntaryWorks = async (payload: NSVoluntaryWork.GetVoluntaryWorks) => }; } -const putRating = async(id: number, rating:number) => { +const putRating = async (id: number, rating: number) => { let voluntaryWork = await VoluntaryWork.findOne({ where: { id } }); - console.log("!!!!!!!!!!!11"); - - if(voluntaryWork){ - voluntaryWork.rating+=rating; - voluntaryWork.rating/=2; + if (voluntaryWork) { + voluntaryWork.rating += rating; + voluntaryWork.rating /= 2; return voluntaryWork.save(); + } else { + throw "VoluntaryWork not found :("; + } +} + +const putFeedback = async (id: number, feedback: string) => { + let voluntaryWork = await VoluntaryWork.findOne({ where: { id } }); + if (voluntaryWork){ + voluntaryWork.feedback.push(feedback); + await voluntaryWork.save(); }else{ throw "VoluntaryWork not found :("; } } -export { createVoluntaryWork, editVoluntaryWork, putRating,getVoluntaryWork, getVoluntaryWorks, deleteVoluntaryWork } \ No newline at end of file +export { createVoluntaryWork, putFeedback,editVoluntaryWork, putRating, getVoluntaryWork, getVoluntaryWorks, deleteVoluntaryWork } \ No newline at end of file diff --git a/src/db/entities/VolunteerProfile.ts b/src/db/entities/VolunteerProfile.ts index 08b1a7d9..e162027d 100644 --- a/src/db/entities/VolunteerProfile.ts +++ b/src/db/entities/VolunteerProfile.ts @@ -12,20 +12,20 @@ export class VolunteerProfile extends BaseEntity { enum: ['Morning', 'Afternoon'], nullable: false }) - availableTime: 'Morning' | 'Afternoon'; + availableTime: ('Morning' | 'Afternoon')[]; @Column({ type: 'enum', enum: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], nullable: false }) - availableDays: 'Sunday' | 'Monday' | 'Tuesday' | 'Wednesday' | 'Thursday' | 'Friday' | 'Saturday'; + availableDays: ('Sunday' | 'Monday' | 'Tuesday' | 'Wednesday' | 'Thursday' | 'Friday' | 'Saturday')[]; @Column({ nullable: false }) availableLocation: string; - @Column({ nullable: false }) - preferredActivities: string; + @Column({ nullable: false, type:"json" }) + preferredActivities: string[]; @ManyToMany(() => SkillTag) @JoinTable() diff --git a/src/routes/voluntaryWork.ts b/src/routes/voluntaryWork.ts index 178b623e..67ad05b1 100644 --- a/src/routes/voluntaryWork.ts +++ b/src/routes/voluntaryWork.ts @@ -1,5 +1,5 @@ import express from 'express'; -import { createVoluntaryWork, deleteVoluntaryWork, editVoluntaryWork, getVoluntaryWork, getVoluntaryWorks, putRating } from '../controllers/voluntaryWork.js'; +import { createVoluntaryWork, deleteVoluntaryWork, editVoluntaryWork, getVoluntaryWork, getVoluntaryWorks, putFeedback, putRating } from '../controllers/voluntaryWork.js'; import { NSVolunteer } from '../../types/volunteer.js'; import { NSVoluntaryWork } from '../../types/voluntaryWork.js'; @@ -79,5 +79,14 @@ router.put("/rating/:id", async (req, res, next) => { }); }); +router.put("/feedback/:id", async (req, res, next) => { + putFeedback( Number(req.params.id),req.body.feedback).then(() => { + res.status(201).send("Feedback added successfully!!") + }).catch(err => { + console.error(err); + res.status(500).send(err); + }); +}); + export default router; From dcf6a5ba5bb559b7c641b86e11d8c46077b2054f Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Thu, 5 Oct 2023 15:05:28 +0300 Subject: [PATCH 041/146] creat a function to add images to data base by url --- src/controllers/voluntaryWork.ts | 12 +++++++++++- src/routes/voluntaryWork.ts | 11 ++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/controllers/voluntaryWork.ts b/src/controllers/voluntaryWork.ts index 8cdb821e..b5966402 100644 --- a/src/controllers/voluntaryWork.ts +++ b/src/controllers/voluntaryWork.ts @@ -168,4 +168,14 @@ const putFeedback = async (id: number, feedback: string) => { } } -export { createVoluntaryWork, putFeedback,editVoluntaryWork, putRating, getVoluntaryWork, getVoluntaryWorks, deleteVoluntaryWork } \ No newline at end of file +const putImages = async (id: number, images: string[]) => { + let voluntaryWork = await VoluntaryWork.findOne({ where: { id } }); + if (voluntaryWork){ + voluntaryWork.images.push(...images); + await voluntaryWork.save(); + }else{ + throw "VoluntaryWork not found :("; + } +} + +export { putImages,createVoluntaryWork, putFeedback,editVoluntaryWork, putRating, getVoluntaryWork, getVoluntaryWorks, deleteVoluntaryWork } \ No newline at end of file diff --git a/src/routes/voluntaryWork.ts b/src/routes/voluntaryWork.ts index 67ad05b1..d347c51a 100644 --- a/src/routes/voluntaryWork.ts +++ b/src/routes/voluntaryWork.ts @@ -1,5 +1,5 @@ import express from 'express'; -import { createVoluntaryWork, deleteVoluntaryWork, editVoluntaryWork, getVoluntaryWork, getVoluntaryWorks, putFeedback, putRating } from '../controllers/voluntaryWork.js'; +import { createVoluntaryWork, deleteVoluntaryWork, editVoluntaryWork, getVoluntaryWork, getVoluntaryWorks, putFeedback, putImages, putRating } from '../controllers/voluntaryWork.js'; import { NSVolunteer } from '../../types/volunteer.js'; import { NSVoluntaryWork } from '../../types/voluntaryWork.js'; @@ -88,5 +88,14 @@ router.put("/feedback/:id", async (req, res, next) => { }); }); +router.put("/images/:id", async (req, res, next) => { + putImages( Number(req.params.id),req.body.images).then(() => { + res.status(201).send("Images added successfully!!") + }).catch(err => { + console.error(err); + res.status(500).send(err); + }); +}); + export default router; From 959d06631f1ed27dfbe21ee13c04e1a1a0f8b782 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Thu, 5 Oct 2023 18:47:21 +0300 Subject: [PATCH 042/146] creat valodator for role and permission --- src/middleware/validation/permission.ts | 20 ++++++++++++++++++++ src/middleware/validation/role.ts | 24 ++++++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 src/middleware/validation/permission.ts create mode 100644 src/middleware/validation/role.ts diff --git a/src/middleware/validation/permission.ts b/src/middleware/validation/permission.ts new file mode 100644 index 00000000..7f0ab3cc --- /dev/null +++ b/src/middleware/validation/permission.ts @@ -0,0 +1,20 @@ +import express from 'express'; + +const validatePermission = (req: express.Request, + res: express.Response, + next: express.NextFunction +) => { + const values = ["name"]; + const user = req.body; + const errorList = values.map(key => !user[key] && `${key} is Required!`).filter(Boolean); + + if (errorList.length) { + res.status(400).send(errorList); + } else { + next(); + } +} + +export { + validatePermission +} \ No newline at end of file diff --git a/src/middleware/validation/role.ts b/src/middleware/validation/role.ts new file mode 100644 index 00000000..8bdfd823 --- /dev/null +++ b/src/middleware/validation/role.ts @@ -0,0 +1,24 @@ +import express from 'express'; + +const validateRole = (req: express.Request, + res: express.Response, + next: express.NextFunction +) => { + const values = ['name', "permissionsId"]; + const role = req.body; + const errorList = values.map(key => !role[key] && `${key} is Required!`).filter(Boolean); + + if (!['root', 'admin', 'volunteer', 'premium'].includes(role.name)) { + errorList.push('role name unknown!'); + } + + if (errorList.length) { + res.status(400).send(errorList); + } else { + next(); + } +} + +export { + validateRole +} \ No newline at end of file From 02b8ac48faa0af11c420a8857c8883b738c9ae86 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Thu, 5 Oct 2023 19:34:48 +0300 Subject: [PATCH 043/146] Creat validation for organizationAdmin --- package-lock.json | 9 +++++ package.json | 1 + src/controllers/index.ts | 35 +++++++++++++++---- src/db/entities/OrganizationAdmin.ts | 2 +- .../validation/organizationAdmin.ts | 33 +++++++++++++++++ src/middleware/validation/permission.ts | 4 +-- 6 files changed, 75 insertions(+), 9 deletions(-) create mode 100644 src/middleware/validation/organizationAdmin.ts diff --git a/package-lock.json b/package-lock.json index a1c675a8..7bcc2cf3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "bcrypt": "^5.1.1", "debug": "~2.6.9", "dotenv": "^16.3.1", + "email-validator": "^2.0.4", "express": "^4.18.2", "http-errors": "~1.6.3", "jade": "~1.11.0", @@ -936,6 +937,14 @@ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, + "node_modules/email-validator": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/email-validator/-/email-validator-2.0.4.tgz", + "integrity": "sha512-gYCwo7kh5S3IDyZPLZf6hSS0MnZT8QmJFqYvbqlDZSbwdZlY6QZWxJ4i/6UhITOJ4XzyI647Bm2MXKCLqnJ4nQ==", + "engines": { + "node": ">4.0" + } + }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", diff --git a/package.json b/package.json index 499a763e..2a1a63c1 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "bcrypt": "^5.1.1", "debug": "~2.6.9", "dotenv": "^16.3.1", + "email-validator": "^2.0.4", "express": "^4.18.2", "http-errors": "~1.6.3", "jade": "~1.11.0", diff --git a/src/controllers/index.ts b/src/controllers/index.ts index 1214fd3c..1b12c5d1 100644 --- a/src/controllers/index.ts +++ b/src/controllers/index.ts @@ -2,7 +2,7 @@ import express from 'express' import { OrganizationAdmin } from '../db/entities/OrganizationAdmin.js'; import { Volunteer } from '../db/entities/Volunteer.js'; -const getSender =async (res:express.Response)=>{ +const getSender = async (res: express.Response) => { let sender: OrganizationAdmin | Volunteer = new Volunteer(); if (res.locals.organizationAdmin) { sender = await OrganizationAdmin.findOne({ @@ -10,7 +10,7 @@ const getSender =async (res:express.Response)=>{ name: res.locals.organizationAdmin.name, email: res.locals?.organizationAdmin.email }, relations: ["roles", "roles.permissions"] }) || new OrganizationAdmin(); - }else if(res.locals.volunteer){ + } else if (res.locals.volunteer) { sender = await Volunteer.findOne({ where: { name: res.locals.volunteer.name, email: res.locals?.volunteer.email @@ -20,9 +20,32 @@ const getSender =async (res:express.Response)=>{ return sender; } -const getDate = (date:string): Date =>{ - let [year, month, day] =date.split('-').map( (str) =>{return parseInt(str, 10);}); - return new Date(year,month-1,day,0,0,0,0); +const getDate = (date: string): Date => { + let [year, month, day] = date.split('-').map((str) => { return parseInt(str, 10); }); + return new Date(year, month - 1, day, 0, 0, 0, 0); } -export {getSender, getDate}; \ No newline at end of file +const isValidPassword = (password: string) => { + const validation = []; + if (password.length < 10) { + validation.push("The password should be at least 10 characters"); + } + + if (!/[A-Z]/.test(password)) { + validation.push("The password should contains at least one uppercase letter"); + } + + if (!/[a-z]/.test(password)) { + validation.push("The password should contains at least one lowercase letter"); + } + + if (!/[0-9]/.test(password)) { + validation.push("The password should contains at least one digit (number)"); + } + + if (!/[!@#$%^&*()_+{}\[\]:;<>,.?~\\-]/.test(password)) { + validation.push("The password should contains at least one special character"); + } + return validation; +}; +export { getSender, getDate, isValidPassword }; \ No newline at end of file diff --git a/src/db/entities/OrganizationAdmin.ts b/src/db/entities/OrganizationAdmin.ts index e539f424..12cf5c63 100644 --- a/src/db/entities/OrganizationAdmin.ts +++ b/src/db/entities/OrganizationAdmin.ts @@ -11,7 +11,7 @@ export class OrganizationAdmin extends BaseEntity { @Column({ length: 255, nullable: false }) name: string; - @Column({ nullable: false }) + @Column({ nullable: false, unique:true }) email: string; @BeforeInsert() diff --git a/src/middleware/validation/organizationAdmin.ts b/src/middleware/validation/organizationAdmin.ts new file mode 100644 index 00000000..65e1532c --- /dev/null +++ b/src/middleware/validation/organizationAdmin.ts @@ -0,0 +1,33 @@ +import express from 'express'; +import * as EmailValidator from 'email-validator'; +import { isValidPassword } from '../../controllers/index.js'; + + +const validateOrganizationAdmin = (req: express.Request, + res: express.Response, + next: express.NextFunction +) => { + const values = ["name", "email", "password", "organizationId"]; + const organizationAdmin = req.body; + const errorList = values.map(key => !organizationAdmin[key] && `${key} is Required!`).filter(Boolean); + + if (!['root', 'admin', 'volunteer', 'premium'].includes(organizationAdmin.name)) { + errorList.push('role name unknown!'); + } + + if (!EmailValidator.validate(organizationAdmin.email)) { + errorList.push('Email is not Valid'); + } + + errorList.push(...isValidPassword(organizationAdmin.password )); + + if (errorList.length) { + res.status(400).send(errorList); + } else { + next(); + } +} + +export { + validateOrganizationAdmin +} \ No newline at end of file diff --git a/src/middleware/validation/permission.ts b/src/middleware/validation/permission.ts index 7f0ab3cc..dec76b5f 100644 --- a/src/middleware/validation/permission.ts +++ b/src/middleware/validation/permission.ts @@ -5,8 +5,8 @@ const validatePermission = (req: express.Request, next: express.NextFunction ) => { const values = ["name"]; - const user = req.body; - const errorList = values.map(key => !user[key] && `${key} is Required!`).filter(Boolean); + const permission = req.body; + const errorList = values.map(key => !permission[key] && `${key} is Required!`).filter(Boolean); if (errorList.length) { res.status(400).send(errorList); From ae01d88e9fe2d1d2dd7b767fdcf27c5cb32dee51 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Thu, 5 Oct 2023 19:49:40 +0300 Subject: [PATCH 044/146] Creat organization Profile validation --- .../validation/organizationAdmin.ts | 4 ---- .../validation/organizationProfile.ts | 23 +++++++++++++++++++ 2 files changed, 23 insertions(+), 4 deletions(-) create mode 100644 src/middleware/validation/organizationProfile.ts diff --git a/src/middleware/validation/organizationAdmin.ts b/src/middleware/validation/organizationAdmin.ts index 65e1532c..d94a2b53 100644 --- a/src/middleware/validation/organizationAdmin.ts +++ b/src/middleware/validation/organizationAdmin.ts @@ -11,10 +11,6 @@ const validateOrganizationAdmin = (req: express.Request, const organizationAdmin = req.body; const errorList = values.map(key => !organizationAdmin[key] && `${key} is Required!`).filter(Boolean); - if (!['root', 'admin', 'volunteer', 'premium'].includes(organizationAdmin.name)) { - errorList.push('role name unknown!'); - } - if (!EmailValidator.validate(organizationAdmin.email)) { errorList.push('Email is not Valid'); } diff --git a/src/middleware/validation/organizationProfile.ts b/src/middleware/validation/organizationProfile.ts new file mode 100644 index 00000000..21d3d352 --- /dev/null +++ b/src/middleware/validation/organizationProfile.ts @@ -0,0 +1,23 @@ +import express from 'express'; +import * as EmailValidator from 'email-validator'; +import { isValidPassword } from '../../controllers/index.js'; + + +const validateOrganizationAdmin = (req: express.Request, + res: express.Response, + next: express.NextFunction +) => { + const values = ["name", "description"]; + const organizationProfile = req.body; + const errorList = values.map(key => !organizationProfile[key] && `${key} is Required!`).filter(Boolean); + + if (errorList.length) { + res.status(400).send(errorList); + } else { + next(); + } +} + +export { + validateOrganizationAdmin +} \ No newline at end of file From 0ea10874c2a0fe80b5dbd0600ff0e9b00ab487bc Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Thu, 5 Oct 2023 19:52:57 +0300 Subject: [PATCH 045/146] Creat skill tag validation --- .../validation/organizationProfile.ts | 3 --- src/middleware/validation/skillTag.ts | 20 +++++++++++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) create mode 100644 src/middleware/validation/skillTag.ts diff --git a/src/middleware/validation/organizationProfile.ts b/src/middleware/validation/organizationProfile.ts index 21d3d352..13d5797d 100644 --- a/src/middleware/validation/organizationProfile.ts +++ b/src/middleware/validation/organizationProfile.ts @@ -1,7 +1,4 @@ import express from 'express'; -import * as EmailValidator from 'email-validator'; -import { isValidPassword } from '../../controllers/index.js'; - const validateOrganizationAdmin = (req: express.Request, res: express.Response, diff --git a/src/middleware/validation/skillTag.ts b/src/middleware/validation/skillTag.ts new file mode 100644 index 00000000..63766db7 --- /dev/null +++ b/src/middleware/validation/skillTag.ts @@ -0,0 +1,20 @@ +import express from 'express'; + +const validatePermission = (req: express.Request, + res: express.Response, + next: express.NextFunction +) => { + const values = ["name"]; + const skillTag = req.body; + const errorList = values.map(key => !skillTag[key] && `${key} is Required!`).filter(Boolean); + + if (errorList.length) { + res.status(400).send(errorList); + } else { + next(); + } +} + +export { + validatePermission +} \ No newline at end of file From bf9f1ef5e376af6a6a5a906df57d8f44292356bd Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Thu, 5 Oct 2023 20:54:47 +0300 Subject: [PATCH 046/146] Creat validation for vulontary work and the date --- src/controllers/index.ts | 20 ++++++++- src/middleware/validation/voluntaryWork.ts | 48 ++++++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 src/middleware/validation/voluntaryWork.ts diff --git a/src/controllers/index.ts b/src/controllers/index.ts index 1b12c5d1..9ae89d8a 100644 --- a/src/controllers/index.ts +++ b/src/controllers/index.ts @@ -48,4 +48,22 @@ const isValidPassword = (password: string) => { } return validation; }; -export { getSender, getDate, isValidPassword }; \ No newline at end of file + +const isValidDate = (date: string) => { + const datePattern = /^\d{4}-(0?[1-9]|1[0-2])-(0?[1-9]|[12]\d|3[01])$/; + if (!datePattern.test(date)) { + return false; + } + + const [year, month, day] = date.split('-').map(Number); + const daysInMonth: { [key: number]: number } = { + 1: 31, 2: 28, 3: 31, 4: 30, 5: 31, 6: 30, 7: 31, 8: 31, 9: 30, 10: 31, 11: 30, 12: 31, + }; + + if (month === 2 && ((year % 4 === 0 && year % 100 !== 0) || (year % 400 === 0))) { + daysInMonth[2] = 29; + } + + return day <= daysInMonth[month]; +} +export { getSender, getDate, isValidPassword, isValidDate }; \ No newline at end of file diff --git a/src/middleware/validation/voluntaryWork.ts b/src/middleware/validation/voluntaryWork.ts new file mode 100644 index 00000000..02b2157c --- /dev/null +++ b/src/middleware/validation/voluntaryWork.ts @@ -0,0 +1,48 @@ +import express from 'express'; +import { NSVoluntaryWork } from '../../../types/voluntaryWork.js'; +import { NSVolunteer } from '../../../types/volunteer.js'; +import { getDate, isValidDate } from '../../controllers/index.js'; + +const validateVoluntaryWork = (req: express.Request, + res: express.Response, + next: express.NextFunction +) => { + const values = ["name", "description", "location", "time", "status", "days", "startedDate", "finishedDate", "capacity", "skillTagIds"]; + const voluntaryWork = req.body; + const errorList = values.map(key => !voluntaryWork[key] && `${key} is Required!`).filter(Boolean); + + const validStatus = voluntaryWork.status.every((status: string) => Object.values(NSVoluntaryWork.StatusType).includes(status as NSVoluntaryWork.StatusType)); + if (!validStatus) { + errorList.push("Invalid status !"); + } + + const validTime = voluntaryWork.time.every((time: string) => Object.values(NSVolunteer.AvailableTime).includes(time as NSVolunteer.AvailableTime)); + if (!validTime) { + errorList.push("Invalid time !"); + } + + const validDays = voluntaryWork.days.every((days: string) => Object.values(NSVolunteer.AvailableDays).includes(days as NSVolunteer.AvailableDays)); + if (!validDays) { + errorList.push("Invalid days !"); + } + + if (voluntaryWork.capacity < 1 || voluntaryWork.capacity > 40) { + errorList.push("Invalid capacity !"); + } + if (!isValidDate(voluntaryWork.startedDate) || !isValidDate(voluntaryWork.finishedDate)) { + errorList.push("Invalid date !") + } + if (getDate(voluntaryWork.startedDate) > getDate(voluntaryWork.finishedDate)){ + errorList.push("The started date should be before the finished date !"); + } + + if (errorList.length) { + res.status(400).send(errorList); + } else { + next(); + } +} + +export { + validateVoluntaryWork +} \ No newline at end of file From a2091ac2a6a58ea8b3303c7c3fdcf5fd53103e8f Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Thu, 5 Oct 2023 21:02:13 +0300 Subject: [PATCH 047/146] Creat a validation for vulonteer --- src/middleware/validation/volunteer.ts | 45 ++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 src/middleware/validation/volunteer.ts diff --git a/src/middleware/validation/volunteer.ts b/src/middleware/validation/volunteer.ts new file mode 100644 index 00000000..2f856c39 --- /dev/null +++ b/src/middleware/validation/volunteer.ts @@ -0,0 +1,45 @@ +import express from 'express'; +import * as EmailValidator from 'email-validator'; +import { isValidPassword } from '../../controllers/index.js'; +import { NSVolunteer } from '../../../types/volunteer.js'; + + +const validateVolunteer = (req: express.Request, + res: express.Response, + next: express.NextFunction +) => { + const values = ["name", "email", "password", "type","availableTime","availableLocation", "PreferredActivities", "availableDays" ]; + const volunteer = req.body; + const errorList = values.map(key => !volunteer[key] && `${key} is Required!`).filter(Boolean); + + if (!EmailValidator.validate(volunteer.email)) { + errorList.push('Email is not Valid'); + } + + errorList.push(...isValidPassword(volunteer.password )); + + const validType= volunteer.type.every((status: string) => Object.values(NSVolunteer.TypeVolunteer).includes(status as NSVolunteer.TypeVolunteer)); + if (!validType) { + errorList.push("Invalid status !"); + } + + const validTime = volunteer.time.every((time: string) => Object.values(NSVolunteer.AvailableTime).includes(time as NSVolunteer.AvailableTime)); + if (!validTime) { + errorList.push("Invalid time !"); + } + + const validDays = volunteer.days.every((days: string) => Object.values(NSVolunteer.AvailableDays).includes(days as NSVolunteer.AvailableDays)); + if (!validDays) { + errorList.push("Invalid days !"); + } + + if (errorList.length) { + res.status(400).send(errorList); + } else { + next(); + } +} + +export { + validateVolunteer +} \ No newline at end of file From 5595908f74e8cc0853c22b5a9206b184b912a843 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Fri, 6 Oct 2023 09:28:42 +0300 Subject: [PATCH 048/146] Creat a login controller to creat a token for valid users --- app.ts | 2 ++ package-lock.json | 31 +++++++++++++++++++++ package.json | 2 ++ src/controllers/permission.ts | 52 ++++++++++++++++++++++++++++++++--- src/routes/permission.ts | 20 +++++++++++--- 5 files changed, 99 insertions(+), 8 deletions(-) diff --git a/app.ts b/app.ts index 2c4f1082..273b4070 100644 --- a/app.ts +++ b/app.ts @@ -4,6 +4,7 @@ import dotenv from 'dotenv' import createError from 'http-errors' import dataSource from './src/db/dataSource.js' import logger from 'morgan' +import cookieParser from 'cookie-parser' import indexRouter from "./src/routes/index.js" import permissionRouter from "./src/routes/permission.js" @@ -16,6 +17,7 @@ const PORT = process.env.PORT || 3000; app.use(express.json()); app.use(express.urlencoded({ extended: false })); +app.use(cookieParser()); app.use('/', indexRouter); app.use('/permission',permissionRouter); diff --git a/package-lock.json b/package-lock.json index 7bcc2cf3..65ceb968 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "version": "1.0.0", "dependencies": { "bcrypt": "^5.1.1", + "cookie-parser": "^1.4.6", "debug": "~2.6.9", "dotenv": "^16.3.1", "email-validator": "^2.0.4", @@ -23,6 +24,7 @@ }, "devDependencies": { "@types/bcrypt": "^5.0.0", + "@types/cookie-parser": "^1.4.4", "@types/express": "^4.17.17", "@types/jsonwebtoken": "^9.0.2", "@types/morgan": "^1.9.6", @@ -94,6 +96,15 @@ "@types/node": "*" } }, + "node_modules/@types/cookie-parser": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/@types/cookie-parser/-/cookie-parser-1.4.4.tgz", + "integrity": "sha512-Var+aj5I6ZgIqsQ05N2V8q5OBrFfZXtIGWWDSrEYLIbMw758obagSwdGcLCjwh1Ga7M7+wj0SDIAaAC/WT7aaA==", + "dev": true, + "dependencies": { + "@types/express": "*" + } + }, "node_modules/@types/express": { "version": "4.17.18", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.18.tgz", @@ -823,6 +834,26 @@ "node": ">= 0.6" } }, + "node_modules/cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-parser": { + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.6.tgz", + "integrity": "sha512-z3IzaNjdwUC2olLIB5/ITd0/setiaFMLYiZJle7xg5Fe9KWAceil7xszYfHHBtDFYLSgJduS2Ty0P1uJdPDJeA==", + "dependencies": { + "cookie": "0.4.1", + "cookie-signature": "1.0.6" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", diff --git a/package.json b/package.json index 2a1a63c1..1af46bbd 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ }, "dependencies": { "bcrypt": "^5.1.1", + "cookie-parser": "^1.4.6", "debug": "~2.6.9", "dotenv": "^16.3.1", "email-validator": "^2.0.4", @@ -27,6 +28,7 @@ }, "devDependencies": { "@types/bcrypt": "^5.0.0", + "@types/cookie-parser": "^1.4.4", "@types/express": "^4.17.17", "@types/jsonwebtoken": "^9.0.2", "@types/morgan": "^1.9.6", diff --git a/src/controllers/permission.ts b/src/controllers/permission.ts index 62402d03..9cf1830e 100644 --- a/src/controllers/permission.ts +++ b/src/controllers/permission.ts @@ -1,7 +1,8 @@ import { NSPermission } from "../../types/permission.js"; -import { OrganizationAdmin } from "../db/entities/OrganizationAdmin.js"; +import jwt from 'jsonwebtoken'; import { Permission } from "../db/entities/Permission.js" import { Volunteer } from "../db/entities/Volunteer.js"; +import { OrganizationAdmin } from "../db/entities/OrganizationAdmin.js"; const createPermission = async (payload: NSPermission.Item) => { try { @@ -81,11 +82,11 @@ const getPermissions = async (payload: { const page = parseInt(payload.page); const pageSize = parseInt(payload.pageSize); - if (payload.id){ + if (payload.id) { return Permission.findOne({ where: { id: payload.id } }) } - if (payload.name){ + if (payload.name) { return Permission.findOne({ where: { name: payload.name } }) } @@ -105,4 +106,47 @@ const getPermissions = async (payload: { }; } -export { createPermission, deletePermission, editPermission, getPermissions } \ No newline at end of file +const login = async (email: string, name: string) => { + const volunteer = await Volunteer.findOneBy({ + email, + name + }); + + const organizationAdmin = await OrganizationAdmin.findOneBy({ + email, + name + }); + + if (volunteer) { + const token = jwt.sign( + { + email: volunteer.email, + name: volunteer.name + }, + process.env.SECRET_KEY || '', + { + expiresIn: "15m" + } + ); + return token; + } else if (organizationAdmin) { + const token = jwt.sign( + { + email: organizationAdmin.email, + name: organizationAdmin.name, + id: organizationAdmin.id + + }, + process.env.SECRET_KEY || '', + { + expiresIn: "15m" + } + ); + return token; + } else { + throw ("Invalid email or name or id !"); + } + +} + +export { login,createPermission, deletePermission, editPermission, getPermissions } \ No newline at end of file diff --git a/src/routes/permission.ts b/src/routes/permission.ts index 130406d2..df689df1 100644 --- a/src/routes/permission.ts +++ b/src/routes/permission.ts @@ -1,5 +1,5 @@ import express from 'express'; -import { createPermission, deletePermission, editPermission, getPermissions } from '../controllers/permission.js'; +import { createPermission, deletePermission, editPermission, getPermissions, login } from '../controllers/permission.js'; var router = express.Router(); @@ -26,7 +26,7 @@ router.delete('/:id', async (req, res) => { }) router.put("/:id", async (req, res, next) => { - editPermission({...req.body, id: req.params.id?.toString()}).then(() => { + editPermission({ ...req.body, id: req.params.id?.toString() }).then(() => { res.status(201).send("Permission edited successfully!!") }).catch(err => { console.error(err); @@ -38,8 +38,8 @@ router.get('/', async (req, res, next) => { const payload = { page: req.query.page?.toString() || '1', pageSize: req.query.pageSize?.toString() || '10', - id: Number(req.query.id ) || 0, - name: req.query.name?.toString() || "" + id: Number(req.query.id) || 0, + name: req.query.name?.toString() || "" }; getPermissions(payload) @@ -52,5 +52,17 @@ router.get('/', async (req, res, next) => { }); }); +router.post('/login', (req, res) => { + const email = req.body.email; + const name = req.body.name; + login(email, name) + .then(data => { + res.status(201).send(data); + }) + .catch(err => { + res.status(401).send(err); + }) +}); + export default router; From d9b4d9a590fefba9f5ce2b2569f059f59fdb90a6 Mon Sep 17 00:00:00 2001 From: TarteelTamimi Date: Fri, 6 Oct 2023 10:29:09 +0300 Subject: [PATCH 049/146] test --- app.ts | 2 ++ src/controllers/volunteer.ts | 23 ++++++++++++++++------- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/app.ts b/app.ts index 072c6413..157f469e 100644 --- a/app.ts +++ b/app.ts @@ -10,6 +10,7 @@ import permissionRouter from "./src/routes/permission.js" import roleRouter from "./src/routes/role.js" import voluntaryWorkRouter from "./src/routes/voluntaryWork.js" import organizationAdminRouter from "./src/routes/organizationAdmin.js" +import organizationProfileRouter from "./src/routes/organizationProfile.js" const app = express(); dotenv.config(); @@ -23,6 +24,7 @@ app.use('/permission',permissionRouter); app.use('/role',roleRouter); app.use('/voluntaryWork',voluntaryWorkRouter); app.use('/organivationAdmin',organizationAdminRouter); +app.use('/organivationProfile',organizationProfileRouter); // app.use('/users', usersRouter); diff --git a/src/controllers/volunteer.ts b/src/controllers/volunteer.ts index c91a3877..1d03f10f 100644 --- a/src/controllers/volunteer.ts +++ b/src/controllers/volunteer.ts @@ -1,23 +1,32 @@ // import { NSVolunteer } from "../../types/volunteer.js"; // import dataSource from "../db/dataSource.js"; -// import { Role } from "../db/entities/Role.js"; +// import { Volunteer } from "../db/entities/Volunteer.js"; // import { VolunteerProfile } from "../db/entities/VolunteerProfile.js"; // const createVolunteer = async (payload: NSVolunteer.Item) => { + // return dataSource.manager.transaction(async (transaction) => { -// const [firstName, ...lastName] = payload.name.split(" ") + // const profile = VolunteerProfile.create({ -// firstName, -// lastName: lastName.join(" "), -// dateOfBirth: payload.dateOfBirth || '', -// status: payload?.status +// availableTime: payload.availableTime + // }) -// await transaction.save(profile) + +// await transaction.save(profile); + // const newUser = User.create(payload); // const roles = await Role.find({ where: { name: newUser?.type || 'user' } }) // newUser.roles = roles; // newUser.profile = profile; // await transaction.save(newUser); // }); + + // }; +// const deleteVolunteer = async (volunteerId: number) => { +// return Volunteer.delete(volunteerId); +// } + +// export { createVolunteer, deleteVolunteer, } + From 16e171375b8853e2f2efb558ffb5200f7818aebc Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Fri, 6 Oct 2023 10:39:23 +0300 Subject: [PATCH 050/146] Creat authorization --- src/controllers/index.ts | 24 +-------------------- src/middleware/auth/authorize.ts | 36 ++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 23 deletions(-) create mode 100644 src/middleware/auth/authorize.ts diff --git a/src/controllers/index.ts b/src/controllers/index.ts index 9ae89d8a..7d9ec0d0 100644 --- a/src/controllers/index.ts +++ b/src/controllers/index.ts @@ -1,25 +1,3 @@ -import express from 'express' -import { OrganizationAdmin } from '../db/entities/OrganizationAdmin.js'; -import { Volunteer } from '../db/entities/Volunteer.js'; - -const getSender = async (res: express.Response) => { - let sender: OrganizationAdmin | Volunteer = new Volunteer(); - if (res.locals.organizationAdmin) { - sender = await OrganizationAdmin.findOne({ - where: { - name: res.locals.organizationAdmin.name, email: res.locals?.organizationAdmin.email - }, relations: ["roles", "roles.permissions"] - }) || new OrganizationAdmin(); - } else if (res.locals.volunteer) { - sender = await Volunteer.findOne({ - where: { - name: res.locals.volunteer.name, email: res.locals?.volunteer.email - }, relations: ["roles", "roles.permissions"] - }) || new Volunteer(); - } - return sender; -} - const getDate = (date: string): Date => { let [year, month, day] = date.split('-').map((str) => { return parseInt(str, 10); }); return new Date(year, month - 1, day, 0, 0, 0, 0); @@ -66,4 +44,4 @@ const isValidDate = (date: string) => { return day <= daysInMonth[month]; } -export { getSender, getDate, isValidPassword, isValidDate }; \ No newline at end of file +export { getDate, isValidPassword, isValidDate }; \ No newline at end of file diff --git a/src/middleware/auth/authorize.ts b/src/middleware/auth/authorize.ts new file mode 100644 index 00000000..49d1c342 --- /dev/null +++ b/src/middleware/auth/authorize.ts @@ -0,0 +1,36 @@ +import express from 'express'; +import { NSPermission } from '../../../types/permission.js'; +import { OrganizationAdmin } from '../../db/entities/OrganizationAdmin.js'; +import { Volunteer } from '../../db/entities/Volunteer.js'; + +const authorize = (api: string) => { + return async ( + req: express.Request, + res: express.Response, + next: express.NextFunction + ) => { + + const permissions: NSPermission.Item[] = []; + + if (res.locals.organizationAdmin) { + const organizationAdmin:OrganizationAdmin = res.locals.organizationAdmin; + permissions.push(...organizationAdmin.roles.permissions); + + } else if (res.locals.volunteer) { + const volunteer:Volunteer = res.locals.volunteer; + volunteer.roles.forEach((role) => { + permissions.push(...role.permissions); + }); + } + + if (permissions?.filter(p => p.name === api).length > 0) { + next(); + } else { + res.status(403).send("You don't have the permission to access this resource!"); + } + } +} + +export { + authorize +} \ No newline at end of file From 39d2eccac6ae89988ab018ac20c1c95bd7cf6fd2 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Fri, 6 Oct 2023 11:13:53 +0300 Subject: [PATCH 051/146] Creat the authentication --- app.ts | 2 +- src/middleware/auth/authenticate.ts | 48 +++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 src/middleware/auth/authenticate.ts diff --git a/app.ts b/app.ts index 273b4070..17c759bd 100644 --- a/app.ts +++ b/app.ts @@ -22,7 +22,7 @@ app.use(cookieParser()); app.use('/', indexRouter); app.use('/permission',permissionRouter); app.use('/role',roleRouter); -app.use('/voluntaryWork',voluntaryWorkRouter) +app.use('/voluntaryWork',voluntaryWorkRouter); // app.use('/users', usersRouter); // catch 404 and forward to error handler diff --git a/src/middleware/auth/authenticate.ts b/src/middleware/auth/authenticate.ts new file mode 100644 index 00000000..cbee6139 --- /dev/null +++ b/src/middleware/auth/authenticate.ts @@ -0,0 +1,48 @@ +import express from 'express'; +import jwt, { JwtPayload } from 'jsonwebtoken'; +import { OrganizationAdmin } from '../../db/entities/OrganizationAdmin.js'; +import { Volunteer } from '../../db/entities/Volunteer.js'; + +const authenticate = async ( + req: express.Request, + res: express.Response, + next: express.NextFunction +) => { + const token = req.cookies['myApp'] || ''; + let tokenIsValid: JwtPayload | null | string; + + try { + tokenIsValid = jwt.verify(token, process.env.SECRET_KEY || ''); + } catch (error) { + tokenIsValid = null; + } + + if (tokenIsValid ) { + const decoded = tokenIsValid as JwtPayload; + + const organizationAdmin = await OrganizationAdmin.findOne({ + where: { name: decoded.name, email: decoded.email, id: decoded.id }, + relations: ["roles", "roles.permissions"] + }); + const volunteer = await Volunteer.findOne({ + where: { name: decoded.name, email: decoded.email, id: decoded.id }, + relations: ["roles", "roles.permissions"] + }); + + if (organizationAdmin) { + res.locals.organizationAdmin = organizationAdmin; + next(); + } else if (volunteer) { + res.locals.volunteer = volunteer; + next(); + } else { + res.status(401).send("You are Unauthorized!"); + } + } else { + res.status(401).send("You are Unauthorized!"); + } +} + +export { + authenticate +} From a8102f78f2ffb43bd8ee400c1fc134cb0cdaa148 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Fri, 6 Oct 2023 11:36:35 +0300 Subject: [PATCH 052/146] creat the cookies and save the token in the cookie --- src/routes/permission.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/routes/permission.ts b/src/routes/permission.ts index df689df1..dd1b4900 100644 --- a/src/routes/permission.ts +++ b/src/routes/permission.ts @@ -57,6 +57,16 @@ router.post('/login', (req, res) => { const name = req.body.name; login(email, name) .then(data => { + res.cookie('myApp', data, { + httpOnly:true, + maxAge: 15 * 60 * 1000, + sameSite:"lax" // Protect against CSRF attacks + }); + res.cookie('name', res.locals.volunteer.name || res.locals.organizationAdmin.name, { + httpOnly:true, + maxAge: 15 * 60 * 1000, + sameSite:"lax" // Protect against CSRF attacks + }); res.status(201).send(data); }) .catch(err => { From 5a25e8ab4b2c1b30bdcdcccc2fc4f23922b0d538 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Fri, 6 Oct 2023 14:37:18 +0300 Subject: [PATCH 053/146] Dreat and edit the whole route with validation, authorization and authountication and preper all the end poits --- app.ts | 15 +-- src/controllers/OrganizationProfile .ts | 5 +- src/controllers/organizationAdmin.ts | 4 +- src/controllers/permission.ts | 48 +------- src/controllers/voluntaryWork.ts | 1 - src/controllers/volunteer.ts | 42 ++++++- .../validation/organizationProfile.ts | 4 +- src/routes/organizationAdmin.ts | 16 +-- src/routes/organizationProfile.ts | 14 ++- src/routes/permission.ts | 34 ++---- src/routes/role.ts | 14 ++- src/routes/users.ts | 51 --------- src/routes/voluntaryWork.ts | 105 ++++++++++++++++-- src/routes/volunteer.ts | 68 ++++++++++++ 14 files changed, 249 insertions(+), 172 deletions(-) delete mode 100644 src/routes/users.ts create mode 100644 src/routes/volunteer.ts diff --git a/app.ts b/app.ts index b9cdcabf..d5f3d553 100644 --- a/app.ts +++ b/app.ts @@ -12,6 +12,8 @@ import roleRouter from "./src/routes/role.js" import voluntaryWorkRouter from "./src/routes/voluntaryWork.js" import organizationAdminRouter from "./src/routes/organizationAdmin.js" import organizationProfileRouter from "./src/routes/organizationProfile.js" +import volunteerRouter from "./src/routes/volunteer.js" +import { authenticate } from "./src/middleware/auth/authenticate.js" const app = express(); dotenv.config(); @@ -22,13 +24,12 @@ app.use(express.urlencoded({ extended: false })); app.use(cookieParser()); app.use('/', indexRouter); -app.use('/permission',permissionRouter); -app.use('/role',roleRouter); -app.use('/voluntaryWork',voluntaryWorkRouter); -app.use('/organivationAdmin',organizationAdminRouter); -app.use('/organivationProfile',organizationProfileRouter); - -// app.use('/users', usersRouter); +app.use('/permission', authenticate, permissionRouter); +app.use('/role', authenticate, roleRouter); +app.use('/voluntaryWork', authenticate, voluntaryWorkRouter); +app.use('/organizationAdmin', authenticate, organizationAdminRouter); +app.use('/organizationProfile', authenticate, organizationProfileRouter); +app.use("/volunteer",volunteerRouter ); // catch 404 and forward to error handler app.use(function (req, res, next) { diff --git a/src/controllers/OrganizationProfile .ts b/src/controllers/OrganizationProfile .ts index bce039f1..f05120d6 100644 --- a/src/controllers/OrganizationProfile .ts +++ b/src/controllers/OrganizationProfile .ts @@ -1,8 +1,7 @@ import { NSOrganizationProfile } from "../../types/organizationProfile.js"; -import { OrganizationAdmin } from "../db/entities/OrganizationAdmin.js"; import { OrganizationProfile } from "../db/entities/OrganizationProfile.js"; -const creatOrganizationProfile = async (payload: NSOrganizationProfile.Item) => { +const createOrganizationProfile = async (payload: NSOrganizationProfile.Item) => { const newOrganizationProfile = OrganizationProfile.create(payload); return newOrganizationProfile.save(); @@ -74,4 +73,4 @@ const getOrganizationProfile = async (payload: { } -export { creatOrganizationProfile, editOrganizationProfile, deleteOrganizationProfile, getOrganizationProfile } \ No newline at end of file +export { createOrganizationProfile, editOrganizationProfile, deleteOrganizationProfile, getOrganizationProfile } \ No newline at end of file diff --git a/src/controllers/organizationAdmin.ts b/src/controllers/organizationAdmin.ts index 33e50096..3a54902f 100644 --- a/src/controllers/organizationAdmin.ts +++ b/src/controllers/organizationAdmin.ts @@ -3,7 +3,7 @@ import { OrganizationAdmin } from "../db/entities/OrganizationAdmin.js"; import { OrganizationProfile } from "../db/entities/OrganizationProfile.js"; import bcrypt from 'bcrypt'; -const creatOrganizationAdmin = async (payload: NSOrganizationAdmin.Item) => { +const createOrganizationAdmin = async (payload: NSOrganizationAdmin.Item) => { const newOrganizationAdmin = OrganizationAdmin.create(payload); @@ -99,4 +99,4 @@ const editOrganizationAdmin = async (payload: { id: string, name: string, email: } -export { creatOrganizationAdmin, deleteOrganizationAdmin, editOrganizationAdmin, getOrganizationAdmins } \ No newline at end of file +export { createOrganizationAdmin , deleteOrganizationAdmin, editOrganizationAdmin, getOrganizationAdmins } \ No newline at end of file diff --git a/src/controllers/permission.ts b/src/controllers/permission.ts index 9cf1830e..459b7ad0 100644 --- a/src/controllers/permission.ts +++ b/src/controllers/permission.ts @@ -1,8 +1,5 @@ import { NSPermission } from "../../types/permission.js"; -import jwt from 'jsonwebtoken'; import { Permission } from "../db/entities/Permission.js" -import { Volunteer } from "../db/entities/Volunteer.js"; -import { OrganizationAdmin } from "../db/entities/OrganizationAdmin.js"; const createPermission = async (payload: NSPermission.Item) => { try { @@ -106,47 +103,4 @@ const getPermissions = async (payload: { }; } -const login = async (email: string, name: string) => { - const volunteer = await Volunteer.findOneBy({ - email, - name - }); - - const organizationAdmin = await OrganizationAdmin.findOneBy({ - email, - name - }); - - if (volunteer) { - const token = jwt.sign( - { - email: volunteer.email, - name: volunteer.name - }, - process.env.SECRET_KEY || '', - { - expiresIn: "15m" - } - ); - return token; - } else if (organizationAdmin) { - const token = jwt.sign( - { - email: organizationAdmin.email, - name: organizationAdmin.name, - id: organizationAdmin.id - - }, - process.env.SECRET_KEY || '', - { - expiresIn: "15m" - } - ); - return token; - } else { - throw ("Invalid email or name or id !"); - } - -} - -export { login,createPermission, deletePermission, editPermission, getPermissions } \ No newline at end of file +export { createPermission, deletePermission, editPermission, getPermissions } \ No newline at end of file diff --git a/src/controllers/voluntaryWork.ts b/src/controllers/voluntaryWork.ts index b5966402..6d1f21ab 100644 --- a/src/controllers/voluntaryWork.ts +++ b/src/controllers/voluntaryWork.ts @@ -2,7 +2,6 @@ import { DeepPartial, FindOperator, FindOptionsWhere, In, LessThan, LessThanOrEq import { NSVoluntaryWork } from "../../types/voluntaryWork.js"; import { SkillTag } from "../db/entities/SkillTag.js"; import { VoluntaryWork } from "../db/entities/VoluntaryWork.js"; -import { NSVolunteer } from "../../types/volunteer.js"; import { getDate } from "./index.js"; const createVoluntaryWork = async (payload: NSVoluntaryWork.Item) => { diff --git a/src/controllers/volunteer.ts b/src/controllers/volunteer.ts index 1d03f10f..7f613440 100644 --- a/src/controllers/volunteer.ts +++ b/src/controllers/volunteer.ts @@ -3,6 +3,11 @@ // import { Volunteer } from "../db/entities/Volunteer.js"; // import { VolunteerProfile } from "../db/entities/VolunteerProfile.js"; +import { OrganizationAdmin } from "../db/entities/OrganizationAdmin.js"; +import { Volunteer } from "../db/entities/Volunteer.js"; +import jwt from 'jsonwebtoken'; + + // const createVolunteer = async (payload: NSVolunteer.Item) => { // return dataSource.manager.transaction(async (transaction) => { @@ -28,5 +33,40 @@ // return Volunteer.delete(volunteerId); // } -// export { createVolunteer, deleteVolunteer, } +const login = async (email: string, name: string, id: string) => { + const volunteer = await Volunteer.findOne({ + where: { email, name, id }, + relations: ["roles", "roles.permissions"], + }); + + const organizationAdmin = await OrganizationAdmin.findOne({ + where: { email, name, id }, + relations: ["roles", "roles.permissions"], + }); + + if (volunteer) { + const token = jwt.sign( + { email, name, id }, + process.env.SECRET_KEY || '', + { + expiresIn: "15m" + } + ); + return token; + } else if (organizationAdmin) { + const token = jwt.sign( + { email, name, id }, + process.env.SECRET_KEY || '', + { + expiresIn: "15m" + } + ); + return token; + } else { + throw ("Invalid email or name or id !"); + } + +} + +export { login,/* createVolunteer, deleteVolunteer,*/ } diff --git a/src/middleware/validation/organizationProfile.ts b/src/middleware/validation/organizationProfile.ts index 13d5797d..55690e62 100644 --- a/src/middleware/validation/organizationProfile.ts +++ b/src/middleware/validation/organizationProfile.ts @@ -1,6 +1,6 @@ import express from 'express'; -const validateOrganizationAdmin = (req: express.Request, +const validateOrganizationProfile = (req: express.Request, res: express.Response, next: express.NextFunction ) => { @@ -16,5 +16,5 @@ const validateOrganizationAdmin = (req: express.Request, } export { - validateOrganizationAdmin + validateOrganizationProfile } \ No newline at end of file diff --git a/src/routes/organizationAdmin.ts b/src/routes/organizationAdmin.ts index cf7482ca..2f96da5d 100644 --- a/src/routes/organizationAdmin.ts +++ b/src/routes/organizationAdmin.ts @@ -1,10 +1,12 @@ import express from "express"; -import { creatOrganizationAdmin, deleteOrganizationAdmin, editOrganizationAdmin, getOrganizationAdmins } from "../controllers/organizationAdmin.js"; +import { createOrganizationAdmin, deleteOrganizationAdmin, editOrganizationAdmin, getOrganizationAdmins } from "../controllers/organizationAdmin.js"; +import { authorize } from "../middleware/auth/authorize.js"; +import { validateOrganizationAdmin } from "../middleware/validation/organizationAdmin.js"; const router = express.Router(); -router.post('/', (req, res, next) => { - creatOrganizationAdmin(req.body).then(() => { +router.post('/', authorize("POST_organizationAdmin"), validateOrganizationAdmin, (req, res, next) => { + createOrganizationAdmin(req.body).then(() => { res.status(201).send("Organization Admin created successfully!!") }).catch(err => { console.error(err); @@ -12,7 +14,7 @@ router.post('/', (req, res, next) => { }); }); -router.delete('/:id', async (req, res) => { +router.delete('/:id', authorize("DELETE_organizationAdmin"), async (req, res) => { const id = Number(req.params.id?.toString()); deleteOrganizationAdmin(id) @@ -25,7 +27,7 @@ router.delete('/:id', async (req, res) => { }); }); -router.put("/", async (req, res, next) => { +router.put("/", authorize("PUT_organizationAdmin"), async (req, res, next) => { editOrganizationAdmin(req.body).then(() => { res.status(201).send("Organization Admin edited successfully!!") }).catch(err => { @@ -34,13 +36,13 @@ router.put("/", async (req, res, next) => { }); }); -router.get('/', async (req, res, next) => { +router.get('/', authorize("GET_organizationAdmins"), async (req, res, next) => { const payload = { page: req.query.page?.toString() || '1', pageSize: req.query.pageSize?.toString() || '10', id: req.query.id?.toString() || '', name: req.query.name?.toString() || '', - email: req.query.eamil?.toString() || '', + email: req.query.email?.toString() || '', organizationName: req.query.organizationName?.toString() || '' }; diff --git a/src/routes/organizationProfile.ts b/src/routes/organizationProfile.ts index e8635f79..a81dd82f 100644 --- a/src/routes/organizationProfile.ts +++ b/src/routes/organizationProfile.ts @@ -1,10 +1,12 @@ import express from "express"; -import { creatOrganizationProfile, deleteOrganizationProfile, editOrganizationProfile, getOrganizationProfile } from "../controllers/OrganizationProfile .js"; +import { createOrganizationProfile, deleteOrganizationProfile, editOrganizationProfile, getOrganizationProfile } from "../controllers/OrganizationProfile .js"; +import { authorize } from "../middleware/auth/authorize.js"; +import { validateOrganizationProfile } from "../middleware/validation/organizationProfile.js"; const router = express.Router(); -router.post('/', (req, res, next) => { - creatOrganizationProfile(req.body).then(() => { +router.post('/', authorize("POST_organizationProfile"), validateOrganizationProfile, (req, res, next) => { + createOrganizationProfile(req.body).then(() => { res.status(201).send("Organization Profile created successfully!!") }).catch(err => { console.error(err); @@ -12,7 +14,7 @@ router.post('/', (req, res, next) => { }); }); -router.delete('/:id', async (req, res) => { +router.delete('/:id', authorize("DELETE_organizationProfile"), async (req, res) => { const id = Number(req.params.id?.toString()); deleteOrganizationProfile(id) @@ -25,7 +27,7 @@ router.delete('/:id', async (req, res) => { }); }); -router.put("/", async (req, res, next) => { +router.put("/", authorize("PUT_organizationProfile"), async (req, res, next) => { editOrganizationProfile(req.body).then(() => { res.status(201).send("Organization Profile edited successfully!!") }).catch(err => { @@ -34,7 +36,7 @@ router.put("/", async (req, res, next) => { }); }); -router.get('/', async (req, res, next) => { +router.get('/', authorize("GET_organizationProfiles"), async (req, res, next) => { const payload = { page: req.query.page?.toString() || '1', pageSize: req.query.pageSize?.toString() || '10', diff --git a/src/routes/permission.ts b/src/routes/permission.ts index dd1b4900..edb5ec11 100644 --- a/src/routes/permission.ts +++ b/src/routes/permission.ts @@ -1,9 +1,11 @@ import express from 'express'; -import { createPermission, deletePermission, editPermission, getPermissions, login } from '../controllers/permission.js'; +import { createPermission, deletePermission, editPermission, getPermissions } from '../controllers/permission.js'; +import { authorize } from '../middleware/auth/authorize.js'; +import { validatePermission } from '../middleware/validation/permission.js'; var router = express.Router(); -router.post('/', (req, res, next) => { +router.post('/', authorize("GET_permissions"), validatePermission, (req, res, next) => { createPermission(req.body).then(() => { res.status(201).send("Permission created successfully!!") }).catch(err => { @@ -12,7 +14,7 @@ router.post('/', (req, res, next) => { }); }); -router.delete('/:id', async (req, res) => { +router.delete('/:id', authorize("DELETE_permission"), async (req, res) => { const id = Number(req.params.id?.toString()); deletePermission(id) @@ -25,7 +27,7 @@ router.delete('/:id', async (req, res) => { }); }) -router.put("/:id", async (req, res, next) => { +router.put("/:id", authorize("PUT_permission"), async (req, res, next) => { editPermission({ ...req.body, id: req.params.id?.toString() }).then(() => { res.status(201).send("Permission edited successfully!!") }).catch(err => { @@ -34,7 +36,7 @@ router.put("/:id", async (req, res, next) => { }); }); -router.get('/', async (req, res, next) => { +router.get('/', authorize("GET_permissions"), async (req, res, next) => { const payload = { page: req.query.page?.toString() || '1', pageSize: req.query.pageSize?.toString() || '10', @@ -52,27 +54,5 @@ router.get('/', async (req, res, next) => { }); }); -router.post('/login', (req, res) => { - const email = req.body.email; - const name = req.body.name; - login(email, name) - .then(data => { - res.cookie('myApp', data, { - httpOnly:true, - maxAge: 15 * 60 * 1000, - sameSite:"lax" // Protect against CSRF attacks - }); - res.cookie('name', res.locals.volunteer.name || res.locals.organizationAdmin.name, { - httpOnly:true, - maxAge: 15 * 60 * 1000, - sameSite:"lax" // Protect against CSRF attacks - }); - res.status(201).send(data); - }) - .catch(err => { - res.status(401).send(err); - }) -}); - export default router; diff --git a/src/routes/role.ts b/src/routes/role.ts index ddb05bdc..ba0eecd5 100644 --- a/src/routes/role.ts +++ b/src/routes/role.ts @@ -1,10 +1,12 @@ import express from 'express'; import { createRole, deleteRole, editRole, getRoles } from '../controllers/role.js'; import { NSRole } from '../../types/role.js'; +import { authorize } from '../middleware/auth/authorize.js'; +import { validateRole } from '../middleware/validation/role.js'; var router = express.Router(); -router.post('/', (req, res, next) => { +router.post('/', authorize("POST_role"), validateRole, (req, res, next) => { createRole(req.body).then(() => { res.status(201).send("Role created successfully!!") }).catch(err => { @@ -13,7 +15,7 @@ router.post('/', (req, res, next) => { }); }); -router.delete('/:id', async (req, res) => { +router.delete('/:id', authorize("DELETE_role"), async (req, res) => { const id = Number(req.params.id?.toString()); deleteRole(id) @@ -26,8 +28,8 @@ router.delete('/:id', async (req, res) => { }); }) -router.put("/:id", async (req, res, next) => { - editRole({...req.body,id: req.params.id?.toString()}).then(() => { +router.put("/:id", authorize("PUT_role"), async (req, res, next) => { + editRole({ ...req.body, id: req.params.id?.toString() }).then(() => { res.status(201).send("Role edited successfully!!") }).catch(err => { console.error(err); @@ -35,11 +37,11 @@ router.put("/:id", async (req, res, next) => { }); }); -router.get('/', async (req, res, next) => { +router.get('/', authorize("DELETE_role"), async (req, res, next) => { const payload = { page: req.query.page?.toString() || '1', pageSize: req.query.pageSize?.toString() || '10', - id: Number(req.query.id ) || 0, + id: Number(req.query.id) || 0, name: req.query.name?.toString() as NSRole.Type }; diff --git a/src/routes/users.ts b/src/routes/users.ts deleted file mode 100644 index 70d8be46..00000000 --- a/src/routes/users.ts +++ /dev/null @@ -1,51 +0,0 @@ -// import express from 'express'; -// import { getAllUsersController, loginController, signupController } from '../controllers/user.js'; -// const router = express.Router(); - -// /* POST Signup user. */ -// router.post("/signup", async (req: express.Request, res: express.Response) => { -// try { -// if (req.body.userName && req.body.password && req.body.email) { -// await signupController(req.body) -// res.status(200).json("User created successfully"); -// } else { -// res.status(400).json("All fields are required"); -// } -// } catch (error) { -// console.log(error); -// if (error !== "user already exists") { -// res.status(500).json("Internal server error"); -// } -// res.status(409).json("user already exists"); -// } -// }); - -// /* POST Login user. */ -// router.post("/login", async (req: express.Request, res: express.Response) => { -// try { -// if (req.body.email && req.body.password) { -// const data = await loginController(req.body) -// res.status(200).json(data); -// } else { -// res.status(400).json("All fields are required"); -// } -// } catch (error) { -// console.log(error); -// res.status(400).json("invalid email or password"); -// } -// }); - - -// /* GET All users. */ -// router.get("/", async (req: express.Request, res: express.Response) => { -// try { -// const users = await getAllUsersController(); -// res.status(200).json({ users: users[0], count: users[1] }); -// } catch (error) { -// console.log(error); -// res.status(500).json("Internal server error"); -// } -// }) - - -// export default router; diff --git a/src/routes/voluntaryWork.ts b/src/routes/voluntaryWork.ts index d347c51a..630f6075 100644 --- a/src/routes/voluntaryWork.ts +++ b/src/routes/voluntaryWork.ts @@ -2,10 +2,12 @@ import express from 'express'; import { createVoluntaryWork, deleteVoluntaryWork, editVoluntaryWork, getVoluntaryWork, getVoluntaryWorks, putFeedback, putImages, putRating } from '../controllers/voluntaryWork.js'; import { NSVolunteer } from '../../types/volunteer.js'; import { NSVoluntaryWork } from '../../types/voluntaryWork.js'; +import { authorize } from '../middleware/auth/authorize.js'; +import { validateVoluntaryWork } from '../middleware/validation/voluntaryWork.js'; var router = express.Router(); -router.post('/', (req, res, next) => { +router.post('/', authorize("POST_voluntaryWork"), validateVoluntaryWork, (req, res, next) => { createVoluntaryWork(req.body).then(() => { res.status(201).send("Voluntary work created successfully!!") }).catch(err => { @@ -14,7 +16,7 @@ router.post('/', (req, res, next) => { }); }); -router.delete('/:id', async (req, res) => { +router.delete('/:id', authorize("DELETE_voluntaryWork"), async (req, res) => { const id = Number(req.params.id?.toString()); deleteVoluntaryWork(id) @@ -26,7 +28,7 @@ router.delete('/:id', async (req, res) => { }); }) -router.put("/:id", async (req, res, next) => { +router.put("/:id", authorize("PUT_voluntaryWork"), async (req, res, next) => { editVoluntaryWork({ ...req.body, id: req.params.id?.toString() }).then(() => { res.status(201).send("Voluntary Work edited successfully!!") }).catch(err => { @@ -35,7 +37,7 @@ router.put("/:id", async (req, res, next) => { }); }); -router.get('/', async (req, res, next) => { +router.get('/', authorize("GET_voluntaryWorks"), async (req, res, next) => { const payload = { page: req.query.page?.toString() || '1', @@ -55,8 +57,8 @@ router.get('/', async (req, res, next) => { finishedBefore: req.query.finishedBefore?.toString() || "", startedAfter: req.query.startedAfter?.toString() || "", startedBefore: req.query.startedBefore?.toString() || "", - ratingMore:Number(req.query.ratingMore) || 0, - ratingLess:Number(req.query.ratingLess) || 0, + ratingMore: Number(req.query.ratingMore) || 0, + ratingLess: Number(req.query.ratingLess) || 0, }; @@ -70,8 +72,78 @@ router.get('/', async (req, res, next) => { }); }); -router.put("/rating/:id", async (req, res, next) => { - putRating( Number(req.params.id),Number(req.body.rating) ).then(() => { +router.get('/analysis', authorize("GET_analysis"), async (req, res, next) => { + + const payload = { + page: req.query.page?.toString() || '1', + pageSize: req.query.pageSize?.toString() || '10', + id: Number(req.query.id) || 0, + name: req.query.name?.toString() || '', + time: ((Array.isArray(req.query.time) ? req.query.time : [req.query.time]).filter(Boolean)) as NSVolunteer.AvailableTime[], + location: (typeof req.query.location === 'string' ? req.query.location : ''), + days: (Array.isArray(req.query.days) ? req.query.days : [req.query.days]).filter(Boolean) as NSVolunteer.AvailableDays[], + rating: Number(req.query.rating) || 0, + status: req.query.status as NSVoluntaryWork.StatusType, + skills: (Array.isArray(req.query.skills) ? req.query.skills : [req.query.skills]).filter(Boolean) as string[], + startedDate: req.query.startedDate?.toString() || "", + finishedDate: req.query.finishedDate?.toString() || "", + capacity: Number(req.query.capacity) || 0, + finishedAfter: req.query.finishedDate?.toString() || "", + finishedBefore: req.query.finishedBefore?.toString() || "", + startedAfter: req.query.startedAfter?.toString() || "", + startedBefore: req.query.startedBefore?.toString() || "", + ratingMore: Number(req.query.ratingMore) || 0, + ratingLess: Number(req.query.ratingLess) || 0, + + }; + + getVoluntaryWorks(payload) + .then(data => { + res.send(data); + }) + .catch(error => { + console.error(error); + res.status(500).send('Something went wrong'); + }); +}); + +router.get('/recommendation', authorize("GET_recommendation"), async (req, res, next) => { + + const payload = { + page: req.query.page?.toString() || '1', + pageSize: req.query.pageSize?.toString() || '10', + id: Number(req.query.id) || 0, + name: req.query.name?.toString() || '', + time: ((Array.isArray(req.query.time) ? req.query.time : [req.query.time]).filter(Boolean)) as NSVolunteer.AvailableTime[], + location: (typeof req.query.location === 'string' ? req.query.location : ''), + days: (Array.isArray(req.query.days) ? req.query.days : [req.query.days]).filter(Boolean) as NSVolunteer.AvailableDays[], + rating: Number(req.query.rating) || 0, + status: req.query.status as NSVoluntaryWork.StatusType, + skills: (Array.isArray(req.query.skills) ? req.query.skills : [req.query.skills]).filter(Boolean) as string[], + startedDate: req.query.startedDate?.toString() || "", + finishedDate: req.query.finishedDate?.toString() || "", + capacity: Number(req.query.capacity) || 0, + finishedAfter: req.query.finishedDate?.toString() || "", + finishedBefore: req.query.finishedBefore?.toString() || "", + startedAfter: req.query.startedAfter?.toString() || "", + startedBefore: req.query.startedBefore?.toString() || "", + ratingMore: Number(req.query.ratingMore) || 0, + ratingLess: Number(req.query.ratingLess) || 0, + + }; + + getVoluntaryWorks(payload) + .then(data => { + res.send(data); + }) + .catch(error => { + console.error(error); + res.status(500).send('Something went wrong'); + }); +}); + +router.put("/rating/:id", authorize("PUT_rating"), async (req, res, next) => { + putRating(Number(req.params.id), Number(req.body.rating)).then(() => { res.status(201).send("Rating added successfully!!") }).catch(err => { console.error(err); @@ -79,8 +151,8 @@ router.put("/rating/:id", async (req, res, next) => { }); }); -router.put("/feedback/:id", async (req, res, next) => { - putFeedback( Number(req.params.id),req.body.feedback).then(() => { +router.put("/feedback/:id", authorize("PUT_feedback"), async (req, res, next) => { + putFeedback(Number(req.params.id), req.body.feedback).then(() => { res.status(201).send("Feedback added successfully!!") }).catch(err => { console.error(err); @@ -88,8 +160,8 @@ router.put("/feedback/:id", async (req, res, next) => { }); }); -router.put("/images/:id", async (req, res, next) => { - putImages( Number(req.params.id),req.body.images).then(() => { +router.put("/images/:id", authorize("PUT_images"), async (req, res, next) => { + putImages(Number(req.params.id), req.body.images).then(() => { res.status(201).send("Images added successfully!!") }).catch(err => { console.error(err); @@ -97,5 +169,14 @@ router.put("/images/:id", async (req, res, next) => { }); }); +router.put("/register/:id", authorize("REGISTER_voluntaryWork"), async (req, res, next) => { + editVoluntaryWork({ ...req.body, id: req.params.id?.toString() }).then(() => { + res.status(201).send("Voluntary Work edited successfully!!") + }).catch(err => { + console.error(err); + res.status(500).send(err); + }); +}); + export default router; diff --git a/src/routes/volunteer.ts b/src/routes/volunteer.ts new file mode 100644 index 00000000..7c19bca4 --- /dev/null +++ b/src/routes/volunteer.ts @@ -0,0 +1,68 @@ +import express from 'express'; +import { authorize } from '../middleware/auth/authorize.js'; +import { authenticate } from '../middleware/auth/authenticate.js'; +import { validateVolunteer } from '../middleware/validation/volunteer.js'; +import { login } from '../controllers/volunteer.js'; + +var router = express.Router(); + +router.post('/register', validateVolunteer, (req, res, next) => { + // create volunteer +}); + +router.post('/login', (req, res, next) => { + const email = req.body.email; + const name = req.body.name; + const id = req.body.id; + login(email, name, id) + .then(data => { + res.cookie('myApp', data, { + httpOnly: true, + maxAge: 15 * 60 * 1000, + sameSite: "lax" // Protect against CSRF attacks + }); + res.cookie('name', res.locals.volunteer.name || res.locals.organizationAdmin.name, { + httpOnly: true, + maxAge: 15 * 60 * 1000, + sameSite: "lax" // Protect against CSRF attacks + }); + res.status(201).send(data); + }) + .catch(err => { + res.status(401).send(err); + }) +}); + +router.delete('/:id', authenticate, authorize("DELETE_volunteer"), async (req, res) => { + +}) + +router.put("/:id", authenticate, authorize("POST_volunteer"), async (req, res, next) => { + +}); + +router.get('/', authenticate, authorize("GET_volunteers"), async (req, res, next) => { + +}); + +router.get("/logout", authenticate, (req, res, next) => { + res.cookie("name", '', { + maxAge: -1 + }) + res.cookie("myApp", '', { + maxAge: -1 + }) + + res.send("Logout correctly!"); +}) + +router.get('/me', authenticate, async (req, res, next) => { + if (res.locals.volunteer) { + res.send(res.locals.volunteer); + } else if (res.locals.organizationAdmin) { + res.send(res.locals.organizationAdmin); + } +}); + +export default router; + From 4d4d0db5b053b539de63637aafca5e3c2dd44e4a Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Fri, 6 Oct 2023 16:31:10 +0300 Subject: [PATCH 054/146] Creat new auth to prevent volnteer, v.w, orgProfile and orgAdmin to be edited or deleted from other non creator or non owner --- src/controllers/organizationAdmin.ts | 3 +- src/middleware/auth/authorize.ts | 82 ++++++++++++++++++++++++++-- src/routes/organizationAdmin.ts | 8 +-- src/routes/organizationProfile.ts | 6 +- src/routes/voluntaryWork.ts | 49 ++++------------- src/routes/volunteer.ts | 6 +- 6 files changed, 100 insertions(+), 54 deletions(-) diff --git a/src/controllers/organizationAdmin.ts b/src/controllers/organizationAdmin.ts index 3a54902f..d9745a30 100644 --- a/src/controllers/organizationAdmin.ts +++ b/src/controllers/organizationAdmin.ts @@ -2,6 +2,7 @@ import { NSOrganizationAdmin } from "../../types/organizationAdmin.js"; import { OrganizationAdmin } from "../db/entities/OrganizationAdmin.js"; import { OrganizationProfile } from "../db/entities/OrganizationProfile.js"; import bcrypt from 'bcrypt'; +import { Volunteer } from "../db/entities/Volunteer.js"; const createOrganizationAdmin = async (payload: NSOrganizationAdmin.Item) => { @@ -99,4 +100,4 @@ const editOrganizationAdmin = async (payload: { id: string, name: string, email: } -export { createOrganizationAdmin , deleteOrganizationAdmin, editOrganizationAdmin, getOrganizationAdmins } \ No newline at end of file +export { createOrganizationAdmin, deleteOrganizationAdmin, editOrganizationAdmin, getOrganizationAdmins } \ No newline at end of file diff --git a/src/middleware/auth/authorize.ts b/src/middleware/auth/authorize.ts index 49d1c342..a5eceb95 100644 --- a/src/middleware/auth/authorize.ts +++ b/src/middleware/auth/authorize.ts @@ -2,6 +2,7 @@ import express from 'express'; import { NSPermission } from '../../../types/permission.js'; import { OrganizationAdmin } from '../../db/entities/OrganizationAdmin.js'; import { Volunteer } from '../../db/entities/Volunteer.js'; +import { OrganizationProfile } from '../../db/entities/OrganizationProfile.js'; const authorize = (api: string) => { return async ( @@ -13,17 +14,17 @@ const authorize = (api: string) => { const permissions: NSPermission.Item[] = []; if (res.locals.organizationAdmin) { - const organizationAdmin:OrganizationAdmin = res.locals.organizationAdmin; + const organizationAdmin: OrganizationAdmin = res.locals.organizationAdmin; permissions.push(...organizationAdmin.roles.permissions); } else if (res.locals.volunteer) { - const volunteer:Volunteer = res.locals.volunteer; + const volunteer: Volunteer = res.locals.volunteer; volunteer.roles.forEach((role) => { permissions.push(...role.permissions); }); } - if (permissions?.filter(p => p.name === api).length > 0) { + if (permissions?.filter(p => p.name === api).length > 0 || (/^PUT_.+/.test(api)) || (/^DELETE_.+/.test(api))) { next(); } else { res.status(403).send("You don't have the permission to access this resource!"); @@ -31,6 +32,79 @@ const authorize = (api: string) => { } } +const checkMe = () => { + return ( + req: express.Request, + res: express.Response, + next: express.NextFunction + ) => { + const id = req.params.id; + if (res.locals.volunteer) { + if (res.locals.volunteer.id == id) { + next() + } + } else if (res.locals.organizationAdmin) { + if (res.locals.organizationAdmin.id == id) { + next(); + } else { + res.status(403).send("You don't have the permission to access this resource!"); + } + } + } +} + +const checkAdmin = () => { + return async ( + req: express.Request, + res: express.Response, + next: express.NextFunction + ) => { + const id = req.params.id; + let organizationProfile = await OrganizationProfile.findOne({ where: { id } }); + const admin = await OrganizationAdmin.findOne({ where: { orgProfile: { id: organizationProfile?.id } } }); + if (res.locals.organizationAdmin) { + if (res.locals.organizationAdmin.id == admin?.id) { + next(); + } else { + res.status(403).send("You don't have the permission to access this resource!"); + } + } + } +} + +const checkCreator = () => { + return async ( + req: express.Request, + res: express.Response, + next: express.NextFunction + ) => { + const id = req.params.id; + let organizationProfile = await OrganizationProfile.findOne({ where: { id } }); + const admin = await OrganizationAdmin.findOne({ where: { orgProfile: { id: organizationProfile?.id } } }); + if (res.locals.organizationAdmin) { + if (res.locals.organizationAdmin.id == admin?.id) { + next(); + } else { + res.status(403).send("You don't have the permission to access this resource!"); + } + } + } +} + +const checkParticipation = () => { + return async ( + req: express.Request, + res: express.Response, + next: express.NextFunction + ) => { + + } +} + export { - authorize + authorize, + checkMe, + checkAdmin, + checkCreator, + checkParticipation } \ No newline at end of file diff --git a/src/routes/organizationAdmin.ts b/src/routes/organizationAdmin.ts index 2f96da5d..2f8556d5 100644 --- a/src/routes/organizationAdmin.ts +++ b/src/routes/organizationAdmin.ts @@ -1,6 +1,6 @@ import express from "express"; import { createOrganizationAdmin, deleteOrganizationAdmin, editOrganizationAdmin, getOrganizationAdmins } from "../controllers/organizationAdmin.js"; -import { authorize } from "../middleware/auth/authorize.js"; +import { authorize, checkMe } from "../middleware/auth/authorize.js"; import { validateOrganizationAdmin } from "../middleware/validation/organizationAdmin.js"; const router = express.Router(); @@ -14,7 +14,7 @@ router.post('/', authorize("POST_organizationAdmin"), validateOrganizationAdmin, }); }); -router.delete('/:id', authorize("DELETE_organizationAdmin"), async (req, res) => { +router.delete('/:id', authorize("DELETE_organizationAdmin"), checkMe, async (req, res) => { const id = Number(req.params.id?.toString()); deleteOrganizationAdmin(id) @@ -27,8 +27,8 @@ router.delete('/:id', authorize("DELETE_organizationAdmin"), async (req, res) => }); }); -router.put("/", authorize("PUT_organizationAdmin"), async (req, res, next) => { - editOrganizationAdmin(req.body).then(() => { +router.put("/:id", authorize("PUT_organizationAdmin"),checkMe(), async (req, res, next) => { + editOrganizationAdmin({...req.body, id:req.params.id}).then(() => { res.status(201).send("Organization Admin edited successfully!!") }).catch(err => { console.error(err); diff --git a/src/routes/organizationProfile.ts b/src/routes/organizationProfile.ts index a81dd82f..24f507cf 100644 --- a/src/routes/organizationProfile.ts +++ b/src/routes/organizationProfile.ts @@ -1,6 +1,6 @@ import express from "express"; import { createOrganizationProfile, deleteOrganizationProfile, editOrganizationProfile, getOrganizationProfile } from "../controllers/OrganizationProfile .js"; -import { authorize } from "../middleware/auth/authorize.js"; +import { authorize, checkAdmin } from "../middleware/auth/authorize.js"; import { validateOrganizationProfile } from "../middleware/validation/organizationProfile.js"; const router = express.Router(); @@ -14,7 +14,7 @@ router.post('/', authorize("POST_organizationProfile"), validateOrganizationProf }); }); -router.delete('/:id', authorize("DELETE_organizationProfile"), async (req, res) => { +router.delete('/:id', authorize("DELETE_organizationProfile"), checkAdmin, async (req, res) => { const id = Number(req.params.id?.toString()); deleteOrganizationProfile(id) @@ -27,7 +27,7 @@ router.delete('/:id', authorize("DELETE_organizationProfile"), async (req, res) }); }); -router.put("/", authorize("PUT_organizationProfile"), async (req, res, next) => { +router.put("/:id", authorize("PUT_organizationProfile"),checkAdmin, async (req, res, next) => { editOrganizationProfile(req.body).then(() => { res.status(201).send("Organization Profile edited successfully!!") }).catch(err => { diff --git a/src/routes/voluntaryWork.ts b/src/routes/voluntaryWork.ts index 630f6075..79df940f 100644 --- a/src/routes/voluntaryWork.ts +++ b/src/routes/voluntaryWork.ts @@ -2,7 +2,7 @@ import express from 'express'; import { createVoluntaryWork, deleteVoluntaryWork, editVoluntaryWork, getVoluntaryWork, getVoluntaryWorks, putFeedback, putImages, putRating } from '../controllers/voluntaryWork.js'; import { NSVolunteer } from '../../types/volunteer.js'; import { NSVoluntaryWork } from '../../types/voluntaryWork.js'; -import { authorize } from '../middleware/auth/authorize.js'; +import { authorize, checkCreator, checkParticipation } from '../middleware/auth/authorize.js'; import { validateVoluntaryWork } from '../middleware/validation/voluntaryWork.js'; var router = express.Router(); @@ -16,7 +16,7 @@ router.post('/', authorize("POST_voluntaryWork"), validateVoluntaryWork, (req, r }); }); -router.delete('/:id', authorize("DELETE_voluntaryWork"), async (req, res) => { +router.delete('/:id', authorize("DELETE_voluntaryWork"), checkCreator, async (req, res) => { const id = Number(req.params.id?.toString()); deleteVoluntaryWork(id) @@ -28,7 +28,7 @@ router.delete('/:id', authorize("DELETE_voluntaryWork"), async (req, res) => { }); }) -router.put("/:id", authorize("PUT_voluntaryWork"), async (req, res, next) => { +router.put("/:id", authorize("PUT_voluntaryWork"), checkCreator, async (req, res, next) => { editVoluntaryWork({ ...req.body, id: req.params.id?.toString() }).then(() => { res.status(201).send("Voluntary Work edited successfully!!") }).catch(err => { @@ -53,10 +53,10 @@ router.get('/', authorize("GET_voluntaryWorks"), async (req, res, next) => { startedDate: req.query.startedDate?.toString() || "", finishedDate: req.query.finishedDate?.toString() || "", capacity: Number(req.query.capacity) || 0, - finishedAfter: req.query.finishedDate?.toString() || "", - finishedBefore: req.query.finishedBefore?.toString() || "", - startedAfter: req.query.startedAfter?.toString() || "", - startedBefore: req.query.startedBefore?.toString() || "", + finishedAfter: "", + finishedBefore: "", + startedAfter: "", + startedBefore: "", ratingMore: Number(req.query.ratingMore) || 0, ratingLess: Number(req.query.ratingLess) || 0, @@ -108,30 +108,7 @@ router.get('/analysis', authorize("GET_analysis"), async (req, res, next) => { }); router.get('/recommendation', authorize("GET_recommendation"), async (req, res, next) => { - - const payload = { - page: req.query.page?.toString() || '1', - pageSize: req.query.pageSize?.toString() || '10', - id: Number(req.query.id) || 0, - name: req.query.name?.toString() || '', - time: ((Array.isArray(req.query.time) ? req.query.time : [req.query.time]).filter(Boolean)) as NSVolunteer.AvailableTime[], - location: (typeof req.query.location === 'string' ? req.query.location : ''), - days: (Array.isArray(req.query.days) ? req.query.days : [req.query.days]).filter(Boolean) as NSVolunteer.AvailableDays[], - rating: Number(req.query.rating) || 0, - status: req.query.status as NSVoluntaryWork.StatusType, - skills: (Array.isArray(req.query.skills) ? req.query.skills : [req.query.skills]).filter(Boolean) as string[], - startedDate: req.query.startedDate?.toString() || "", - finishedDate: req.query.finishedDate?.toString() || "", - capacity: Number(req.query.capacity) || 0, - finishedAfter: req.query.finishedDate?.toString() || "", - finishedBefore: req.query.finishedBefore?.toString() || "", - startedAfter: req.query.startedAfter?.toString() || "", - startedBefore: req.query.startedBefore?.toString() || "", - ratingMore: Number(req.query.ratingMore) || 0, - ratingLess: Number(req.query.ratingLess) || 0, - - }; - + const payload = { ...res.locals.volunteer }; getVoluntaryWorks(payload) .then(data => { res.send(data); @@ -142,7 +119,7 @@ router.get('/recommendation', authorize("GET_recommendation"), async (req, res, }); }); -router.put("/rating/:id", authorize("PUT_rating"), async (req, res, next) => { +router.put("/rating/:id", authorize("PUT_rating"), checkParticipation, async (req, res, next) => { putRating(Number(req.params.id), Number(req.body.rating)).then(() => { res.status(201).send("Rating added successfully!!") }).catch(err => { @@ -151,7 +128,7 @@ router.put("/rating/:id", authorize("PUT_rating"), async (req, res, next) => { }); }); -router.put("/feedback/:id", authorize("PUT_feedback"), async (req, res, next) => { +router.put("/feedback/:id", authorize("PUT_feedback"), checkParticipation, async (req, res, next) => { putFeedback(Number(req.params.id), req.body.feedback).then(() => { res.status(201).send("Feedback added successfully!!") }).catch(err => { @@ -170,12 +147,6 @@ router.put("/images/:id", authorize("PUT_images"), async (req, res, next) => { }); router.put("/register/:id", authorize("REGISTER_voluntaryWork"), async (req, res, next) => { - editVoluntaryWork({ ...req.body, id: req.params.id?.toString() }).then(() => { - res.status(201).send("Voluntary Work edited successfully!!") - }).catch(err => { - console.error(err); - res.status(500).send(err); - }); }); export default router; diff --git a/src/routes/volunteer.ts b/src/routes/volunteer.ts index 7c19bca4..52a7e5b9 100644 --- a/src/routes/volunteer.ts +++ b/src/routes/volunteer.ts @@ -1,5 +1,5 @@ import express from 'express'; -import { authorize } from '../middleware/auth/authorize.js'; +import { authorize, checkMe } from '../middleware/auth/authorize.js'; import { authenticate } from '../middleware/auth/authenticate.js'; import { validateVolunteer } from '../middleware/validation/volunteer.js'; import { login } from '../controllers/volunteer.js'; @@ -33,11 +33,11 @@ router.post('/login', (req, res, next) => { }) }); -router.delete('/:id', authenticate, authorize("DELETE_volunteer"), async (req, res) => { +router.delete('/:id', authenticate, authorize("DELETE_volunteer"), checkMe, async (req, res) => { }) -router.put("/:id", authenticate, authorize("POST_volunteer"), async (req, res, next) => { +router.put("/:id", authenticate, authorize("POST_volunteer"), checkMe, async (req, res, next) => { }); From 0678d69779c64986b0ea68663839fba50a7b7ec9 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Fri, 6 Oct 2023 17:18:45 +0300 Subject: [PATCH 055/146] Creat check participation function to allow rating and give feedback from olny participated voluntters --- src/db/entities/VoluntaryWork.ts | 5 ++- src/db/entities/Volunteer.ts | 2 +- src/middleware/auth/authorize.ts | 61 ++++++++++++++++++++++++++------ 3 files changed, 55 insertions(+), 13 deletions(-) diff --git a/src/db/entities/VoluntaryWork.ts b/src/db/entities/VoluntaryWork.ts index 4c52a28b..03267a94 100644 --- a/src/db/entities/VoluntaryWork.ts +++ b/src/db/entities/VoluntaryWork.ts @@ -53,9 +53,12 @@ export class VoluntaryWork extends BaseEntity { @Column({ type: 'json', nullable: true }) feedback: string[]; - @Column() + @Column({nullable:false}) capacity: number; + @Column({nullable:false}) + creatorId: string; + @ManyToMany(() => SkillTag) @JoinTable() skillTags: SkillTag[]; diff --git a/src/db/entities/Volunteer.ts b/src/db/entities/Volunteer.ts index 0e24acb0..5f3fa201 100644 --- a/src/db/entities/Volunteer.ts +++ b/src/db/entities/Volunteer.ts @@ -34,7 +34,7 @@ export class Volunteer extends BaseEntity { @JoinTable() roles: Role[]; - @OneToOne(() => VolunteerProfile, {cascade: true, onDelete:"CASCADE"}) + @OneToOne(() => VolunteerProfile, {cascade: true, onDelete:"SET NULL"}) @JoinColumn() volunteerProfile: VolunteerProfile diff --git a/src/middleware/auth/authorize.ts b/src/middleware/auth/authorize.ts index a5eceb95..1f8a9395 100644 --- a/src/middleware/auth/authorize.ts +++ b/src/middleware/auth/authorize.ts @@ -3,6 +3,8 @@ import { NSPermission } from '../../../types/permission.js'; import { OrganizationAdmin } from '../../db/entities/OrganizationAdmin.js'; import { Volunteer } from '../../db/entities/Volunteer.js'; import { OrganizationProfile } from '../../db/entities/OrganizationProfile.js'; +import { VoluntaryWork } from '../../db/entities/VoluntaryWork.js'; +import { VolunteerProfile } from '../../db/entities/VolunteerProfile.js'; const authorize = (api: string) => { return async ( @@ -61,13 +63,13 @@ const checkAdmin = () => { ) => { const id = req.params.id; let organizationProfile = await OrganizationProfile.findOne({ where: { id } }); - const admin = await OrganizationAdmin.findOne({ where: { orgProfile: { id: organizationProfile?.id } } }); + const admin = await OrganizationAdmin.findOne({ where: { orgProfile: { id: organizationProfile?.id } } }); if (res.locals.organizationAdmin) { if (res.locals.organizationAdmin.id == admin?.id) { next(); - } else { - res.status(403).send("You don't have the permission to access this resource!"); } + } else { + res.status(403).send("You don't have the permission to access this resource!"); } } } @@ -78,29 +80,66 @@ const checkCreator = () => { res: express.Response, next: express.NextFunction ) => { - const id = req.params.id; - let organizationProfile = await OrganizationProfile.findOne({ where: { id } }); - const admin = await OrganizationAdmin.findOne({ where: { orgProfile: { id: organizationProfile?.id } } }); + const id = Number(req.params.id); + let voluntaryWork = await VoluntaryWork.findOne({ where: { id } }); + if (res.locals.organizationAdmin) { - if (res.locals.organizationAdmin.id == admin?.id) { + if (res.locals.organizationAdmin.id == voluntaryWork?.creatorId) { + next(); + } + } else if (res.locals.volunteer) { + if (res.locals.volunteer.id == voluntaryWork?.creatorId) { next(); - } else { - res.status(403).send("You don't have the permission to access this resource!"); } + } else { + res.status(403).send("You don't have the permission to access this resource!"); } } } -const checkParticipation = () => { +const c1heckParticipation = () => { return async ( req: express.Request, res: express.Response, next: express.NextFunction ) => { - + const id = Number(req.params.id); + let voluntaryWork = await VoluntaryWork.findOne({ where: { id } }); + if(res.locals.volunteer) { + const volunteer:Volunteer=res.locals.volunteer; + }else { + res.status(403).send("You don't have the permission to access this resource!"); + } } } +const checkParticipation = () => { + return async ( + req: express.Request, + res: express.Response, + next: express.NextFunction + ) => { + const id = Number(req.params.id); + + if (res.locals.volunteer) { + const volunteer = res.locals.volunteer; + const volunteerProfile = volunteer.volunteerProfile; + + if (volunteerProfile) { + const voluntaryWork = await VoluntaryWork.findOne({ + where: { id }, + relations: ['volunteerProfiles'] + }); + + if (voluntaryWork && voluntaryWork.volunteerProfiles.includes(volunteerProfile)) { + next(); + } + } + } + res.status(403).send("You don't have permission to access this resource."); + }; +}; + export { authorize, checkMe, From 9e3bbc738d1f88f592be4ea643861448ca1566d3 Mon Sep 17 00:00:00 2001 From: TarteelTamimi Date: Fri, 6 Oct 2023 17:53:21 +0300 Subject: [PATCH 056/146] set up the units of testing --- .babelrc | 5 + .env.test | 7 + __test__/createOrgAdmin.test.js | 28 + app.ts | 10 +- jest.config.json | 3 + package-lock.json | 6452 ++++++++++++++++++++++++++----- package.json | 6 +- src/db/dataSource.ts | 7 + 8 files changed, 5437 insertions(+), 1081 deletions(-) create mode 100644 .babelrc create mode 100644 .env.test create mode 100644 __test__/createOrgAdmin.test.js create mode 100644 jest.config.json diff --git a/.babelrc b/.babelrc new file mode 100644 index 00000000..0639bf76 --- /dev/null +++ b/.babelrc @@ -0,0 +1,5 @@ +{ + "presets": [ + "@babel/preset-env" + ] +} \ No newline at end of file diff --git a/.env.test b/.env.test new file mode 100644 index 00000000..e38aa90e --- /dev/null +++ b/.env.test @@ -0,0 +1,7 @@ +# PORT=3001 +# SECRET_KEY=iugf97$oifh0823!nfoeih80239u$k%lih0f820nfm409 +# DB_HOST=localhost +# DB_PORT=3306 +# DB_USERNAME=root +# DB_PASSWORD="" +# DB_NAME=serve-and-shine \ No newline at end of file diff --git a/__test__/createOrgAdmin.test.js b/__test__/createOrgAdmin.test.js new file mode 100644 index 00000000..124992ca --- /dev/null +++ b/__test__/createOrgAdmin.test.js @@ -0,0 +1,28 @@ +import dataSource, { initDB } from '../dist/src/db/dataSource.js' +import { creatOrganizationAdmin } from '../dist/src/controllers/organizationAdmin.js'; + +beforeAll(async () => { + await initDB(); +}); + +afterAll(async () => { + await dataSource.destroy(); +}); + +const tmpData = { + "name": "Sarah Abu Irmaileh", + "email": "tamimitarteel27@gamil.com", + "password": "toto2003", + "organizationId": "e4b41a72-2abe-459c-8657-7a09956f1243" +}; + +describe("create an organization admin", () => { + let data; + beforeAll(async () => { + data = await creatOrganizationAdmin({name: tmpData.name, email: tmpData.email, password: tmpData.password, organizationId: tmpData.organizationId}); + }) + + it("returns a success response", async () => { + expect(data.name).toBe('Sarah Abu Irmaileh'); + }) +}) diff --git a/app.ts b/app.ts index b9cdcabf..f7ca256d 100644 --- a/app.ts +++ b/app.ts @@ -2,7 +2,7 @@ import "./config.js" import express from 'express' import dotenv from 'dotenv' import createError from 'http-errors' -import dataSource from './src/db/dataSource.js' +import dataSource, { initDB } from './src/db/dataSource.js' import logger from 'morgan' import cookieParser from 'cookie-parser' @@ -46,16 +46,10 @@ app.use(function (err: any, req: any, res: any, next: any) { res.status(err.status || 500).send({ error: err.message }); }); -dataSource.initialize().then(() => { - console.log("Connected to DB!"); -}).catch(err => { - console.error('Failed to connect to DB: ' + err); -}); - app.listen(PORT, () => { logger(`App is listening on port ${PORT}`); console.log(`App is listening on port ${PORT} and host http://localhost:${PORT}`); + initDB(); }); - export default app; diff --git a/jest.config.json b/jest.config.json new file mode 100644 index 00000000..ddc16f35 --- /dev/null +++ b/jest.config.json @@ -0,0 +1,3 @@ +{ + "testTimeout": 20000 +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 65ceb968..42c353fc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,7 @@ "express": "^4.18.2", "http-errors": "~1.6.3", "jade": "~1.11.0", + "jest": "^29.7.0", "jsonwebtoken": "^9.0.2", "morgan": "^1.10.0", "mysql": "^2.18.1", @@ -23,9 +24,11 @@ "typescript": "^5.2.2" }, "devDependencies": { + "@babel/preset-env": "^7.22.20", "@types/bcrypt": "^5.0.0", "@types/cookie-parser": "^1.4.4", "@types/express": "^4.17.17", + "@types/jest": "^29.5.5", "@types/jsonwebtoken": "^9.0.2", "@types/morgan": "^1.9.6", "@types/node": "^20.5.6", @@ -33,219 +36,132 @@ "nodemon": "^3.0.1" } }, - "node_modules/@babel/runtime": { - "version": "7.23.1", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.1.tgz", - "integrity": "sha512-hC2v6p8ZSI/W0HUzh3V8C5g+NwSKzKPtJwSpTjwl0o297GP9+ZLQSkdvHz46CM3LqyoXxq+5G9komY+eSqSO0g==", + "node_modules/@ampproject/remapping": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", + "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", "dependencies": { - "regenerator-runtime": "^0.14.0" + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" }, "engines": { - "node": ">=6.9.0" + "node": ">=6.0.0" } }, - "node_modules/@mapbox/node-pre-gyp": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz", - "integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==", + "node_modules/@babel/code-frame": { + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", "dependencies": { - "detect-libc": "^2.0.0", - "https-proxy-agent": "^5.0.0", - "make-dir": "^3.1.0", - "node-fetch": "^2.6.7", - "nopt": "^5.0.0", - "npmlog": "^5.0.1", - "rimraf": "^3.0.2", - "semver": "^7.3.5", - "tar": "^6.1.11" + "@babel/highlight": "^7.22.13", + "chalk": "^2.4.2" }, - "bin": { - "node-pre-gyp": "bin/node-pre-gyp" - } - }, - "node_modules/@sqltools/formatter": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/@sqltools/formatter/-/formatter-1.2.5.tgz", - "integrity": "sha512-Uy0+khmZqUrUGm5dmMqVlnvufZRSK0FbYzVgp0UMstm+F5+W2/jnEEQyc9vo1ZR/E5ZI/B1WjjoTqBqwJL6Krw==" - }, - "node_modules/@types/bcrypt": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@types/bcrypt/-/bcrypt-5.0.0.tgz", - "integrity": "sha512-agtcFKaruL8TmcvqbndlqHPSJgsolhf/qPWchFlgnW1gECTN/nKbFcoFnvKAQRFfKbh+BO6A3SWdJu9t+xF3Lw==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/body-parser": { - "version": "1.19.3", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.3.tgz", - "integrity": "sha512-oyl4jvAfTGX9Bt6Or4H9ni1Z447/tQuxnZsytsCaExKlmJiU8sFgnIBRzJUpKwB5eWn9HuBYlUlVA74q/yN0eQ==", - "dev": true, - "dependencies": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "node_modules/@types/connect": { - "version": "3.4.36", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.36.tgz", - "integrity": "sha512-P63Zd/JUGq+PdrM1lv0Wv5SBYeA2+CORvbrXbngriYY0jzLUWfQMQQxOhjONEz/wlHOAxOdY7CY65rgQdTjq2w==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/cookie-parser": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/@types/cookie-parser/-/cookie-parser-1.4.4.tgz", - "integrity": "sha512-Var+aj5I6ZgIqsQ05N2V8q5OBrFfZXtIGWWDSrEYLIbMw758obagSwdGcLCjwh1Ga7M7+wj0SDIAaAC/WT7aaA==", - "dev": true, - "dependencies": { - "@types/express": "*" - } - }, - "node_modules/@types/express": { - "version": "4.17.18", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.18.tgz", - "integrity": "sha512-Sxv8BSLLgsBYmcnGdGjjEjqET2U+AKAdCRODmMiq02FgjwuV75Ut85DRpvFjyw/Mk0vgUOliGRU0UUmuuZHByQ==", - "dev": true, - "dependencies": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.33", - "@types/qs": "*", - "@types/serve-static": "*" + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@types/express-serve-static-core": { - "version": "4.17.37", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.37.tgz", - "integrity": "sha512-ZohaCYTgGFcOP7u6aJOhY9uIZQgZ2vxC2yWoArY+FeDXlqeH66ZVBjgvg+RLVAS/DWNq4Ap9ZXu1+SUQiiWYMg==", - "dev": true, + "node_modules/@babel/code-frame/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" } }, - "node_modules/@types/http-errors": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.2.tgz", - "integrity": "sha512-lPG6KlZs88gef6aD85z3HNkztpj7w2R7HmR3gygjfXCQmsLloWNARFkMuzKiiY8FGdh1XDpgBdrSf4aKDiA7Kg==", - "dev": true - }, - "node_modules/@types/jsonwebtoken": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.3.tgz", - "integrity": "sha512-b0jGiOgHtZ2jqdPgPnP6WLCXZk1T8p06A/vPGzUvxpFGgKMbjXJDjC5m52ErqBnIuWZFgGoIJyRdeG5AyreJjA==", - "dev": true, + "node_modules/@babel/code-frame/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dependencies": { - "@types/node": "*" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" } }, - "node_modules/@types/mime": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", - "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", - "dev": true - }, - "node_modules/@types/morgan": { - "version": "1.9.6", - "resolved": "https://registry.npmjs.org/@types/morgan/-/morgan-1.9.6.tgz", - "integrity": "sha512-xfKogz5WcKww2DAiVT9zxMgrqQt+Shq8tDVeLT+otoj6dJnkRkyJxMF51mHtUc3JCPKGk5x1EBU0buuGpfftlQ==", - "dev": true, + "node_modules/@babel/code-frame/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dependencies": { - "@types/node": "*" + "color-name": "1.1.3" } }, - "node_modules/@types/node": { - "version": "20.7.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.7.0.tgz", - "integrity": "sha512-zI22/pJW2wUZOVyguFaUL1HABdmSVxpXrzIqkjsHmyUjNhPoWM1CKfvVuXfetHhIok4RY573cqS0mZ1SJEnoTg==", - "dev": true - }, - "node_modules/@types/qs": { - "version": "6.9.8", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.8.tgz", - "integrity": "sha512-u95svzDlTysU5xecFNTgfFG5RUWu1A9P0VzgpcIiGZA9iraHOdSzcxMxQ55DyeRaGCSxQi7LxXDI4rzq/MYfdg==", - "dev": true - }, - "node_modules/@types/range-parser": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", - "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", - "dev": true + "node_modules/@babel/code-frame/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" }, - "node_modules/@types/send": { - "version": "0.17.2", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.2.tgz", - "integrity": "sha512-aAG6yRf6r0wQ29bkS+x97BIs64ZLxeE/ARwyS6wrldMm3C1MdKwCcnnEwMC1slI8wuxJOpiUH9MioC0A0i+GJw==", - "dev": true, - "dependencies": { - "@types/mime": "^1", - "@types/node": "*" + "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" } }, - "node_modules/@types/serve-static": { - "version": "1.15.3", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.3.tgz", - "integrity": "sha512-yVRvFsEMrv7s0lGhzrggJjNOSmZCdgCjw9xWrPr/kNNLp6FaDfMC1KaYl3TSJ0c58bECwNBMoQrZJ8hA8E1eFg==", - "dev": true, - "dependencies": { - "@types/http-errors": "*", - "@types/mime": "*", - "@types/node": "*" + "node_modules/@babel/code-frame/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" } }, - "node_modules/abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" - }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "node_modules/@babel/code-frame/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" + "has-flag": "^3.0.0" }, "engines": { - "node": ">= 0.6" + "node": ">=4" } }, - "node_modules/acorn": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-2.7.0.tgz", - "integrity": "sha512-pXK8ez/pVjqFdAgBkF1YPVRacuLQ9EXBKaKWaeh58WNfMkCmZhOZzu+NtKSPD5PHmCCHheQ5cD29qM1K4QTxIg==", - "bin": { - "acorn": "bin/acorn" - }, + "node_modules/@babel/compat-data": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.20.tgz", + "integrity": "sha512-BQYjKbpXjoXwFW5jGqiizJQQT/aC7pFm9Ok1OWssonuguICi264lbgMzRp2ZMmRSlfkX6DsWDDcsrctK8Rwfiw==", "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-globals": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-1.0.9.tgz", - "integrity": "sha512-j3/4pkfih8W4NK22gxVSXcEonTpAHOHh0hu5BoZrKcOsW/4oBPxTi4Yk3SAj+FhC1f3+bRTkXdm4019gw1vg9g==", - "dependencies": { - "acorn": "^2.1.0" + "node": ">=6.9.0" } }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dependencies": { - "debug": "4" + "node_modules/@babel/core": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.0.tgz", + "integrity": "sha512-97z/ju/Jy1rZmDxybphrBuI+jtJjFVoz7Mr9yUQVVVi+DNZE333uFQeMOqcCIy1x3WYBIbWftUSLmbNXNT7qFQ==", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.0", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-module-transforms": "^7.23.0", + "@babel/helpers": "^7.23.0", + "@babel/parser": "^7.23.0", + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.0", + "@babel/types": "^7.23.0", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" }, "engines": { - "node": ">= 6.0.0" + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" } }, - "node_modules/agent-base/node_modules/debug": { + "node_modules/@babel/core/node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", @@ -261,1256 +177,4981 @@ } } }, - "node_modules/agent-base/node_modules/ms": { + "node_modules/@babel/core/node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, - "node_modules/align-text": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", - "integrity": "sha512-GrTZLRpmp6wIC2ztrWW9MjjTgSKccffgFagbNDOX95/dcjEcYZibYTeaOntySQLcdw1ztBoFkviiUvTMbb9MYg==", + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz", + "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==", "dependencies": { - "kind-of": "^3.0.2", - "longest": "^1.0.1", - "repeat-string": "^1.5.2" + "@babel/types": "^7.23.0", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" }, "engines": { - "node": ">=0.10.0" + "node": ">=6.9.0" } }, - "node_modules/amdefine": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==", + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", + "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, "engines": { - "node": ">=0.4.2" + "node": ">=6.9.0" } }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.15.tgz", + "integrity": "sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.15" + }, "engines": { - "node": ">=8" + "node": ">=6.9.0" } }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/@babel/helper-compilation-targets": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz", + "integrity": "sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==", "dependencies": { - "color-convert": "^2.0.1" + "@babel/compat-data": "^7.22.9", + "@babel/helper-validator-option": "^7.22.15", + "browserslist": "^4.21.9", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": ">=6.9.0" } }, - "node_modules/any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==" + "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dependencies": { + "yallist": "^3.0.2" + } }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.15.tgz", + "integrity": "sha512-jKkwA59IXcvSaiK2UN45kKwSC9o+KuoXsBDvHvU/7BecYIp8GQ2UwrVvFgJASUT+hBnwJx6MhvMCuMzwZZ7jlg==", "dev": true, "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-function-name": "^7.22.5", + "@babel/helper-member-expression-to-functions": "^7.22.15", + "@babel/helper-optimise-call-expression": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "semver": "^6.3.1" }, "engines": { - "node": ">= 8" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/app-root-path": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-3.1.0.tgz", - "integrity": "sha512-biN3PwB2gUtjaYy/isrU3aNWI5w+fAfvHkSvCKeQGxhmYpwKFUxudR3Yya+KqVRHBmEDYh+/lTozYCFbmzX4nA==", + "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz", + "integrity": "sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "regexpu-core": "^5.3.1", + "semver": "^6.3.1" + }, "engines": { - "node": ">= 6.0.0" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/aproba": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", - "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" + "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } }, - "node_modules/are-we-there-yet": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", - "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.2.tgz", + "integrity": "sha512-k0qnnOqHn5dK9pZpfD5XXZ9SojAITdCKRn2Lp6rnDGzIbaP0rHyMPk/4wsSxVBVz4RfN0q6VpXWP2pDGIoQ7hw==", + "dev": true, "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^3.6.0" + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2" }, - "engines": { - "node": ">=10" + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, - "node_modules/are-we-there-yet/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "node_modules/@babel/helper-define-polyfill-provider/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "ms": "2.1.2" }, "engines": { - "node": ">= 6" + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" - }, - "node_modules/asap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/asap/-/asap-1.0.0.tgz", - "integrity": "sha512-Ej9qjcXY+8Tuy1cNqiwNMwFRXOy9UwgTeMA8LxreodygIPV48lx8PU1ecFxb5ZeU1DpMKxiq6vGLTxcitWZPbA==" - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + "node_modules/@babel/helper-define-polyfill-provider/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] + "node_modules/@babel/helper-environment-visitor": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", + "engines": { + "node": ">=6.9.0" + } }, - "node_modules/basic-auth": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", - "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", + "node_modules/@babel/helper-function-name": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "dependencies": { - "safe-buffer": "5.1.2" + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" }, "engines": { - "node": ">= 0.8" + "node": ">=6.9.0" } }, - "node_modules/basic-auth/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/bcrypt": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.1.1.tgz", - "integrity": "sha512-AGBHOG5hPYZ5Xl9KXzU5iKq9516yEmvCKDg3ecP5kX2aB6UqTeXZxk2ELnDgDm6BQSMlLt9rDB4LoSMx0rYwww==", - "hasInstallScript": true, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", "dependencies": { - "@mapbox/node-pre-gyp": "^1.0.11", - "node-addon-api": "^5.0.0" + "@babel/types": "^7.22.5" }, "engines": { - "node": ">= 10.0.0" + "node": ">=6.9.0" } }, - "node_modules/bignumber.js": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.0.tgz", - "integrity": "sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A==", + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz", + "integrity": "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.23.0" + }, "engines": { - "node": "*" + "node": ">=6.9.0" } }, - "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true, + "node_modules/@babel/helper-module-imports": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", + "dependencies": { + "@babel/types": "^7.22.15" + }, "engines": { - "node": ">=8" + "node": ">=6.9.0" } }, - "node_modules/body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "node_modules/@babel/helper-module-transforms": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.0.tgz", + "integrity": "sha512-WhDWw1tdrlT0gMgUJSlX0IQvoO1eN279zrAUbVB+KpV2c3Tylz8+GnKOLllCS6Z/iZQEyVYxhZVUdPTqs2YYPw==", "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.20" }, "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/body-parser/node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz", + "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==", + "dev": true, "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" + "@babel/types": "^7.22.5" }, "engines": { - "node": ">= 0.8" + "node": ">=6.9.0" } }, - "node_modules/body-parser/node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + "node_modules/@babel/helper-plugin-utils": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", + "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", + "engines": { + "node": ">=6.9.0" + } }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz", + "integrity": "sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==", + "dev": true, "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-wrap-function": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "node_modules/@babel/helper-replace-supers": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.20.tgz", + "integrity": "sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==", "dev": true, "dependencies": { - "fill-range": "^7.0.1" + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-member-expression-to-functions": "^7.22.15", + "@babel/helper-optimise-call-expression": "^7.22.5" }, "engines": { - "node": ">=8" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], + "node_modules/@babel/helper-simple-access": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" } }, - "node_modules/buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" - }, - "node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz", + "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, "engines": { - "node": ">= 0.8" + "node": ">=6.9.0" } }, - "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "@babel/types": "^7.22.5" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=6.9.0" } }, - "node_modules/camelcase": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", - "integrity": "sha512-wzLkDa4K/mzI1OSITC+DUyjgIl/ETNHE9QvYgy6J6Jvqyyz4C0Xfd+lQhb19sX2jMpZV4IssUn0VDVmglV+s4g==", + "node_modules/@babel/helper-string-parser": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", + "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", "engines": { - "node": ">=0.10.0" + "node": ">=6.9.0" } }, - "node_modules/center-align": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", - "integrity": "sha512-Baz3aNe2gd2LP2qk5U+sDk/m4oSuwSDcBfayTCTBoWpfIGO5XFxPmjILQII4NGiZjD6DoDI6kf7gKaxkf7s3VQ==", + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz", + "integrity": "sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.20.tgz", + "integrity": "sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw==", + "dev": true, "dependencies": { - "align-text": "^0.1.3", - "lazy-cache": "^1.0.3" + "@babel/helper-function-name": "^7.22.5", + "@babel/template": "^7.22.15", + "@babel/types": "^7.22.19" }, "engines": { - "node": ">=0.10.0" + "node": ">=6.9.0" } }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/@babel/helpers": { + "version": "7.23.1", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.1.tgz", + "integrity": "sha512-chNpneuK18yW5Oxsr+t553UZzzAs3aZnFm4bxhebsNTeshrC95yA7l5yl7GBAG+JG1rF0F7zzD2EixK9mWSDoA==", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.0", + "@babel/types": "^7.23.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node": ">=6.9.0" } }, - "node_modules/chalk/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/@babel/highlight": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", + "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", "dependencies": { - "has-flag": "^4.0.0" + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0" }, "engines": { - "node": ">=8" + "node": ">=6.9.0" } }, - "node_modules/character-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-1.2.1.tgz", - "integrity": "sha512-6OEBVBlf/y8LaAphnbAnt743O3zMhlBer+FO5D40H6wqAdU9B1TvuApkejgLW0cvv0tEZNLktv1AnRI+C87ueQ==" - }, - "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" + "color-convert": "^1.9.0" }, "engines": { - "node": ">= 8.10.0" + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" }, - "optionalDependencies": { - "fsevents": "~2.3.2" + "engines": { + "node": ">=4" } }, - "node_modules/chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "engines": { - "node": ">=10" + "node": ">=0.8.0" } }, - "node_modules/clean-css": { - "version": "3.4.28", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-3.4.28.tgz", - "integrity": "sha512-aTWyttSdI2mYi07kWqHi24NUU9YlELFKGOAgFzZjDN1064DMAOy2FBuoyGmkKRlXkbpXd0EVHmiVkbKhKoirTw==", + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dependencies": { - "commander": "2.8.x", - "source-map": "0.4.x" + "has-flag": "^3.0.0" }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/parser": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", + "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==", "bin": { - "cleancss": "bin/cleancss" + "parser": "bin/babel-parser.js" }, "engines": { - "node": ">=0.10.0" + "node": ">=6.0.0" } }, - "node_modules/clean-css/node_modules/commander": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz", - "integrity": "sha512-+pJLBFVk+9ZZdlAOB5WuIElVPPth47hILFkmGym57aq8kwxsowvByvB0DHs1vQAhyMZzdcpTtF0VDKGkSDR4ZQ==", + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.22.15.tgz", + "integrity": "sha512-FB9iYlz7rURmRJyXRKEnalYPPdn87H5no108cyuQQyMwlpJ2SJtpIUBI27kdTin956pz+LPypkPVPUTlxOmrsg==", + "dev": true, "dependencies": { - "graceful-readlink": ">= 1.0.0" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { - "node": ">= 0.6.x" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/cli-highlight": { - "version": "2.1.11", - "resolved": "https://registry.npmjs.org/cli-highlight/-/cli-highlight-2.1.11.tgz", - "integrity": "sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg==", + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.22.15.tgz", + "integrity": "sha512-Hyph9LseGvAeeXzikV88bczhsrLrIZqDPxO+sSmAunMPaGrBGhfMWzCPYTtiW9t+HzSE2wtV8e5cc5P6r1xMDQ==", + "dev": true, "dependencies": { - "chalk": "^4.0.0", - "highlight.js": "^10.7.1", - "mz": "^2.4.0", - "parse5": "^5.1.1", - "parse5-htmlparser2-tree-adapter": "^6.0.0", - "yargs": "^16.0.0" + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/plugin-transform-optional-chaining": "^7.22.15" }, - "bin": { - "highlight": "bin/highlight" + "engines": { + "node": ">=6.9.0" }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "dev": true, "engines": { - "node": ">=8.0.0", - "npm": ">=5.0.0" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/cli-highlight/node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/cli-highlight/node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" + "@babel/helper-plugin-utils": "^7.8.0" }, - "engines": { - "node": ">=10" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/cli-highlight/node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "engines": { - "node": ">=10" + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" + "@babel/helper-plugin-utils": "^7.14.5" }, "engines": { - "node": ">=12" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "dev": true, "dependencies": { - "color-name": "~1.1.4" + "@babel/helper-plugin-utils": "^7.8.0" }, - "engines": { - "node": ">=7.0.0" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/color-support": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", - "bin": { - "color-support": "bin.js" + "node_modules/@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", + "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/commander": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.6.0.tgz", - "integrity": "sha512-PhbTMT+ilDXZKqH8xbvuUY2ZEQNef0Q7DKxgoEKb4ccytsdvVVJmYqR0sGbi96nxU6oGrwEIQnclpK2NBZuQlg==", + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.22.5.tgz", + "integrity": "sha512-rdV97N7KqsRzeNGoWUOK6yUsWarLjE5Su/Snk9IYPU9CwkWHs4t+rTGOvffTR8XGkJMTAdLfO0xVnXm8wugIJg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, "engines": { - "node": ">= 0.6.x" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" - }, - "node_modules/concurrently": { - "version": "8.2.1", - "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-8.2.1.tgz", - "integrity": "sha512-nVraf3aXOpIcNud5pB9M82p1tynmZkrSGQ1p6X/VY8cJ+2LMVqAgXsJxYYefACSHbTYlm92O1xuhdGTjwoEvbQ==", + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.22.5.tgz", + "integrity": "sha512-KwvoWDeNKPETmozyFE0P2rOLqh39EoQHNjqizrI5B8Vt0ZNS7M56s7dAiAqbYfiAYOuIzIh96z3iR2ktgu3tEg==", "dev": true, "dependencies": { - "chalk": "^4.1.2", - "date-fns": "^2.30.0", - "lodash": "^4.17.21", - "rxjs": "^7.8.1", - "shell-quote": "^1.8.1", - "spawn-command": "0.0.2", - "supports-color": "^8.1.1", - "tree-kill": "^1.2.2", - "yargs": "^17.7.2" - }, - "bin": { - "conc": "dist/bin/concurrently.js", - "concurrently": "dist/bin/concurrently.js" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { - "node": "^14.13.0 || >=16.0.0" + "node": ">=6.9.0" }, - "funding": { - "url": "https://github.com/open-cli-tools/concurrently?sponsor=1" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==" - }, - "node_modules/constantinople": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-3.0.2.tgz", - "integrity": "sha512-UnEggAQrmhxuTxlb7n1OsTtagNXWUv2CRlOogZhWOU4jLK4EJEbF8UDSNxuGu+jVtWNtO2j51ab2H1wlBIzF/w==", - "deprecated": "Please update to at least constantinople 3.1.1", + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", "dependencies": { - "acorn": "^2.1.0" + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", "dependencies": { - "safe-buffer": "5.2.1" + "@babel/helper-plugin-utils": "^7.8.0" }, - "engines": { - "node": ">= 0.6" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz", + "integrity": "sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, "engines": { - "node": ">= 0.6" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/cookie": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", - "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==", - "engines": { - "node": ">= 0.6" + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/cookie-parser": { - "version": "1.4.6", - "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.6.tgz", - "integrity": "sha512-z3IzaNjdwUC2olLIB5/ITd0/setiaFMLYiZJle7xg5Fe9KWAceil7xszYfHHBtDFYLSgJduS2Ty0P1uJdPDJeA==", + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", "dependencies": { - "cookie": "0.4.1", - "cookie-signature": "1.0.6" + "@babel/helper-plugin-utils": "^7.8.0" }, - "engines": { - "node": ">= 0.8.0" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" - }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "node_modules/css": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/css/-/css-1.0.8.tgz", - "integrity": "sha512-qmTYWhHk910nQWnGqMAiWWPQlB6tESiWgNebQJmiozOAGcBAQ1+U/UzUOkhdrcshlkSRRiKWodwmVvO0OmnIGg==", + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", "dependencies": { - "css-parse": "1.0.4", - "css-stringify": "1.0.5" + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/css-parse": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-1.0.4.tgz", - "integrity": "sha512-pfstzKVRZiHprDXdsmtfH1HYUEw22lzjuHdnpe1hscwoQvgW2C5zDQIBE0RKoALEReTn9W1ECdY8uaT/kO4VfA==" + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "node_modules/css-stringify": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/css-stringify/-/css-stringify-1.0.5.tgz", - "integrity": "sha512-aIThpcErhG5EyHorGqNlTh0TduNBqLrrXLO3x5rku3ZKBxuVfY+T7noyM2G2X/01iQANqJUb6d3+FLoa+N7Xwg==" + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "node_modules/date-fns": { - "version": "2.30.0", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", - "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dev": true, "dependencies": { - "@babel/runtime": "^7.21.0" + "@babel/helper-plugin-utils": "^7.14.5" }, "engines": { - "node": ">=0.11" + "node": ">=6.9.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/date-fns" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", "dependencies": { - "ms": "2.0.0" + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.22.5.tgz", + "integrity": "sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, "engines": { - "node": ">=0.10.0" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==" - }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, "engines": { - "node": ">= 0.8" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.22.5.tgz", + "integrity": "sha512-26lTNXoVRdAnsaDXPpvCNUq+OVWEVC6bx7Vvz9rC53F2bagUWW4u4ii2+h8Fejfh7RYqPxn+libeFBBck9muEw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/detect-libc": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz", - "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==", + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.22.15.tgz", + "integrity": "sha512-jBm1Es25Y+tVoTi5rfd5t1KLmL8ogLKpXszboWOTTtGFGz2RKnQe2yn7HbZ+kb/B8N0FVSGQo874NSlOU1T4+w==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-remap-async-to-generator": "^7.22.9", + "@babel/plugin-syntax-async-generators": "^7.8.4" + }, "engines": { - "node": ">=8" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/dotenv": { - "version": "16.3.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", - "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==", + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.22.5.tgz", + "integrity": "sha512-b1A8D8ZzE/VhNDoV1MSJTnpKkCG5bJo+19R4o4oy03zM7ws8yEMK755j61Dc3EyvdysbqH5BOOTquJ7ZX9C6vQ==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-remap-async-to-generator": "^7.22.5" + }, "engines": { - "node": ">=12" + "node": ">=6.9.0" }, - "funding": { - "url": "https://github.com/motdotla/dotenv?sponsor=1" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.22.5.tgz", + "integrity": "sha512-tdXZ2UdknEKQWKJP1KMNmuF5Lx3MymtMN/pvA+p/VEkhK8jVcQ1fzSy8KM9qRYhAf2/lV33hoMPKI/xaI9sADA==", + "dev": true, "dependencies": { - "safe-buffer": "^5.0.1" + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" - }, - "node_modules/email-validator": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/email-validator/-/email-validator-2.0.4.tgz", - "integrity": "sha512-gYCwo7kh5S3IDyZPLZf6hSS0MnZT8QmJFqYvbqlDZSbwdZlY6QZWxJ4i/6UhITOJ4XzyI647Bm2MXKCLqnJ4nQ==", + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.0.tgz", + "integrity": "sha512-cOsrbmIOXmf+5YbL99/S49Y3j46k/T16b9ml8bm9lP6N9US5iQ2yBK7gpui1pg0V/WMcXdkfKbTb7HXq9u+v4g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, "engines": { - "node": ">4.0" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.22.5.tgz", + "integrity": "sha512-nDkQ0NfkOhPTq8YCLiWNxp1+f9fCobEjCb0n8WdbNUBc4IB5V7P1QnX9IjpSoquKrXF5SKojHleVNs2vGeHCHQ==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, "engines": { - "node": ">= 0.8" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.22.11.tgz", + "integrity": "sha512-GMM8gGmqI7guS/llMFk1bJDkKfn3v3C4KHK9Yg1ey5qcHcOlKb0QvcMrgzvxo+T03/4szNh5lghY+fEC98Kq9g==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.22.11", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + }, "engines": { - "node": ">=6" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" } }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + "node_modules/@babel/plugin-transform-classes": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.22.15.tgz", + "integrity": "sha512-VbbC3PGjBdE0wAWDdHM9G8Gm977pnYI0XpqMd6LrKISj8/DJXEsWqgRuTYaNE9Bv0JGhTZUzHDlMk18IpOuoqw==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-function-name": "^7.22.5", + "@babel/helper-optimise-call-expression": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.9", + "@babel/helper-split-export-declaration": "^7.22.6", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.22.5.tgz", + "integrity": "sha512-4GHWBgRf0krxPX+AaPtgBAlTgTeZmqDynokHOX7aqqAB4tHs3U2Y02zH6ETFdLZGcg9UQSD1WCmkVrE9ErHeOg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/template": "^7.22.5" + }, "engines": { - "node": ">= 0.6" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/express": { - "version": "4.18.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.0.tgz", + "integrity": "sha512-vaMdgNXFkYrB+8lbgniSYWHsgqK5gjaMNcc84bMIOMRLH0L9AqYq3hwMdvnyqj1OPqea8UtjPEuS/DCenah1wg==", + "dev": true, "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.1", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.5.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.11.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { - "node": ">= 0.10.0" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/express/node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.22.5.tgz", + "integrity": "sha512-5/Yk9QxCQCl+sOIB1WelKnVRxTJDSAIxtJLL2/pqL14ZVlbH0fUQUZa/T5/UnQtBNgghR7mfB8ERBKyKPCi7Vw==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, "engines": { - "node": ">= 0.6" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/express/node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.22.5.tgz", + "integrity": "sha512-dEnYD+9BBgld5VBXHnF/DbYGp3fqGMsyxKbtD1mDyIA7AkTSpKXFhCVuj/oQVOoALfBs77DudA0BE4d5mcpmqw==", + "dev": true, "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { - "node": ">= 0.8" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/express/node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.22.11.tgz", + "integrity": "sha512-g/21plo58sfteWjaO0ZNVb+uEOkJNjAaHhbejrnBmu011l/eNDScmkbjCC3l4FKb10ViaGU4aOkFznSu2zRHgA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.22.5.tgz", + "integrity": "sha512-vIpJFNM/FjZ4rh1myqIya9jXwrwwgFRHPjT3DkUA9ZLHuzox8jiXkOLvwm1H+PQIP3CqfC++WPKeuDi0Sjdj1g==", "dev": true, "dependencies": { - "to-regex-range": "^5.0.1" + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { - "node": ">=8" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.22.11.tgz", + "integrity": "sha512-xa7aad7q7OiT8oNZ1mU7NrISjlSkVdMbNxn9IuLZyL9AJEhs1Apba3I+u5riX1dIkdptP5EKDG5XDPByWxtehw==", + "dev": true, "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" }, "engines": { - "node": ">= 0.8" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.22.15.tgz", + "integrity": "sha512-me6VGeHsx30+xh9fbDLLPi0J1HzmeIIyenoOQHuw2D4m2SAU3NrspX5XxJLBpqn5yrLzrlw2Iy3RA//Bx27iOA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, "engines": { - "node": ">= 0.6" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.22.5.tgz", + "integrity": "sha512-UIzQNMS0p0HHiQm3oelztj+ECwFnj+ZRV4KnguvlsD2of1whUeM6o7wGNj6oLwcDoAXQ8gEqfgC24D+VdIcevg==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.5", + "@babel/helper-function-name": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, "engines": { - "node": ">= 0.6" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.22.11.tgz", + "integrity": "sha512-CxT5tCqpA9/jXFlme9xIBCc5RPtdDq3JpkkhgHQqtDdiTnTI0jtZ0QzXhr5DILeYifDPp2wvY2ad+7+hLMW5Pw==", + "dev": true, "dependencies": { - "minipass": "^3.0.0" + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-json-strings": "^7.8.3" }, "engines": { - "node": ">= 8" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/fs-minipass/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "node_modules/@babel/plugin-transform-literals": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.22.5.tgz", + "integrity": "sha512-fTLj4D79M+mepcw3dgFBTIDYpbcB9Sm0bpm4ppXPaO+U+PKFFyV9MGRvS0gvGw62sd10kT5lRMKXAADb9pWy8g==", + "dev": true, "dependencies": { - "yallist": "^4.0.0" + "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { - "node": ">=8" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.22.11.tgz", + "integrity": "sha512-qQwRTP4+6xFCDV5k7gZBF3C31K34ut0tbEcTKxlX/0KXxm9GLcO14p570aWxFvVzx6QAfPgq7gaeIHXJC8LswQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.22.5.tgz", + "integrity": "sha512-RZEdkNtzzYCFl9SE9ATaUMTj2hqMb4StarOJLrZRbqqU4HSBE7UlBw9WBWQiDzrJZJdUWiMTVDI6Gv/8DPvfew==", "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.23.0.tgz", + "integrity": "sha512-xWT5gefv2HGSm4QHtgc1sYPbseOyf+FFDo2JbpE25GWl5BqTGO9IMwTYJRoIdjsF85GE+VegHxSCUt5EvoYTAw==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.23.0", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "node_modules/gauge": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", - "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.0.tgz", + "integrity": "sha512-32Xzss14/UVc7k9g775yMIvkVK8xwKE0DPdP5JTapr3+Z9w4tzeOuLNY6BXDQR6BdnzIlXnCGAzsk/ICHBLVWQ==", + "dev": true, "dependencies": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.2", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.1", - "object-assign": "^4.1.1", - "signal-exit": "^3.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.2" + "@babel/helper-module-transforms": "^7.23.0", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-simple-access": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.0.tgz", + "integrity": "sha512-qBej6ctXZD2f+DhlOC9yO47yEYgUh5CZNz/aBoH4j/3NOlRfJXJbY7xDQCqQVf9KbrqGzIWER1f23doHGrIHFg==", + "dev": true, + "dependencies": { + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-module-transforms": "^7.23.0", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.22.5.tgz", + "integrity": "sha512-+S6kzefN/E1vkSsKx8kmQuqeQsvCKCd1fraCM7zXm4SFoggI099Tr4G8U81+5gtMdUeMQ4ipdQffbKLX0/7dBQ==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz", + "integrity": "sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.22.5.tgz", + "integrity": "sha512-AsF7K0Fx/cNKVyk3a+DW0JLo+Ua598/NxMRvxDnkpCIGFh43+h/v2xyhRUYf6oD8gE4QtL83C7zZVghMjHd+iw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.22.11.tgz", + "integrity": "sha512-YZWOw4HxXrotb5xsjMJUDlLgcDXSfO9eCmdl1bgW4+/lAGdkjaEvOnQ4p5WKKdUgSzO39dgPl0pTnfxm0OAXcg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.22.11.tgz", + "integrity": "sha512-3dzU4QGPsILdJbASKhF/V2TVP+gJya1PsueQCxIPCEcerqF21oEcrob4mzjsp2Py/1nLfF5m+xYNMDpmA8vffg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.22.15.tgz", + "integrity": "sha512-fEB+I1+gAmfAyxZcX1+ZUwLeAuuf8VIg67CTznZE0MqVFumWkh8xWtn58I4dxdVf080wn7gzWoF8vndOViJe9Q==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.22.9", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.22.5.tgz", + "integrity": "sha512-klXqyaT9trSjIUrcsYIfETAzmOEZL3cBYqOYLJxBHfMFFggmXOv+NYSX/Jbs9mzMVESw/WycLFPRx8ba/b2Ipw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.22.11.tgz", + "integrity": "sha512-rli0WxesXUeCJnMYhzAglEjLWVDF6ahb45HuprcmQuLidBJFWjNnOzssk2kuc6e33FlLaiZhG/kUIzUMWdBKaQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.23.0.tgz", + "integrity": "sha512-sBBGXbLJjxTzLBF5rFWaikMnOGOk/BmK6vVByIdEggZ7Vn6CvWXZyRkkLFK6WE0IF8jSliyOkUN6SScFgzCM0g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.22.15.tgz", + "integrity": "sha512-hjk7qKIqhyzhhUvRT683TYQOFa/4cQKwQy7ALvTpODswN40MljzNDa0YldevS6tGbxwaEKVn502JmY0dP7qEtQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.22.5.tgz", + "integrity": "sha512-PPjh4gyrQnGe97JTalgRGMuU4icsZFnWkzicB/fUtzlKUqvsWBKEpPPfr5a2JiyirZkHxnAqkQMO5Z5B2kK3fA==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.22.11.tgz", + "integrity": "sha512-sSCbqZDBKHetvjSwpyWzhuHkmW5RummxJBVbYLkGkaiTOWGxml7SXt0iWa03bzxFIx7wOj3g/ILRd0RcJKBeSQ==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.22.11", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.22.5.tgz", + "integrity": "sha512-TiOArgddK3mK/x1Qwf5hay2pxI6wCZnvQqrFSqbtg1GLl2JcNMitVH/YnqjP+M31pLUeTfzY1HAXFDnUBV30rQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.22.10.tgz", + "integrity": "sha512-F28b1mDt8KcT5bUyJc/U9nwzw6cV+UmTeRlXYIl2TNqMMJif0Jeey9/RQ3C4NOd2zp0/TRsDns9ttj2L523rsw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "regenerator-transform": "^0.15.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.22.5.tgz", + "integrity": "sha512-DTtGKFRQUDm8svigJzZHzb/2xatPc6TzNvAIJ5GqOKDsGFYgAskjRulbR/vGsPKq3OPqtexnz327qYpP57RFyA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.22.5.tgz", + "integrity": "sha512-vM4fq9IXHscXVKzDv5itkO1X52SmdFBFcMIBZ2FRn2nqVYqw6dBexUgMvAjHW+KXpPPViD/Yo3GrDEBaRC0QYA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.22.5.tgz", + "integrity": "sha512-5ZzDQIGyvN4w8+dMmpohL6MBo+l2G7tfC/O2Dg7/hjpgeWvUx8FzfeOKxGog9IimPa4YekaQ9PlDqTLOljkcxg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.22.5.tgz", + "integrity": "sha512-zf7LuNpHG0iEeiyCNwX4j3gDg1jgt1k3ZdXBKbZSoA3BbGQGvMiSvfbZRR3Dr3aeJe3ooWFZxOOG3IRStYp2Bw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.22.5.tgz", + "integrity": "sha512-5ciOehRNf+EyUeewo8NkbQiUs4d6ZxiHo6BcBcnFlgiJfu16q0bQUw9Jvo0b0gBKFG1SMhDSjeKXSYuJLeFSMA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.22.5.tgz", + "integrity": "sha512-bYkI5lMzL4kPii4HHEEChkD0rkc+nvnlR6+o/qdqR6zrm0Sv/nodmyLhlq2DO0YKLUNd2VePmPRjJXSBh9OIdA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.22.10", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.22.10.tgz", + "integrity": "sha512-lRfaRKGZCBqDlRU3UIFovdp9c9mEvlylmpod0/OatICsSfuQ9YFthRo1tpTkGsklEefZdqlEFdY4A2dwTb6ohg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.22.5.tgz", + "integrity": "sha512-HCCIb+CbJIAE6sXn5CjFQXMwkCClcOfPCzTlilJ8cUatfzwHlWQkbtV0zD338u9dZskwvuOYTuuaMaA8J5EI5A==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.22.5.tgz", + "integrity": "sha512-028laaOKptN5vHJf9/Arr/HiJekMd41hOEZYvNsrsXqJ7YPYuX2bQxh31fkZzGmq3YqHRJzYFFAVYvKfMPKqyg==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.22.5.tgz", + "integrity": "sha512-lhMfi4FC15j13eKrh3DnYHjpGj6UKQHtNKTbtc1igvAhRy4+kLhV07OpLcsN0VgDEw/MjAvJO4BdMJsHwMhzCg==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.22.20.tgz", + "integrity": "sha512-11MY04gGC4kSzlPHRfvVkNAZhUxOvm7DCJ37hPDnUENwe06npjIRAfInEMTGSb4LZK5ZgDFkv5hw0lGebHeTyg==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.22.20", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-option": "^7.22.15", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.22.15", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.22.15", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-import-assertions": "^7.22.5", + "@babel/plugin-syntax-import-attributes": "^7.22.5", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.22.5", + "@babel/plugin-transform-async-generator-functions": "^7.22.15", + "@babel/plugin-transform-async-to-generator": "^7.22.5", + "@babel/plugin-transform-block-scoped-functions": "^7.22.5", + "@babel/plugin-transform-block-scoping": "^7.22.15", + "@babel/plugin-transform-class-properties": "^7.22.5", + "@babel/plugin-transform-class-static-block": "^7.22.11", + "@babel/plugin-transform-classes": "^7.22.15", + "@babel/plugin-transform-computed-properties": "^7.22.5", + "@babel/plugin-transform-destructuring": "^7.22.15", + "@babel/plugin-transform-dotall-regex": "^7.22.5", + "@babel/plugin-transform-duplicate-keys": "^7.22.5", + "@babel/plugin-transform-dynamic-import": "^7.22.11", + "@babel/plugin-transform-exponentiation-operator": "^7.22.5", + "@babel/plugin-transform-export-namespace-from": "^7.22.11", + "@babel/plugin-transform-for-of": "^7.22.15", + "@babel/plugin-transform-function-name": "^7.22.5", + "@babel/plugin-transform-json-strings": "^7.22.11", + "@babel/plugin-transform-literals": "^7.22.5", + "@babel/plugin-transform-logical-assignment-operators": "^7.22.11", + "@babel/plugin-transform-member-expression-literals": "^7.22.5", + "@babel/plugin-transform-modules-amd": "^7.22.5", + "@babel/plugin-transform-modules-commonjs": "^7.22.15", + "@babel/plugin-transform-modules-systemjs": "^7.22.11", + "@babel/plugin-transform-modules-umd": "^7.22.5", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", + "@babel/plugin-transform-new-target": "^7.22.5", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.22.11", + "@babel/plugin-transform-numeric-separator": "^7.22.11", + "@babel/plugin-transform-object-rest-spread": "^7.22.15", + "@babel/plugin-transform-object-super": "^7.22.5", + "@babel/plugin-transform-optional-catch-binding": "^7.22.11", + "@babel/plugin-transform-optional-chaining": "^7.22.15", + "@babel/plugin-transform-parameters": "^7.22.15", + "@babel/plugin-transform-private-methods": "^7.22.5", + "@babel/plugin-transform-private-property-in-object": "^7.22.11", + "@babel/plugin-transform-property-literals": "^7.22.5", + "@babel/plugin-transform-regenerator": "^7.22.10", + "@babel/plugin-transform-reserved-words": "^7.22.5", + "@babel/plugin-transform-shorthand-properties": "^7.22.5", + "@babel/plugin-transform-spread": "^7.22.5", + "@babel/plugin-transform-sticky-regex": "^7.22.5", + "@babel/plugin-transform-template-literals": "^7.22.5", + "@babel/plugin-transform-typeof-symbol": "^7.22.5", + "@babel/plugin-transform-unicode-escapes": "^7.22.10", + "@babel/plugin-transform-unicode-property-regex": "^7.22.5", + "@babel/plugin-transform-unicode-regex": "^7.22.5", + "@babel/plugin-transform-unicode-sets-regex": "^7.22.5", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "@babel/types": "^7.22.19", + "babel-plugin-polyfill-corejs2": "^0.4.5", + "babel-plugin-polyfill-corejs3": "^0.8.3", + "babel-plugin-polyfill-regenerator": "^0.5.2", + "core-js-compat": "^3.31.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==", + "dev": true + }, + "node_modules/@babel/runtime": { + "version": "7.23.1", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.1.tgz", + "integrity": "sha512-hC2v6p8ZSI/W0HUzh3V8C5g+NwSKzKPtJwSpTjwl0o297GP9+ZLQSkdvHz46CM3LqyoXxq+5G9komY+eSqSO0g==", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", + "dependencies": { + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.0.tgz", + "integrity": "sha512-t/QaEvyIoIkwzpiZ7aoSKK8kObQYeF7T2v+dazAYCb8SXtp58zEVkWW7zAnju8FNKNdr4ScAOEDmMItbyOmEYw==", + "dependencies": { + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.0", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.0", + "@babel/types": "^7.23.0", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@babel/traverse/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/@babel/types": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", + "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==", + "dependencies": { + "@babel/helper-string-parser": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==" + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", + "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/core": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", + "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/reporters": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^29.7.0", + "jest-config": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-resolve-dependencies": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "jest-watcher": "^29.7.0", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/environment": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", + "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", + "dependencies": { + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", + "dependencies": { + "expect": "^29.7.0", + "jest-snapshot": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", + "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", + "dependencies": { + "jest-get-type": "^29.6.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/fake-timers": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", + "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", + "dependencies": { + "@jest/types": "^29.6.3", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/globals": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", + "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/types": "^29.6.3", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/reporters": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", + "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^6.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "v8-to-istanbul": "^9.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/source-map": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", + "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.18", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-result": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", + "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", + "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", + "dependencies": { + "@jest/test-result": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/transform": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.19", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz", + "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@mapbox/node-pre-gyp": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz", + "integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==", + "dependencies": { + "detect-libc": "^2.0.0", + "https-proxy-agent": "^5.0.0", + "make-dir": "^3.1.0", + "node-fetch": "^2.6.7", + "nopt": "^5.0.0", + "npmlog": "^5.0.1", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.11" + }, + "bin": { + "node-pre-gyp": "bin/node-pre-gyp" + } + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==" + }, + "node_modules/@sinonjs/commons": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", + "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==", + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", + "dependencies": { + "@sinonjs/commons": "^3.0.0" + } + }, + "node_modules/@sqltools/formatter": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@sqltools/formatter/-/formatter-1.2.5.tgz", + "integrity": "sha512-Uy0+khmZqUrUGm5dmMqVlnvufZRSK0FbYzVgp0UMstm+F5+W2/jnEEQyc9vo1ZR/E5ZI/B1WjjoTqBqwJL6Krw==" + }, + "node_modules/@types/babel__core": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.2.tgz", + "integrity": "sha512-pNpr1T1xLUc2l3xJKuPtsEky3ybxN3m4fJkknfIpTCTfIZCDW57oAg+EfCgIIp2rvCe0Wn++/FfodDS4YXxBwA==", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.5", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.5.tgz", + "integrity": "sha512-h9yIuWbJKdOPLJTbmSpPzkF67e659PbQDba7ifWm5BJ8xTv+sDmS7rFmywkWOvXedGTivCdeGSIIX8WLcRTz8w==", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.2.tgz", + "integrity": "sha512-/AVzPICMhMOMYoSx9MoKpGDKdBRsIXMNByh1PXSZoa+v6ZoLa8xxtsT/uLQ/NJm0XVAWl/BvId4MlDeXJaeIZQ==", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.2.tgz", + "integrity": "sha512-ojlGK1Hsfce93J0+kn3H5R73elidKUaZonirN33GSmgTUMpzI/MIFfSpF3haANe3G1bEBS9/9/QEqwTzwqFsKw==", + "dependencies": { + "@babel/types": "^7.20.7" + } + }, + "node_modules/@types/bcrypt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/bcrypt/-/bcrypt-5.0.0.tgz", + "integrity": "sha512-agtcFKaruL8TmcvqbndlqHPSJgsolhf/qPWchFlgnW1gECTN/nKbFcoFnvKAQRFfKbh+BO6A3SWdJu9t+xF3Lw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.3", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.3.tgz", + "integrity": "sha512-oyl4jvAfTGX9Bt6Or4H9ni1Z447/tQuxnZsytsCaExKlmJiU8sFgnIBRzJUpKwB5eWn9HuBYlUlVA74q/yN0eQ==", + "dev": true, + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.36", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.36.tgz", + "integrity": "sha512-P63Zd/JUGq+PdrM1lv0Wv5SBYeA2+CORvbrXbngriYY0jzLUWfQMQQxOhjONEz/wlHOAxOdY7CY65rgQdTjq2w==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/cookie-parser": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/@types/cookie-parser/-/cookie-parser-1.4.4.tgz", + "integrity": "sha512-Var+aj5I6ZgIqsQ05N2V8q5OBrFfZXtIGWWDSrEYLIbMw758obagSwdGcLCjwh1Ga7M7+wj0SDIAaAC/WT7aaA==", + "dev": true, + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/express": { + "version": "4.17.18", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.18.tgz", + "integrity": "sha512-Sxv8BSLLgsBYmcnGdGjjEjqET2U+AKAdCRODmMiq02FgjwuV75Ut85DRpvFjyw/Mk0vgUOliGRU0UUmuuZHByQ==", + "dev": true, + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.17.37", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.37.tgz", + "integrity": "sha512-ZohaCYTgGFcOP7u6aJOhY9uIZQgZ2vxC2yWoArY+FeDXlqeH66ZVBjgvg+RLVAS/DWNq4Ap9ZXu1+SUQiiWYMg==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/graceful-fs": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.7.tgz", + "integrity": "sha512-MhzcwU8aUygZroVwL2jeYk6JisJrPl/oov/gsgGCue9mkgl9wjGbzReYQClxiUgFDnib9FuHqTndccKeZKxTRw==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/http-errors": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.2.tgz", + "integrity": "sha512-lPG6KlZs88gef6aD85z3HNkztpj7w2R7HmR3gygjfXCQmsLloWNARFkMuzKiiY8FGdh1XDpgBdrSf4aKDiA7Kg==", + "dev": true + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", + "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==" + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-gPQuzaPR5h/djlAv2apEG1HVOyj1IUs7GpfMZixU0/0KXT3pm64ylHuMUI1/Akh+sq/iikxg6Z2j+fcMDXaaTQ==", + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.2.tgz", + "integrity": "sha512-kv43F9eb3Lhj+lr/Hn6OcLCs/sSM8bt+fIaP11rCYngfV6NVjzWXJ17owQtDQTL9tQ8WSLUrGsSJ6rJz0F1w1A==", + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/jest": { + "version": "29.5.5", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.5.tgz", + "integrity": "sha512-ebylz2hnsWR9mYvmBFbXJXr+33UPc4+ZdxyDXh5w0FlPBTfCVN3wPL+kuOiQt3xvrK419v7XWeAs+AeOksafXg==", + "dev": true, + "dependencies": { + "expect": "^29.0.0", + "pretty-format": "^29.0.0" + } + }, + "node_modules/@types/jsonwebtoken": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.3.tgz", + "integrity": "sha512-b0jGiOgHtZ2jqdPgPnP6WLCXZk1T8p06A/vPGzUvxpFGgKMbjXJDjC5m52ErqBnIuWZFgGoIJyRdeG5AyreJjA==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/mime": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", + "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", + "dev": true + }, + "node_modules/@types/morgan": { + "version": "1.9.6", + "resolved": "https://registry.npmjs.org/@types/morgan/-/morgan-1.9.6.tgz", + "integrity": "sha512-xfKogz5WcKww2DAiVT9zxMgrqQt+Shq8tDVeLT+otoj6dJnkRkyJxMF51mHtUc3JCPKGk5x1EBU0buuGpfftlQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/node": { + "version": "20.7.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.7.0.tgz", + "integrity": "sha512-zI22/pJW2wUZOVyguFaUL1HABdmSVxpXrzIqkjsHmyUjNhPoWM1CKfvVuXfetHhIok4RY573cqS0mZ1SJEnoTg==" + }, + "node_modules/@types/qs": { + "version": "6.9.8", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.8.tgz", + "integrity": "sha512-u95svzDlTysU5xecFNTgfFG5RUWu1A9P0VzgpcIiGZA9iraHOdSzcxMxQ55DyeRaGCSxQi7LxXDI4rzq/MYfdg==", + "dev": true + }, + "node_modules/@types/range-parser": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", + "dev": true + }, + "node_modules/@types/send": { + "version": "0.17.2", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.2.tgz", + "integrity": "sha512-aAG6yRf6r0wQ29bkS+x97BIs64ZLxeE/ARwyS6wrldMm3C1MdKwCcnnEwMC1slI8wuxJOpiUH9MioC0A0i+GJw==", + "dev": true, + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.3.tgz", + "integrity": "sha512-yVRvFsEMrv7s0lGhzrggJjNOSmZCdgCjw9xWrPr/kNNLp6FaDfMC1KaYl3TSJ0c58bECwNBMoQrZJ8hA8E1eFg==", + "dev": true, + "dependencies": { + "@types/http-errors": "*", + "@types/mime": "*", + "@types/node": "*" + } + }, + "node_modules/@types/stack-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==" + }, + "node_modules/@types/yargs": { + "version": "17.0.26", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.26.tgz", + "integrity": "sha512-Y3vDy2X6zw/ZCumcwLpdhM5L7jmyGpmBCTYMHDLqT2IKVMYRRLdv6ZakA+wxhra6Z/3bwhNbNl9bDGXaFU+6rw==", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.1.tgz", + "integrity": "sha512-axdPBuLuEJt0c4yI5OZssC19K2Mq1uKdrfZBzuxLvaztgqUtFYZUNw7lETExPYJR9jdEoIg4mb7RQKRQzOkeGQ==" + }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-2.7.0.tgz", + "integrity": "sha512-pXK8ez/pVjqFdAgBkF1YPVRacuLQ9EXBKaKWaeh58WNfMkCmZhOZzu+NtKSPD5PHmCCHheQ5cD29qM1K4QTxIg==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-globals": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-1.0.9.tgz", + "integrity": "sha512-j3/4pkfih8W4NK22gxVSXcEonTpAHOHh0hu5BoZrKcOsW/4oBPxTi4Yk3SAj+FhC1f3+bRTkXdm4019gw1vg9g==", + "dependencies": { + "acorn": "^2.1.0" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/agent-base/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/agent-base/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/align-text": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", + "integrity": "sha512-GrTZLRpmp6wIC2ztrWW9MjjTgSKccffgFagbNDOX95/dcjEcYZibYTeaOntySQLcdw1ztBoFkviiUvTMbb9MYg==", + "dependencies": { + "kind-of": "^3.0.2", + "longest": "^1.0.1", + "repeat-string": "^1.5.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==", + "engines": { + "node": ">=0.4.2" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==" + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/app-root-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-3.1.0.tgz", + "integrity": "sha512-biN3PwB2gUtjaYy/isrU3aNWI5w+fAfvHkSvCKeQGxhmYpwKFUxudR3Yya+KqVRHBmEDYh+/lTozYCFbmzX4nA==", + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/aproba": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" + }, + "node_modules/are-we-there-yet": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", + "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/are-we-there-yet/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, + "node_modules/asap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/asap/-/asap-1.0.0.tgz", + "integrity": "sha512-Ej9qjcXY+8Tuy1cNqiwNMwFRXOy9UwgTeMA8LxreodygIPV48lx8PU1ecFxb5ZeU1DpMKxiq6vGLTxcitWZPbA==" + }, + "node_modules/babel-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", + "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", + "dependencies": { + "@jest/transform": "^29.7.0", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.6.3", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-istanbul/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", + "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.5.tgz", + "integrity": "sha512-19hwUH5FKl49JEsvyTcoHakh6BE0wgXLLptIyKZ3PijHc/Ci521wygORCUCCred+E/twuqRyAkE02BAWPmsHOg==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.4.2", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.4.tgz", + "integrity": "sha512-9l//BZZsPR+5XjyJMPtZSK4jv0BsTO1zDac2GC6ygx9WLGlcsnRd1Co0B2zT5fF5Ic6BZy+9m3HNZ3QcOeDKfg==", + "dev": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.4.2", + "core-js-compat": "^3.32.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.2.tgz", + "integrity": "sha512-tAlOptU0Xj34V1Y2PNTL4Y0FOJMDB6bZmoW39FeCQIhigGLkqu3Fj6uiXpxIf6Ij274ENdYx64y6Au+ZKlb1IA==", + "dev": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.4.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/babel-preset-jest": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", + "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", + "dependencies": { + "babel-plugin-jest-hoist": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/basic-auth": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", + "dependencies": { + "safe-buffer": "5.1.2" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/basic-auth/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/bcrypt": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.1.1.tgz", + "integrity": "sha512-AGBHOG5hPYZ5Xl9KXzU5iKq9516yEmvCKDg3ecP5kX2aB6UqTeXZxk2ELnDgDm6BQSMlLt9rDB4LoSMx0rYwww==", + "hasInstallScript": true, + "dependencies": { + "@mapbox/node-pre-gyp": "^1.0.11", + "node-addon-api": "^5.0.0" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/bignumber.js": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.0.tgz", + "integrity": "sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A==", + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/body-parser": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/body-parser/node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz", + "integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001541", + "electron-to-chromium": "^1.4.535", + "node-releases": "^2.0.13", + "update-browserslist-db": "^1.0.13" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", + "integrity": "sha512-wzLkDa4K/mzI1OSITC+DUyjgIl/ETNHE9QvYgy6J6Jvqyyz4C0Xfd+lQhb19sX2jMpZV4IssUn0VDVmglV+s4g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001546", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001546.tgz", + "integrity": "sha512-zvtSJwuQFpewSyRrI3AsftF6rM0X80mZkChIt1spBGEvRglCrjTniXvinc8JKRoqTwXAgvqTImaN9igfSMtUBw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/center-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", + "integrity": "sha512-Baz3aNe2gd2LP2qk5U+sDk/m4oSuwSDcBfayTCTBoWpfIGO5XFxPmjILQII4NGiZjD6DoDI6kf7gKaxkf7s3VQ==", + "dependencies": { + "align-text": "^0.1.3", + "lazy-cache": "^1.0.3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "engines": { + "node": ">=10" + } + }, + "node_modules/character-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-1.2.1.tgz", + "integrity": "sha512-6OEBVBlf/y8LaAphnbAnt743O3zMhlBer+FO5D40H6wqAdU9B1TvuApkejgLW0cvv0tEZNLktv1AnRI+C87ueQ==" + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } + }, + "node_modules/cjs-module-lexer": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz", + "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==" + }, + "node_modules/clean-css": { + "version": "3.4.28", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-3.4.28.tgz", + "integrity": "sha512-aTWyttSdI2mYi07kWqHi24NUU9YlELFKGOAgFzZjDN1064DMAOy2FBuoyGmkKRlXkbpXd0EVHmiVkbKhKoirTw==", + "dependencies": { + "commander": "2.8.x", + "source-map": "0.4.x" + }, + "bin": { + "cleancss": "bin/cleancss" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/clean-css/node_modules/commander": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz", + "integrity": "sha512-+pJLBFVk+9ZZdlAOB5WuIElVPPth47hILFkmGym57aq8kwxsowvByvB0DHs1vQAhyMZzdcpTtF0VDKGkSDR4ZQ==", + "dependencies": { + "graceful-readlink": ">= 1.0.0" + }, + "engines": { + "node": ">= 0.6.x" + } + }, + "node_modules/cli-highlight": { + "version": "2.1.11", + "resolved": "https://registry.npmjs.org/cli-highlight/-/cli-highlight-2.1.11.tgz", + "integrity": "sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg==", + "dependencies": { + "chalk": "^4.0.0", + "highlight.js": "^10.7.1", + "mz": "^2.4.0", + "parse5": "^5.1.1", + "parse5-htmlparser2-tree-adapter": "^6.0.0", + "yargs": "^16.0.0" + }, + "bin": { + "highlight": "bin/highlight" + }, + "engines": { + "node": ">=8.0.0", + "npm": ">=5.0.0" + } + }, + "node_modules/cli-highlight/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/cli-highlight/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cli-highlight/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "engines": { + "node": ">=10" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", + "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==" + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "bin": { + "color-support": "bin.js" + } + }, + "node_modules/commander": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.6.0.tgz", + "integrity": "sha512-PhbTMT+ilDXZKqH8xbvuUY2ZEQNef0Q7DKxgoEKb4ccytsdvVVJmYqR0sGbi96nxU6oGrwEIQnclpK2NBZuQlg==", + "engines": { + "node": ">= 0.6.x" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/concurrently": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-8.2.1.tgz", + "integrity": "sha512-nVraf3aXOpIcNud5pB9M82p1tynmZkrSGQ1p6X/VY8cJ+2LMVqAgXsJxYYefACSHbTYlm92O1xuhdGTjwoEvbQ==", + "dev": true, + "dependencies": { + "chalk": "^4.1.2", + "date-fns": "^2.30.0", + "lodash": "^4.17.21", + "rxjs": "^7.8.1", + "shell-quote": "^1.8.1", + "spawn-command": "0.0.2", + "supports-color": "^8.1.1", + "tree-kill": "^1.2.2", + "yargs": "^17.7.2" + }, + "bin": { + "conc": "dist/bin/concurrently.js", + "concurrently": "dist/bin/concurrently.js" + }, + "engines": { + "node": "^14.13.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/open-cli-tools/concurrently?sponsor=1" + } + }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==" + }, + "node_modules/constantinople": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-3.0.2.tgz", + "integrity": "sha512-UnEggAQrmhxuTxlb7n1OsTtagNXWUv2CRlOogZhWOU4jLK4EJEbF8UDSNxuGu+jVtWNtO2j51ab2H1wlBIzF/w==", + "deprecated": "Please update to at least constantinople 3.1.1", + "dependencies": { + "acorn": "^2.1.0" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" + }, + "node_modules/cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-parser": { + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.6.tgz", + "integrity": "sha512-z3IzaNjdwUC2olLIB5/ITd0/setiaFMLYiZJle7xg5Fe9KWAceil7xszYfHHBtDFYLSgJduS2Ty0P1uJdPDJeA==", + "dependencies": { + "cookie": "0.4.1", + "cookie-signature": "1.0.6" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, + "node_modules/core-js-compat": { + "version": "3.33.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.33.0.tgz", + "integrity": "sha512-0w4LcLXsVEuNkIqwjjf9rjCoPhK8uqA4tMRh4Ge26vfLtUutshn+aRJU21I9LCJlh2QQHfisNToLjw1XEJLTWw==", + "dev": true, + "dependencies": { + "browserslist": "^4.22.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "node_modules/create-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", + "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "prompts": "^2.0.1" + }, + "bin": { + "create-jest": "bin/create-jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/css/-/css-1.0.8.tgz", + "integrity": "sha512-qmTYWhHk910nQWnGqMAiWWPQlB6tESiWgNebQJmiozOAGcBAQ1+U/UzUOkhdrcshlkSRRiKWodwmVvO0OmnIGg==", + "dependencies": { + "css-parse": "1.0.4", + "css-stringify": "1.0.5" + } + }, + "node_modules/css-parse": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-1.0.4.tgz", + "integrity": "sha512-pfstzKVRZiHprDXdsmtfH1HYUEw22lzjuHdnpe1hscwoQvgW2C5zDQIBE0RKoALEReTn9W1ECdY8uaT/kO4VfA==" + }, + "node_modules/css-stringify": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/css-stringify/-/css-stringify-1.0.5.tgz", + "integrity": "sha512-aIThpcErhG5EyHorGqNlTh0TduNBqLrrXLO3x5rku3ZKBxuVfY+T7noyM2G2X/01iQANqJUb6d3+FLoa+N7Xwg==" + }, + "node_modules/date-fns": { + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", + "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", + "dependencies": { + "@babel/runtime": "^7.21.0" + }, + "engines": { + "node": ">=0.11" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/date-fns" + } + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/dedent": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.1.tgz", + "integrity": "sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==", + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==" + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-libc": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz", + "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/dotenv": { + "version": "16.3.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", + "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/motdotla/dotenv?sponsor=1" + } + }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "node_modules/electron-to-chromium": { + "version": "1.4.543", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.543.tgz", + "integrity": "sha512-t2ZP4AcGE0iKCCQCBx/K2426crYdxD3YU6l0uK2EO3FZH0pbC4pFz/sZm2ruZsND6hQBTcDWWlo/MLpiOdif5g==" + }, + "node_modules/email-validator": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/email-validator/-/email-validator-2.0.4.tgz", + "integrity": "sha512-gYCwo7kh5S3IDyZPLZf6hSS0MnZT8QmJFqYvbqlDZSbwdZlY6QZWxJ4i/6UhITOJ4XzyI647Bm2MXKCLqnJ4nQ==", + "engines": { + "node": ">4.0" + } + }, + "node_modules/emittery": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", + "dependencies": { + "@jest/expect-utils": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/express": { + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.1", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express/node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express/node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/express/node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "node_modules/fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "node_modules/gauge": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", + "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.2", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.1", + "object-assign": "^4.1.1", + "signal-exit": "^3.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", + "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + }, + "node_modules/graceful-readlink": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", + "integrity": "sha512-8tLu60LgxF6XpdbK8OW3FA+IfTNBn1ZHGHKF4KQbEeSkajYw5PlYJcKluntgegDPTg8UkHjpet1T82vk6TQ68w==" + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" + }, + "node_modules/highlight.js": { + "version": "10.7.3", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", + "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", + "engines": { + "node": "*" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" + }, + "node_modules/http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/http-errors/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/http-errors/node_modules/setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" + }, + "node_modules/http-errors/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/https-proxy-agent/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/https-proxy-agent/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", + "dev": true + }, + "node_modules/import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "node_modules/is-core-module": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", + "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==", + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-promise": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==" + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.1.tgz", + "integrity": "sha512-EAMEJBsYuyyztxMxW3g7ugGPkrZsV57v0Hmv3mm1uQsmB+QnZuepg731CRaIgeUVSdmsTngOkSnauNF8p7FIhA==", + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report/node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/istanbul-lib-report/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" }, "engines": { - "node": ">=10" + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "node_modules/istanbul-lib-source-maps/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/istanbul-lib-source-maps/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "engines": { - "node": "6.* || 8.* || >= 10.*" + "node": ">=0.10.0" } }, - "node_modules/get-intrinsic": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", - "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", + "node_modules/istanbul-reports": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", + "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3" + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=8" } }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "node_modules/jade": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/jade/-/jade-1.11.0.tgz", + "integrity": "sha512-J76sbGKeLtu7uwW97Ntzb1UvGnpKTDplYa9ROr2gNRhM+SxvlBSG0Ees3TQ8+7ya2UVkzMEeFxhRhEpN68s7Tg==", + "deprecated": "Jade has been renamed to pug, please install the latest version of pug instead of jade", "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" + "character-parser": "1.2.1", + "clean-css": "^3.1.9", + "commander": "~2.6.0", + "constantinople": "~3.0.1", + "jstransformer": "0.0.2", + "mkdirp": "~0.5.0", + "transformers": "2.1.0", + "uglify-js": "^2.4.19", + "void-elements": "~2.0.1", + "with": "~4.0.0" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "bin": { + "jade": "bin/jade.js" } }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, + "node_modules/jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", + "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", "dependencies": { - "is-glob": "^4.0.1" + "@jest/core": "^29.7.0", + "@jest/types": "^29.6.3", + "import-local": "^3.0.2", + "jest-cli": "^29.7.0" + }, + "bin": { + "jest": "bin/jest.js" }, "engines": { - "node": ">= 6" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "node_modules/graceful-readlink": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", - "integrity": "sha512-8tLu60LgxF6XpdbK8OW3FA+IfTNBn1ZHGHKF4KQbEeSkajYw5PlYJcKluntgegDPTg8UkHjpet1T82vk6TQ68w==" - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "node_modules/jest-changed-files": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz", + "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==", "dependencies": { - "function-bind": "^1.1.1" + "execa": "^5.0.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0" }, "engines": { - "node": ">= 0.4.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/jest-circus": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", + "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^1.0.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^29.7.0", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0", + "pretty-format": "^29.7.0", + "pure-rand": "^6.0.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-cli": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", + "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", + "dependencies": { + "@jest/core": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "create-jest": "^29.7.0", + "exit": "^0.1.2", + "import-local": "^3.0.2", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "yargs": "^17.3.1" + }, + "bin": { + "jest": "bin/jest.js" + }, "engines": { - "node": ">=8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "node_modules/has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", - "engines": { - "node": ">= 0.4" + "node_modules/jest-config": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", + "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-jest": "^29.7.0", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "peerDependencies": { + "@types/node": "*", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "ts-node": { + "optional": true + } } }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "engines": { - "node": ">= 0.4" + "node_modules/jest-diff": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", + "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" - }, - "node_modules/highlight.js": { - "version": "10.7.3", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", - "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", + "node_modules/jest-docblock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", + "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", + "dependencies": { + "detect-newline": "^3.0.0" + }, "engines": { - "node": "*" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "node_modules/jest-each": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz", + "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "jest-util": "^29.7.0", + "pretty-format": "^29.7.0" }, "engines": { - "node": ">= 0.6" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/http-errors/node_modules/depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "node_modules/jest-environment-node": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", + "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, "engines": { - "node": ">= 0.6" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/http-errors/node_modules/setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" - }, - "node_modules/http-errors/node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "node_modules/jest-get-type": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", "engines": { - "node": ">= 0.6" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "node_modules/jest-haste-map": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", "dependencies": { - "agent-base": "6", - "debug": "4" + "@jest/types": "^29.6.3", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" }, "engines": { - "node": ">= 6" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" } }, - "node_modules/https-proxy-agent/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "node_modules/jest-leak-detector": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", + "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", "dependencies": { - "ms": "2.1.2" + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" }, "engines": { - "node": ">=6.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", + "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/https-proxy-agent/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "node_modules/jest-message-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", + "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.6.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "node_modules/jest-mock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", + "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-util": "^29.7.0" }, "engines": { - "node": ">=0.10.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" + "node_modules/jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true } - ] - }, - "node_modules/ignore-by-default": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", - "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", - "dev": true - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" } }, - "node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" + "node_modules/jest-regex-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", + "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", + "dependencies": { + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "resolve": "^1.20.0", + "resolve.exports": "^2.0.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "node_modules/jest-resolve-dependencies": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", + "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", + "dependencies": { + "jest-regex-util": "^29.6.3", + "jest-snapshot": "^29.7.0" + }, "engines": { - "node": ">= 0.10" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, + "node_modules/jest-runner": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", + "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", "dependencies": { - "binary-extensions": "^2.0.0" + "@jest/console": "^29.7.0", + "@jest/environment": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-leak-detector": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-resolve": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-util": "^29.7.0", + "jest-watcher": "^29.7.0", + "jest-worker": "^29.7.0", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runtime": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", + "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/globals": "^29.7.0", + "@jest/source-map": "^29.6.3", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", + "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", + "dependencies": { + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "natural-compare": "^1.4.0", + "pretty-format": "^29.7.0", + "semver": "^7.5.3" }, "engines": { - "node": ">=8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + "node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, + "node_modules/jest-validate": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", + "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", + "dependencies": { + "@jest/types": "^29.6.3", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "leven": "^3.1.0", + "pretty-format": "^29.7.0" + }, "engines": { - "node": ">=0.10.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, + "node_modules/jest-watcher": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", + "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", "dependencies": { - "is-extglob": "^2.1.1" + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "jest-util": "^29.7.0", + "string-length": "^4.0.1" }, "engines": { - "node": ">=0.10.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, + "node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "dependencies": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, "engines": { - "node": ">=0.12.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/is-promise": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", - "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==" - }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, - "node_modules/jade": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/jade/-/jade-1.11.0.tgz", - "integrity": "sha512-J76sbGKeLtu7uwW97Ntzb1UvGnpKTDplYa9ROr2gNRhM+SxvlBSG0Ees3TQ8+7ya2UVkzMEeFxhRhEpN68s7Tg==", - "deprecated": "Jade has been renamed to pug, please install the latest version of pug instead of jade", + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dependencies": { - "character-parser": "1.2.1", - "clean-css": "^3.1.9", - "commander": "~2.6.0", - "constantinople": "~3.0.1", - "jstransformer": "0.0.2", - "mkdirp": "~0.5.0", - "transformers": "2.1.0", - "uglify-js": "^2.4.19", - "void-elements": "~2.0.1", - "with": "~4.0.0" + "argparse": "^1.0.7", + "esprima": "^4.0.0" }, "bin": { - "jade": "bin/jade.js" + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" } }, "node_modules/jsonwebtoken": { @@ -1578,6 +5219,14 @@ "node": ">=0.10.0" } }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "engines": { + "node": ">=6" + } + }, "node_modules/lazy-cache": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", @@ -1586,12 +5235,42 @@ "node": ">=0.10.0" } }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "dev": true + }, "node_modules/lodash.includes": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", @@ -1668,6 +5347,14 @@ "semver": "bin/semver.js" } }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dependencies": { + "tmpl": "1.0.5" + } + }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -1681,6 +5368,11 @@ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + }, "node_modules/methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", @@ -1689,6 +5381,18 @@ "node": ">= 0.6" } }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, "node_modules/mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", @@ -1719,6 +5423,14 @@ "node": ">= 0.6" } }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "engines": { + "node": ">=6" + } + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -1840,6 +5552,11 @@ "thenify-all": "^1.0.0" } }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" + }, "node_modules/negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", @@ -1872,6 +5589,16 @@ } } }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==" + }, + "node_modules/node-releases": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", + "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==" + }, "node_modules/nodemon": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.0.1.tgz", @@ -1954,11 +5681,21 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, "engines": { "node": ">=0.10.0" } }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/npmlog": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", @@ -2013,6 +5750,20 @@ "wrappy": "1" } }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/optimist": { "version": "0.3.7", "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.3.7.tgz", @@ -2021,6 +5772,70 @@ "wordwrap": "~0.0.2" } }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-locate/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/parse5": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", @@ -2047,6 +5862,14 @@ "node": ">= 0.8" } }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "engines": { + "node": ">=8" + } + }, "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", @@ -2055,21 +5878,81 @@ "node": ">=0.10.0" } }, - "node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "engines": { - "node": ">=8.6" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/process-nextick-args": { @@ -2085,6 +5968,18 @@ "asap": "~1.0.0" } }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -2103,6 +5998,21 @@ "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", "dev": true }, + "node_modules/pure-rand": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.4.tgz", + "integrity": "sha512-LA0Y9kxMYv47GIPJy6MI84fqTd2HmYZI83W/kM/SkKfDlajnZYfmXFTxkbY+xSBPkLJxltMa9hIkmdc29eguMA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ] + }, "node_modules/qs": { "version": "6.11.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", @@ -2159,6 +6069,11 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, + "node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + }, "node_modules/readable-stream": { "version": "2.3.7", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", @@ -2195,11 +6110,76 @@ "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "dev": true + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", + "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", + "dev": true, + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/regenerator-runtime": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==" }, + "node_modules/regenerator-transform": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", + "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.8.4" + } + }, + "node_modules/regexpu-core": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", + "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", + "dev": true, + "dependencies": { + "@babel/regjsgen": "^0.8.0", + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.1.0", + "regjsparser": "^0.9.1", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regjsparser": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", + "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", + "dev": true, + "dependencies": { + "jsesc": "~0.5.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + } + }, "node_modules/repeat-string": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", @@ -2216,6 +6196,49 @@ "node": ">=0.10.0" } }, + "node_modules/resolve": { + "version": "1.22.6", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.6.tgz", + "integrity": "sha512-njhxM7mV12JfufShqGy3Rz8j11RPdLy4xi15UurGJeoHLfJpVXKdh3ueuOqbYUcDZnffr6X739JBo5LzyahEsw==", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve.exports": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", + "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", + "engines": { + "node": ">=10" + } + }, "node_modules/right-align": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", @@ -2372,6 +6395,25 @@ "sha.js": "bin.js" } }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "engines": { + "node": ">=8" + } + }, "node_modules/shell-quote": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", @@ -2411,6 +6453,19 @@ "node": ">=10" } }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "engines": { + "node": ">=8" + } + }, "node_modules/source-map": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", @@ -2422,12 +6477,34 @@ "node": ">=0.8.0" } }, + "node_modules/source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/spawn-command": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2.tgz", "integrity": "sha512-zC8zGoGkmc8J9ndvml8Xksr1Amk9qBujgbF0JAIWO7kXr43w0h/0GJNM/Vustixu+YE8N/MTrQ7N31FvHUACxQ==", "dev": true }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" + }, "node_modules/sqlstring": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz", @@ -2436,6 +6513,17 @@ "node": ">= 0.6" } }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", @@ -2457,6 +6545,18 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, + "node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -2481,11 +6581,37 @@ "node": ">=8" } }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -2496,6 +6622,17 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/tar": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.0.tgz", @@ -2523,6 +6660,19 @@ "node": ">=10" } }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/thenify": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", @@ -2542,11 +6692,23 @@ "node": ">=0.8" } }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==" + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "engines": { + "node": ">=4" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, "dependencies": { "is-number": "^7.0.0" }, @@ -2658,6 +6820,25 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -2926,6 +7107,46 @@ "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", "dev": true }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", + "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dev": true, + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", + "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -2934,6 +7155,35 @@ "node": ">= 0.8" } }, + "node_modules/update-browserslist-db": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -2959,6 +7209,19 @@ "uuid": "dist/bin/uuid" } }, + "node_modules/v8-to-istanbul": { + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.3.tgz", + "integrity": "sha512-9lDD+EVI2fjFsMWXc6dy5JJzBsVTcQ2fVkfBvncZ6xJWG9wtBhOldG+mHkSL0+V1K/xgZz0JDO5UT5hFwHUghg==", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^2.0.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -2975,6 +7238,14 @@ "node": ">=0.10.0" } }, + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dependencies": { + "makeerror": "1.0.12" + } + }, "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", @@ -2989,6 +7260,20 @@ "webidl-conversions": "^3.0.0" } }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/wide-align": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", @@ -3054,6 +7339,18 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, + "node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -3091,6 +7388,17 @@ "engines": { "node": ">=12" } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } } } diff --git a/package.json b/package.json index 1af46bbd..542e3c0c 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,8 @@ "start": "node ./bin/www", "build-tsc": "tsc -w", "run-watch": "nodemon ./dist/app.js", - "dev": "concurrently \"npm:build-tsc\" \"npm:run-watch\"" + "dev": "concurrently \"npm:build-tsc\" \"npm:run-watch\"", + "test": "tsc && jest" }, "dependencies": { "bcrypt": "^5.1.1", @@ -20,6 +21,7 @@ "express": "^4.18.2", "http-errors": "~1.6.3", "jade": "~1.11.0", + "jest": "^29.7.0", "jsonwebtoken": "^9.0.2", "morgan": "^1.10.0", "mysql": "^2.18.1", @@ -27,9 +29,11 @@ "typescript": "^5.2.2" }, "devDependencies": { + "@babel/preset-env": "^7.22.20", "@types/bcrypt": "^5.0.0", "@types/cookie-parser": "^1.4.4", "@types/express": "^4.17.17", + "@types/jest": "^29.5.5", "@types/jsonwebtoken": "^9.0.2", "@types/morgan": "^1.9.6", "@types/node": "^20.5.6", diff --git a/src/db/dataSource.ts b/src/db/dataSource.ts index 8cebbb57..f49020e8 100644 --- a/src/db/dataSource.ts +++ b/src/db/dataSource.ts @@ -22,4 +22,11 @@ const dataSource = new DataSource({ logging: false }); +export const initDB = async () => + await dataSource.initialize().then(() => { + console.log("Connected to DB!"); + }).catch(err => { + console.log('Failed to connect to DB: ' + err) + }); + export default dataSource; \ No newline at end of file From cfcf88bcb5c8cda27fdd5360874e74bc241029ed Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Fri, 6 Oct 2023 18:12:26 +0300 Subject: [PATCH 057/146] added new attribute to calculate the number of volunteer which particibated in each voluntary work --- app.ts | 2 +- src/controllers/voluntaryWork.ts | 24 +++++++++++++++--------- src/routes/voluntaryWork.ts | 8 ++++---- types/voluntaryWork.ts | 2 ++ 4 files changed, 22 insertions(+), 14 deletions(-) diff --git a/app.ts b/app.ts index d5f3d553..39e3ebb2 100644 --- a/app.ts +++ b/app.ts @@ -26,7 +26,7 @@ app.use(cookieParser()); app.use('/', indexRouter); app.use('/permission', authenticate, permissionRouter); app.use('/role', authenticate, roleRouter); -app.use('/voluntaryWork', authenticate, voluntaryWorkRouter); +app.use('/voluntaryWork', voluntaryWorkRouter); app.use('/organizationAdmin', authenticate, organizationAdminRouter); app.use('/organizationProfile', authenticate, organizationProfileRouter); app.use("/volunteer",volunteerRouter ); diff --git a/src/controllers/voluntaryWork.ts b/src/controllers/voluntaryWork.ts index 6d1f21ab..7e2692a4 100644 --- a/src/controllers/voluntaryWork.ts +++ b/src/controllers/voluntaryWork.ts @@ -12,8 +12,8 @@ const createVoluntaryWork = async (payload: NSVoluntaryWork.Item) => { where: { id: In(payload.skillTagIds) }, }); newVoluntaryWork.skillTags = skillTags; - newVoluntaryWork.feedback=[]; - newVoluntaryWork.images=[]; + newVoluntaryWork.feedback = []; + newVoluntaryWork.images = []; return newVoluntaryWork.save(); } @@ -99,6 +99,9 @@ const getVoluntaryWorks = async (payload: NSVoluntaryWork.GetVoluntaryWorks) => if (payload.capacity) { conditions.push({ capacity: payload.capacity }); } + if (payload.creatorId) { + conditions.push({ creatorId: payload.creatorId }); + } if (payload.startedAfter) { const startedAfterDate = getDate(payload.startedAfter); @@ -135,14 +138,17 @@ const getVoluntaryWorks = async (payload: NSVoluntaryWork.GetVoluntaryWorks) => order: { createdAt: 'ASC' }, - relations: ['skillTags'] + relations: ['skillTags', 'volunteerProfiles'] }); return { page, pageSize: voluntaryWorks.length, total, - voluntaryWorks + voluntaryWorks: voluntaryWorks.map(voluntaryWork => ({ + ...voluntaryWork, + volunteerNumbers: voluntaryWork.volunteerProfiles.length, + })) }; } @@ -159,22 +165,22 @@ const putRating = async (id: number, rating: number) => { const putFeedback = async (id: number, feedback: string) => { let voluntaryWork = await VoluntaryWork.findOne({ where: { id } }); - if (voluntaryWork){ + if (voluntaryWork) { voluntaryWork.feedback.push(feedback); await voluntaryWork.save(); - }else{ + } else { throw "VoluntaryWork not found :("; } } const putImages = async (id: number, images: string[]) => { let voluntaryWork = await VoluntaryWork.findOne({ where: { id } }); - if (voluntaryWork){ + if (voluntaryWork) { voluntaryWork.images.push(...images); await voluntaryWork.save(); - }else{ + } else { throw "VoluntaryWork not found :("; } } -export { putImages,createVoluntaryWork, putFeedback,editVoluntaryWork, putRating, getVoluntaryWork, getVoluntaryWorks, deleteVoluntaryWork } \ No newline at end of file +export { putImages, createVoluntaryWork, putFeedback, editVoluntaryWork, putRating, getVoluntaryWork, getVoluntaryWorks, deleteVoluntaryWork } \ No newline at end of file diff --git a/src/routes/voluntaryWork.ts b/src/routes/voluntaryWork.ts index 79df940f..5eaddd3c 100644 --- a/src/routes/voluntaryWork.ts +++ b/src/routes/voluntaryWork.ts @@ -8,7 +8,7 @@ import { validateVoluntaryWork } from '../middleware/validation/voluntaryWork.js var router = express.Router(); router.post('/', authorize("POST_voluntaryWork"), validateVoluntaryWork, (req, res, next) => { - createVoluntaryWork(req.body).then(() => { + createVoluntaryWork({ ...req.body, creatorId: res.locals.volunteer.id || res.locals.organizationAdmin.id }).then(() => { res.status(201).send("Voluntary work created successfully!!") }).catch(err => { console.error(err); @@ -37,7 +37,7 @@ router.put("/:id", authorize("PUT_voluntaryWork"), checkCreator, async (req, res }); }); -router.get('/', authorize("GET_voluntaryWorks"), async (req, res, next) => { +router.get('/', async (req, res, next) => { const payload = { page: req.query.page?.toString() || '1', @@ -59,7 +59,7 @@ router.get('/', authorize("GET_voluntaryWorks"), async (req, res, next) => { startedBefore: "", ratingMore: Number(req.query.ratingMore) || 0, ratingLess: Number(req.query.ratingLess) || 0, - + creatorId: "" }; getVoluntaryWorks(payload) @@ -94,7 +94,7 @@ router.get('/analysis', authorize("GET_analysis"), async (req, res, next) => { startedBefore: req.query.startedBefore?.toString() || "", ratingMore: Number(req.query.ratingMore) || 0, ratingLess: Number(req.query.ratingLess) || 0, - + creatorId:req.query.creatorId?.toString() || "" }; getVoluntaryWorks(payload) diff --git a/types/voluntaryWork.ts b/types/voluntaryWork.ts index 909626e8..46af9de9 100644 --- a/types/voluntaryWork.ts +++ b/types/voluntaryWork.ts @@ -48,6 +48,7 @@ export namespace NSVoluntaryWork { startedBefore: string; ratingMore:number; ratingLess:number; + creatorId:string; } export interface Date { @@ -72,5 +73,6 @@ export namespace NSVoluntaryWork { finishedDate: string; capacity: number; skillTagIds: number[]; + creatorId:string; } } From f38fd05ea312b412140bfaedb45fbc3060761a36 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Fri, 6 Oct 2023 19:00:39 +0300 Subject: [PATCH 058/146] Creat functions to register in voluntary work by volunteer and by admin, the first will check if data is sutisfying, the other without, even if we want to register volunteer above the capacity --- app.ts | 2 +- src/controllers/voluntaryWork.ts | 59 ++++++++++++++++++++++++++++++-- src/routes/voluntaryWork.ts | 25 ++++++++++++-- 3 files changed, 79 insertions(+), 7 deletions(-) diff --git a/app.ts b/app.ts index ecb12469..d49228ff 100644 --- a/app.ts +++ b/app.ts @@ -26,7 +26,7 @@ app.use(cookieParser()); app.use('/', indexRouter); app.use('/permission', authenticate, permissionRouter); app.use('/role', authenticate, roleRouter); -app.use('/voluntaryWork', voluntaryWorkRouter); +app.use('/voluntaryWork', authenticate, voluntaryWorkRouter); app.use('/organizationAdmin', authenticate, organizationAdminRouter); app.use('/organizationProfile', authenticate, organizationProfileRouter); app.use("/volunteer",volunteerRouter ); diff --git a/src/controllers/voluntaryWork.ts b/src/controllers/voluntaryWork.ts index 7e2692a4..b1dae1ee 100644 --- a/src/controllers/voluntaryWork.ts +++ b/src/controllers/voluntaryWork.ts @@ -3,6 +3,7 @@ import { NSVoluntaryWork } from "../../types/voluntaryWork.js"; import { SkillTag } from "../db/entities/SkillTag.js"; import { VoluntaryWork } from "../db/entities/VoluntaryWork.js"; import { getDate } from "./index.js"; +import { Volunteer } from "../db/entities/Volunteer.js"; const createVoluntaryWork = async (payload: NSVoluntaryWork.Item) => { let payloadDate = { ...payload, startedDate: getDate(payload.startedDate), finishedDate: getDate(payload.finishedDate) }; @@ -65,10 +66,20 @@ const getVoluntaryWorks = async (payload: NSVoluntaryWork.GetVoluntaryWorks) => const conditions = []; if (payload.id) { - return VoluntaryWork.findOne({ where: { id: payload.id } }) + const voluntaryWork = await VoluntaryWork.findOne({ where: { id: payload.id }, relations: ['skillTags', 'volunteerProfiles'] }) + return { + ...voluntaryWork, + volunteerNumbers: voluntaryWork?.volunteerProfiles.length + } + + } if (payload.name) { - return VoluntaryWork.findOne({ where: { name: payload.name } }) + const voluntaryWork = await VoluntaryWork.findOne({ where: { name: payload.name }, relations: ['skillTags', 'volunteerProfiles'] }) + return { + ...voluntaryWork, + volunteerNumbers: voluntaryWork?.volunteerProfiles.length + } } if (payload.time.length > 0) { conditions.push({ time: In(payload.time) }); @@ -183,4 +194,46 @@ const putImages = async (id: number, images: string[]) => { } } -export { putImages, createVoluntaryWork, putFeedback, editVoluntaryWork, putRating, getVoluntaryWork, getVoluntaryWorks, deleteVoluntaryWork } \ No newline at end of file +const registerByVolunteer = async (workId: number, volunteerProfile: Volunteer["volunteerProfile"]) => { + const voluntaryWork = await VoluntaryWork.findOne({ where: { id: workId } }); + if (!voluntaryWork) { + throw new Error("VoluntaryWork not found"); + } + + if ( + volunteerProfile.availableLocation !== voluntaryWork.location || + !volunteerProfile.availableDays.every(day => voluntaryWork.days.includes(day)) || + !volunteerProfile.availableTime.every(time => voluntaryWork.time.includes(time)) || + !volunteerProfile.skillTags.every(skillTag => voluntaryWork.skillTags.some(workSkill => workSkill.id === skillTag.id)) + ) { + throw new Error("Volunteer's profile information does not align with the VoluntaryWork information"); + } + + if (voluntaryWork.volunteerProfiles.length >= voluntaryWork.capacity) { + throw new Error("VoluntaryWork is already at full capacity"); + } + + voluntaryWork.volunteerProfiles.push(volunteerProfile); + await voluntaryWork.save(); + + return "Registration successful!"; +} + +const registerByOrganizationAdmin = async (workId: number, volunteerId: string) => { + const voluntaryWork = await VoluntaryWork.findOne({ where: { id: workId } }); + const volunteer = await Volunteer.findOne({where:{id:volunteerId}}); + + if (!voluntaryWork) { + throw new Error("VoluntaryWork not found"); + } + if(!volunteer){ + throw new Error("Volunteer not found"); + } + + voluntaryWork.volunteerProfiles.push(volunteer.volunteerProfile); + await voluntaryWork.save(); + + return "Registration successful!"; +} + +export { registerByOrganizationAdmin, registerByVolunteer, putImages, createVoluntaryWork, putFeedback, editVoluntaryWork, putRating, getVoluntaryWork, getVoluntaryWorks, deleteVoluntaryWork } \ No newline at end of file diff --git a/src/routes/voluntaryWork.ts b/src/routes/voluntaryWork.ts index 5eaddd3c..c0e30de1 100644 --- a/src/routes/voluntaryWork.ts +++ b/src/routes/voluntaryWork.ts @@ -1,5 +1,5 @@ import express from 'express'; -import { createVoluntaryWork, deleteVoluntaryWork, editVoluntaryWork, getVoluntaryWork, getVoluntaryWorks, putFeedback, putImages, putRating } from '../controllers/voluntaryWork.js'; +import { createVoluntaryWork, deleteVoluntaryWork, editVoluntaryWork, getVoluntaryWork, getVoluntaryWorks, putFeedback, putImages, putRating, registerByOrganizationAdmin, registerByVolunteer } from '../controllers/voluntaryWork.js'; import { NSVolunteer } from '../../types/volunteer.js'; import { NSVoluntaryWork } from '../../types/voluntaryWork.js'; import { authorize, checkCreator, checkParticipation } from '../middleware/auth/authorize.js'; @@ -37,7 +37,7 @@ router.put("/:id", authorize("PUT_voluntaryWork"), checkCreator, async (req, res }); }); -router.get('/', async (req, res, next) => { +router.get('/', authorize("GET_voluntaryWorks"), async (req, res, next) => { const payload = { page: req.query.page?.toString() || '1', @@ -94,7 +94,7 @@ router.get('/analysis', authorize("GET_analysis"), async (req, res, next) => { startedBefore: req.query.startedBefore?.toString() || "", ratingMore: Number(req.query.ratingMore) || 0, ratingLess: Number(req.query.ratingLess) || 0, - creatorId:req.query.creatorId?.toString() || "" + creatorId: req.query.creatorId?.toString() || "" }; getVoluntaryWorks(payload) @@ -147,6 +147,25 @@ router.put("/images/:id", authorize("PUT_images"), async (req, res, next) => { }); router.put("/register/:id", authorize("REGISTER_voluntaryWork"), async (req, res, next) => { + if (res.locals.volunteer) { + registerByVolunteer(Number(req.params.id), res.locals.volunteer["volunteerProfile"]).then(() => { + res.status(201).send("Rating added successfully!!") + }).catch(err => { + console.error(err); + res.status(500).send(err); + }); + } else if (res.locals.organizationAdmin) { + if (!req.body.volunteerId.toString()) { + throw "volunteer id is required!"; + } + + registerByOrganizationAdmin(Number(req.params.id), req.body.volunteerId.toString()).then(() => { + res.status(201).send("Rating added successfully!!") + }).catch(err => { + console.error(err); + res.status(500).send(err); + }); + } }); export default router; From d4289f41f9c0a38a200fa6060b8ddf45a0cd01af Mon Sep 17 00:00:00 2001 From: TarteelTamimi Date: Fri, 6 Oct 2023 19:56:28 +0300 Subject: [PATCH 059/146] volunteer controller --- src/controllers/volunteer.ts | 63 +++++++++++++++++++++++------------- types/volunteer.ts | 2 +- 2 files changed, 41 insertions(+), 24 deletions(-) diff --git a/src/controllers/volunteer.ts b/src/controllers/volunteer.ts index 7f613440..f4c39c6a 100644 --- a/src/controllers/volunteer.ts +++ b/src/controllers/volunteer.ts @@ -1,37 +1,54 @@ -// import { NSVolunteer } from "../../types/volunteer.js"; -// import dataSource from "../db/dataSource.js"; -// import { Volunteer } from "../db/entities/Volunteer.js"; -// import { VolunteerProfile } from "../db/entities/VolunteerProfile.js"; - -import { OrganizationAdmin } from "../db/entities/OrganizationAdmin.js"; +import { NSVolunteer } from "../../types/volunteer.js"; +import dataSource from "../db/dataSource.js"; import { Volunteer } from "../db/entities/Volunteer.js"; +import { VolunteerProfile } from "../db/entities/VolunteerProfile.js"; +import { OrganizationAdmin } from "../db/entities/OrganizationAdmin.js"; import jwt from 'jsonwebtoken'; +import bcrypt from 'bcrypt'; + + +const createVolunteer = async (payload: NSVolunteer.Item) => { + + return dataSource.manager.transaction(async (transaction) => { + // tags -// const createVolunteer = async (payload: NSVolunteer.Item) => { + const profile = VolunteerProfile.create({ + availableTime: payload.availableTime, + availableLocation: payload.availableLocation, + availableDays: payload.availableDays + }); + await transaction.save(profile); -// return dataSource.manager.transaction(async (transaction) => { + const newVolunteer = Volunteer.create(payload); -// const profile = VolunteerProfile.create({ -// availableTime: payload.availableTime + newVolunteer.volunteerProfile = profile; + await transaction.save(newVolunteer); + }); +}; -// }) +const deleteVolunteer = async (volunteerId: number) => { + return Volunteer.delete(volunteerId); +} -// await transaction.save(profile); +const editVolunteer = async (payload: { name: string, id: string, email: string, password: string }) => { + const volunteer = await Volunteer.findOne({ where: { id: payload.id } }); + if (volunteer) { + if(payload.name) + volunteer.name = payload.name; -// const newUser = User.create(payload); -// const roles = await Role.find({ where: { name: newUser?.type || 'user' } }) -// newUser.roles = roles; -// newUser.profile = profile; -// await transaction.save(newUser); -// }); + if(payload.email) + volunteer.email = payload.email; + if(payload.password) + volunteer.password = await bcrypt.hash(payload.password, 10); -// }; + return volunteer.save(); -// const deleteVolunteer = async (volunteerId: number) => { -// return Volunteer.delete(volunteerId); -// } + } else { + throw "Volunteer not found :("; + } +} const login = async (email: string, name: string, id: string) => { const volunteer = await Volunteer.findOne({ @@ -68,5 +85,5 @@ const login = async (email: string, name: string, id: string) => { } -export { login,/* createVolunteer, deleteVolunteer,*/ } +export { login, createVolunteer, deleteVolunteer, editVolunteer } diff --git a/types/volunteer.ts b/types/volunteer.ts index 4555c690..7de70d71 100644 --- a/types/volunteer.ts +++ b/types/volunteer.ts @@ -29,7 +29,7 @@ export namespace NSVolunteer { type: TypeVolunteer; availableTime: AvailableTime[]; availableLocation: string; - PreferredActivities: string[]; availableDays: AvailableDays[]; + skills: string[]; } } \ No newline at end of file From 7913488e4bfbdb6e5fdc8e9a2c4c6a9bc99c7753 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Fri, 6 Oct 2023 20:35:16 +0300 Subject: [PATCH 060/146] edit creat volunteer and add the controllers to routes --- src/controllers/volunteer.ts | 28 ++++++++++++------ src/db/entities/VolunteerProfile.ts | 3 -- src/middleware/validation/volunteer.ts | 38 ++++++++++++++----------- src/routes/volunteer.ts | 39 ++++++++++++++++++++++++-- 4 files changed, 77 insertions(+), 31 deletions(-) diff --git a/src/controllers/volunteer.ts b/src/controllers/volunteer.ts index f4c39c6a..cadb8add 100644 --- a/src/controllers/volunteer.ts +++ b/src/controllers/volunteer.ts @@ -5,18 +5,30 @@ import { VolunteerProfile } from "../db/entities/VolunteerProfile.js"; import { OrganizationAdmin } from "../db/entities/OrganizationAdmin.js"; import jwt from 'jsonwebtoken'; import bcrypt from 'bcrypt'; +import { SkillTag } from "../db/entities/SkillTag.js"; +import { In } from "typeorm"; const createVolunteer = async (payload: NSVolunteer.Item) => { return dataSource.manager.transaction(async (transaction) => { - // tags + const existingSkillTags = await SkillTag.find({ + where: { name: In(payload.skills) }, + }); + + const newSkillTags = await Promise.all( + payload.skills.map(async (skillName) => { + return existingSkillTags.find((tag) => tag.name === skillName) || + (await transaction.save(SkillTag.create({ name: skillName }))); + }) + ); const profile = VolunteerProfile.create({ availableTime: payload.availableTime, availableLocation: payload.availableLocation, - availableDays: payload.availableDays + availableDays: payload.availableDays, + skillTags: newSkillTags }); await transaction.save(profile); @@ -34,14 +46,14 @@ const deleteVolunteer = async (volunteerId: number) => { const editVolunteer = async (payload: { name: string, id: string, email: string, password: string }) => { const volunteer = await Volunteer.findOne({ where: { id: payload.id } }); if (volunteer) { - if(payload.name) - volunteer.name = payload.name; + if (payload.name) + volunteer.name = payload.name; - if(payload.email) - volunteer.email = payload.email; + if (payload.email) + volunteer.email = payload.email; - if(payload.password) - volunteer.password = await bcrypt.hash(payload.password, 10); + if (payload.password) + volunteer.password = await bcrypt.hash(payload.password, 10); return volunteer.save(); diff --git a/src/db/entities/VolunteerProfile.ts b/src/db/entities/VolunteerProfile.ts index e162027d..cab56275 100644 --- a/src/db/entities/VolunteerProfile.ts +++ b/src/db/entities/VolunteerProfile.ts @@ -24,9 +24,6 @@ export class VolunteerProfile extends BaseEntity { @Column({ nullable: false }) availableLocation: string; - @Column({ nullable: false, type:"json" }) - preferredActivities: string[]; - @ManyToMany(() => SkillTag) @JoinTable() skillTags: SkillTag[]; diff --git a/src/middleware/validation/volunteer.ts b/src/middleware/validation/volunteer.ts index 2f856c39..9ae6aa43 100644 --- a/src/middleware/validation/volunteer.ts +++ b/src/middleware/validation/volunteer.ts @@ -4,41 +4,45 @@ import { isValidPassword } from '../../controllers/index.js'; import { NSVolunteer } from '../../../types/volunteer.js'; -const validateVolunteer = (req: express.Request, - res: express.Response, - next: express.NextFunction -) => { - const values = ["name", "email", "password", "type","availableTime","availableLocation", "PreferredActivities", "availableDays" ]; +const validateVolunteer = (req: express.Request, res: express.Response, next: express.NextFunction) => { const volunteer = req.body; - const errorList = values.map(key => !volunteer[key] && `${key} is Required!`).filter(Boolean); + const errorList: string[] = []; + + const requiredFields = ["name", "email", "password", "type", "availableTime", "availableLocation", "availableDays", "skills"]; + requiredFields.forEach((field) => { + if (!volunteer[field]) { + errorList.push(`${field} is required.`); + } + }); if (!EmailValidator.validate(volunteer.email)) { - errorList.push('Email is not Valid'); + errorList.push('Email is not valid.'); } - - errorList.push(...isValidPassword(volunteer.password )); - const validType= volunteer.type.every((status: string) => Object.values(NSVolunteer.TypeVolunteer).includes(status as NSVolunteer.TypeVolunteer)); + const validType = Object.values(NSVolunteer.TypeVolunteer).includes(volunteer.type); if (!validType) { - errorList.push("Invalid status !"); + errorList.push("Invalid type!"); } - const validTime = volunteer.time.every((time: string) => Object.values(NSVolunteer.AvailableTime).includes(time as NSVolunteer.AvailableTime)); + const validTime = volunteer.availableTime.every((time: string) => Object.values(NSVolunteer.AvailableTime).includes(time as NSVolunteer.AvailableTime)); if (!validTime) { - errorList.push("Invalid time !"); + errorList.push("Invalid time!"); } - const validDays = volunteer.days.every((days: string) => Object.values(NSVolunteer.AvailableDays).includes(days as NSVolunteer.AvailableDays)); + const validDays = volunteer.availableDays.every((days: string) => Object.values(NSVolunteer.AvailableDays).includes(days as NSVolunteer.AvailableDays)); if (!validDays) { - errorList.push("Invalid days !"); + errorList.push("Invalid days!"); } + errorList.push(...isValidPassword(volunteer.password)); + if (errorList.length) { - res.status(400).send(errorList); + res.status(400).send({ errors: errorList }); } else { next(); } -} +}; + export { validateVolunteer diff --git a/src/routes/volunteer.ts b/src/routes/volunteer.ts index 52a7e5b9..57b2c4a9 100644 --- a/src/routes/volunteer.ts +++ b/src/routes/volunteer.ts @@ -2,12 +2,17 @@ import express from 'express'; import { authorize, checkMe } from '../middleware/auth/authorize.js'; import { authenticate } from '../middleware/auth/authenticate.js'; import { validateVolunteer } from '../middleware/validation/volunteer.js'; -import { login } from '../controllers/volunteer.js'; +import { createVolunteer, deleteVolunteer, editVolunteer, login } from '../controllers/volunteer.js'; var router = express.Router(); router.post('/register', validateVolunteer, (req, res, next) => { - // create volunteer + createVolunteer(req.body).then(() => { + res.status(201).send("Volunteer created successfully!!") + }).catch(err => { + console.error(err); + res.status(500).send(err); + }); }); router.post('/login', (req, res, next) => { @@ -34,15 +39,43 @@ router.post('/login', (req, res, next) => { }); router.delete('/:id', authenticate, authorize("DELETE_volunteer"), checkMe, async (req, res) => { + const id = Number(req.params.id?.toString()); + deleteVolunteer(id) + .then(data => { + res.send(data); + }) + .catch(error => { + console.error(error); + res.status(500).send('Something went wrong'); + }); }) router.put("/:id", authenticate, authorize("POST_volunteer"), checkMe, async (req, res, next) => { - + editVolunteer({ ...req.body, id: req.params.id?.toString() }).then(() => { + res.status(201).send("Volunteer edited successfully!!") + }).catch(err => { + console.error(err); + res.status(500).send(err); + }); }); router.get('/', authenticate, authorize("GET_volunteers"), async (req, res, next) => { + // const payload = { + // page: req.query.page?.toString() || '1', + // pageSize: req.query.pageSize?.toString() || '10', + // id: Number(req.query.id) || 0, + // name: req.query.name?.toString() as NSRole.Type + // }; + // getVoluneers(payload) + // .then(data => { + // res.send(data); + // }) + // .catch(error => { + // console.error(error); + // res.status(500).send('Something went wrong'); + // }); }); router.get("/logout", authenticate, (req, res, next) => { From 2eb15db605a8bd1a67a6e7ee311bc45fa50f13c1 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Fri, 6 Oct 2023 21:56:43 +0300 Subject: [PATCH 061/146] Creat get volunteers function and router --- src/controllers/volunteer.ts | 60 ++++++++++++++++++++++++++++++++++-- src/routes/volunteer.ts | 38 ++++++++++++++--------- 2 files changed, 81 insertions(+), 17 deletions(-) diff --git a/src/controllers/volunteer.ts b/src/controllers/volunteer.ts index cadb8add..7d4bb6f8 100644 --- a/src/controllers/volunteer.ts +++ b/src/controllers/volunteer.ts @@ -6,7 +6,7 @@ import { OrganizationAdmin } from "../db/entities/OrganizationAdmin.js"; import jwt from 'jsonwebtoken'; import bcrypt from 'bcrypt'; import { SkillTag } from "../db/entities/SkillTag.js"; -import { In } from "typeorm"; +import { In, Like } from "typeorm"; const createVolunteer = async (payload: NSVolunteer.Item) => { @@ -97,5 +97,61 @@ const login = async (email: string, name: string, id: string) => { } -export { login, createVolunteer, deleteVolunteer, editVolunteer } +const getVolunteers = async (payload: NSVolunteer.Item & { page: string; pageSize: string }) => { + const page = parseInt(payload.page); + const pageSize = parseInt(payload.pageSize); + const conditions: Record = {}; + + if (payload.id) { + conditions["id"] = payload.id; + } + if (payload.name) { + conditions["name"] = Like(`%${payload.name}%`); + } + if (payload.email) { + conditions["email"] = payload.email; + } + if (payload.availableTime.length > 0) { + conditions["availableTime"] = In(payload.availableTime); + } + if (payload.availableLocation) { + conditions["availableLocation"] = payload.availableLocation; + } + if (payload.type) { + conditions["type"] = payload.type; + } + if (payload.availableDays.length > 0) { + conditions["availableDays"] = In(payload.availableDays); + } + const [volunteers, total] = await Volunteer.findAndCount({ + where: conditions, + order: { + createdAt: 'ASC', + }, + relations: [ + "volunteerProfile.skillTags", + "volunteerProfile" + ], + }); + + const filteredVolunteers = volunteers.filter((volunteer) => { + if (payload.skills.length > 0) { + const hasMatchingSkill = volunteer.volunteerProfile.skillTags.some((skillTag) => payload.skills.includes(skillTag.name)); + return hasMatchingSkill; + } + return true; + }); + const startIndex = (page - 1) * pageSize; + const endIndex = startIndex + pageSize; + const paginatedVolunteers = filteredVolunteers.slice(startIndex, endIndex); + + return { + page, + pageSize: paginatedVolunteers.length, + total: filteredVolunteers.length, + volunteers: paginatedVolunteers, + }; +}; + +export { getVolunteers, login, createVolunteer, deleteVolunteer, editVolunteer } diff --git a/src/routes/volunteer.ts b/src/routes/volunteer.ts index 57b2c4a9..78fce29f 100644 --- a/src/routes/volunteer.ts +++ b/src/routes/volunteer.ts @@ -2,7 +2,8 @@ import express from 'express'; import { authorize, checkMe } from '../middleware/auth/authorize.js'; import { authenticate } from '../middleware/auth/authenticate.js'; import { validateVolunteer } from '../middleware/validation/volunteer.js'; -import { createVolunteer, deleteVolunteer, editVolunteer, login } from '../controllers/volunteer.js'; +import { createVolunteer, deleteVolunteer, editVolunteer, getVolunteers, login } from '../controllers/volunteer.js'; +import { NSVolunteer } from '../../types/volunteer.js'; var router = express.Router(); @@ -61,21 +62,28 @@ router.put("/:id", authenticate, authorize("POST_volunteer"), checkMe, async (re }); router.get('/', authenticate, authorize("GET_volunteers"), async (req, res, next) => { - // const payload = { - // page: req.query.page?.toString() || '1', - // pageSize: req.query.pageSize?.toString() || '10', - // id: Number(req.query.id) || 0, - // name: req.query.name?.toString() as NSRole.Type - // }; + const payload = { + page: req.query.page?.toString() || '1', + pageSize: req.query.pageSize?.toString() || '10', + id: req.query.id?.toString()|| "", + name: req.query.name?.toString() || "", + email: req.query.email?.toString() || "", + availableLocation: req.query.availableLocation?.toString() || "", + skills: ((Array.isArray(req.query.skills) ? req.query.skills : [req.query.skills]).filter(Boolean)) as string[], + type: req.query.status as NSVolunteer.TypeVolunteer, + availableDays: (Array.isArray(req.query.availableDays) ? req.query.availableDays : [req.query.availableDays]).filter(Boolean) as NSVolunteer.AvailableDays[], + availableTime: ((Array.isArray(req.query.availableTime) ? req.query.availableTime : [req.query.availableTime]).filter(Boolean)) as NSVolunteer.AvailableTime[], + password:"" + }; - // getVoluneers(payload) - // .then(data => { - // res.send(data); - // }) - // .catch(error => { - // console.error(error); - // res.status(500).send('Something went wrong'); - // }); + getVolunteers(payload) + .then(data => { + res.send(data); + }) + .catch(error => { + console.error(error); + res.status(500).send('Something went wrong'); + }); }); router.get("/logout", authenticate, (req, res, next) => { From 5d72857666455f613e742d9e6a9e88772ffba351 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Sat, 7 Oct 2023 07:36:49 +0300 Subject: [PATCH 062/146] Edit orgAdmin to change the password if the old password is correct --- src/controllers/organizationAdmin.ts | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/src/controllers/organizationAdmin.ts b/src/controllers/organizationAdmin.ts index d9745a30..189a8cf5 100644 --- a/src/controllers/organizationAdmin.ts +++ b/src/controllers/organizationAdmin.ts @@ -70,7 +70,7 @@ const deleteOrganizationAdmin = async (adminId: number) => { return OrganizationAdmin.delete(adminId); } -const editOrganizationAdmin = async (payload: { id: string, name: string, email: string, password: string, organizationName: string }) => { +const editOrganizationAdmin = async (payload: { id: string, name: string, email: string, newPassword: string, oldPassword: string, organizationName: string }) => { const admin = await OrganizationAdmin.findOne({ where: { id: payload.id } }); @@ -81,18 +81,27 @@ const editOrganizationAdmin = async (payload: { id: string, name: string, email: if (payload.email) admin.email = payload.email; - if (payload.password) { - admin.password = await bcrypt.hash(payload.password, 10); + if (payload.newPassword) { + if (!payload.oldPassword){ + throw "Old password is needed !"; + } - if (payload.organizationName) { + const passwordMatching = await bcrypt.compare(payload.oldPassword, admin?.password || ''); + if (passwordMatching){ + admin.password = await bcrypt.hash(payload.newPassword, 10); + }else{ + throw "The old password isn't correct !" + } + } + if (payload.organizationName) { - const profile = await OrganizationProfile.findOne({ where: { name: payload.organizationName } }); - if (profile) { - admin.orgProfile = profile; - } + const profile = await OrganizationProfile.findOne({ where: { name: payload.organizationName } }); + if (profile) { + admin.orgProfile = profile; } - return admin.save(); } + return admin.save(); + } else { throw "Organization admin not found :("; From 2510f0fb10423908fd83c90d24ef1d701bcc11d8 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Sat, 7 Oct 2023 07:53:00 +0300 Subject: [PATCH 063/146] Creat get orgProfile by admin name --- app.ts | 3 +-- src/controllers/OrganizationProfile .ts | 21 +++++++++------------ src/controllers/organizationAdmin.ts | 3 ++- src/routes/organizationAdmin.ts | 2 +- 4 files changed, 13 insertions(+), 16 deletions(-) diff --git a/app.ts b/app.ts index d49228ff..c5b5a929 100644 --- a/app.ts +++ b/app.ts @@ -27,7 +27,7 @@ app.use('/', indexRouter); app.use('/permission', authenticate, permissionRouter); app.use('/role', authenticate, roleRouter); app.use('/voluntaryWork', authenticate, voluntaryWorkRouter); -app.use('/organizationAdmin', authenticate, organizationAdminRouter); +app.use('/organizationAdmin',/* authenticate, */organizationAdminRouter); app.use('/organizationProfile', authenticate, organizationProfileRouter); app.use("/volunteer",volunteerRouter ); @@ -36,7 +36,6 @@ app.use(function (req, res, next) { next(createError(404)); }); - // error handler app.use(function (err: any, req: any, res: any, next: any) { // set locals, only providing error in development diff --git a/src/controllers/OrganizationProfile .ts b/src/controllers/OrganizationProfile .ts index f05120d6..c4cf8c13 100644 --- a/src/controllers/OrganizationProfile .ts +++ b/src/controllers/OrganizationProfile .ts @@ -1,4 +1,5 @@ import { NSOrganizationProfile } from "../../types/organizationProfile.js"; +import { OrganizationAdmin } from "../db/entities/OrganizationAdmin.js"; import { OrganizationProfile } from "../db/entities/OrganizationProfile.js"; const createOrganizationProfile = async (payload: NSOrganizationProfile.Item) => { @@ -42,19 +43,15 @@ const getOrganizationProfile = async (payload: { return OrganizationProfile.findOne({ where: { name: payload.name } }) } - // //get OrganizationProfile by organizationAdmin + if (payload.adminName) { + const admin = await OrganizationAdmin.findOne({ where: { name: payload.adminName } }); - // if (payload.adminName) { - // const admin = await OrganizationAdmin.findOne({ where: { name: payload.name } }); - - // if (admin) { - - // return await OrganizationProfile.findOne({ where: { orgProfile: { id: admin.id } } }); - // } else { - // throw "Admin name not found :("; - // } - - // } + if (admin) { + return admin; + } else { + throw "Admin name not found :("; + } + } const [orgs, total] = await OrganizationProfile.findAndCount({ skip: pageSize * (page - 1), diff --git a/src/controllers/organizationAdmin.ts b/src/controllers/organizationAdmin.ts index 189a8cf5..35c1ca6c 100644 --- a/src/controllers/organizationAdmin.ts +++ b/src/controllers/organizationAdmin.ts @@ -41,7 +41,8 @@ const getOrganizationAdmins = async (payload: { return OrganizationAdmin.findOne({ where: { email: payload.email } }) } if (payload.organizationName) { - const organization = await OrganizationProfile.findOne({ where: { name: payload.name } }); + + const organization = await OrganizationProfile.findOne({ where: { name: payload.organizationName} }); if (organization) { return await OrganizationAdmin.findOne({ where: { orgProfile: { id: organization.id } } }); diff --git a/src/routes/organizationAdmin.ts b/src/routes/organizationAdmin.ts index 2f8556d5..d7d8cd69 100644 --- a/src/routes/organizationAdmin.ts +++ b/src/routes/organizationAdmin.ts @@ -52,7 +52,7 @@ router.get('/', authorize("GET_organizationAdmins"), async (req, res, next) => { }) .catch(error => { console.error(error); - res.status(500).send('Something went wrong'); + res.status(500).send(error); }); }); From b0836dc599fc2661326f5b4f4549c760a1010b84 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Sat, 7 Oct 2023 08:15:50 +0300 Subject: [PATCH 064/146] Creat derigtration function for voluntary work --- app.ts | 8 +++--- src/controllers/organizationAdmin.ts | 1 - src/controllers/permission.ts | 41 ---------------------------- src/controllers/voluntaryWork.ts | 31 +++++++++++++++++++-- src/db/entities/OrganizationAdmin.ts | 2 +- src/routes/organizationProfile.ts | 4 +-- src/routes/voluntaryWork.ts | 18 +++++++++--- 7 files changed, 49 insertions(+), 56 deletions(-) diff --git a/app.ts b/app.ts index c5b5a929..554dcb08 100644 --- a/app.ts +++ b/app.ts @@ -24,11 +24,11 @@ app.use(express.urlencoded({ extended: false })); app.use(cookieParser()); app.use('/', indexRouter); -app.use('/permission', authenticate, permissionRouter); -app.use('/role', authenticate, roleRouter); -app.use('/voluntaryWork', authenticate, voluntaryWorkRouter); +app.use('/permission',/* authenticate,*/ permissionRouter); +app.use('/role', /*authenticate, */roleRouter); +app.use('/voluntaryWork', /*authenticate,*/ voluntaryWorkRouter); app.use('/organizationAdmin',/* authenticate, */organizationAdminRouter); -app.use('/organizationProfile', authenticate, organizationProfileRouter); +app.use('/organizationProfile',/* authenticate,*/ organizationProfileRouter); app.use("/volunteer",volunteerRouter ); // catch 404 and forward to error handler diff --git a/src/controllers/organizationAdmin.ts b/src/controllers/organizationAdmin.ts index 35c1ca6c..21d1d8fa 100644 --- a/src/controllers/organizationAdmin.ts +++ b/src/controllers/organizationAdmin.ts @@ -2,7 +2,6 @@ import { NSOrganizationAdmin } from "../../types/organizationAdmin.js"; import { OrganizationAdmin } from "../db/entities/OrganizationAdmin.js"; import { OrganizationProfile } from "../db/entities/OrganizationProfile.js"; import bcrypt from 'bcrypt'; -import { Volunteer } from "../db/entities/Volunteer.js"; const createOrganizationAdmin = async (payload: NSOrganizationAdmin.Item) => { diff --git a/src/controllers/permission.ts b/src/controllers/permission.ts index 459b7ad0..fc4bb95a 100644 --- a/src/controllers/permission.ts +++ b/src/controllers/permission.ts @@ -12,52 +12,11 @@ const createPermission = async (payload: NSPermission.Item) => { } const deletePermission = async (permissionId: number) => { - // const roles = sender?.roles; - // let hasDeletePermission: boolean = false; - // let typeName: string = ""; - - // if (sender instanceof OrganizationAdmin) { - // if (!Array.isArray(roles)) { - // typeName = "organizationAdmin"; - // hasDeletePermission = roles.permissions.some(permission => permission.name === `DELETE_${typeName}`); - // } - // } else { - // if (Array.isArray(roles)) { - // typeName = sender?.type; - // hasDeletePermission = roles?.some(role => - // role.permissions.some(permission => permission.name === `DELETE_${typeName}`)) - // } - // } - - // if (!hasDeletePermission) { - // return `You don't have a permission to delete ${typeName}` - // } - return Permission.delete(permissionId); } const editPermission = async (payload: { name: string, id: number }) => { - // const roles = sender.roles; - // let hasEditPermission: boolean = false; - // let typeName: string = ""; - - // if (sender instanceof OrganizationAdmin) { - // if (!Array.isArray(roles)) { - // typeName = "organizationAdmin"; - // hasEditPermission = roles.permissions.some(permission => permission.name === `EDIT_${typeName}`); - // } - // } else { - // if (Array.isArray(roles)) { - // typeName = sender?.type; - // hasEditPermission = roles?.some(role => - // role.permissions.some(permission => permission.name === `DELETE_${typeName}`)) - // } - // } - - // if (!hasEditPermission) { - // return `You don't have a permission to delete ${typeName}` - // } const permission = await Permission.findOne({ where: { id: payload.id } }); diff --git a/src/controllers/voluntaryWork.ts b/src/controllers/voluntaryWork.ts index b1dae1ee..4d392d5d 100644 --- a/src/controllers/voluntaryWork.ts +++ b/src/controllers/voluntaryWork.ts @@ -4,6 +4,7 @@ import { SkillTag } from "../db/entities/SkillTag.js"; import { VoluntaryWork } from "../db/entities/VoluntaryWork.js"; import { getDate } from "./index.js"; import { Volunteer } from "../db/entities/Volunteer.js"; +import { VolunteerProfile } from "../db/entities/VolunteerProfile.js"; const createVoluntaryWork = async (payload: NSVoluntaryWork.Item) => { let payloadDate = { ...payload, startedDate: getDate(payload.startedDate), finishedDate: getDate(payload.finishedDate) }; @@ -221,12 +222,12 @@ const registerByVolunteer = async (workId: number, volunteerProfile: Volunteer[" const registerByOrganizationAdmin = async (workId: number, volunteerId: string) => { const voluntaryWork = await VoluntaryWork.findOne({ where: { id: workId } }); - const volunteer = await Volunteer.findOne({where:{id:volunteerId}}); + const volunteer = await Volunteer.findOne({ where: { id: volunteerId } }); if (!voluntaryWork) { throw new Error("VoluntaryWork not found"); } - if(!volunteer){ + if (!volunteer) { throw new Error("Volunteer not found"); } @@ -236,4 +237,28 @@ const registerByOrganizationAdmin = async (workId: number, volunteerId: string) return "Registration successful!"; } -export { registerByOrganizationAdmin, registerByVolunteer, putImages, createVoluntaryWork, putFeedback, editVoluntaryWork, putRating, getVoluntaryWork, getVoluntaryWorks, deleteVoluntaryWork } \ No newline at end of file +const deregisterVoluntaryWork = async (workId: number, volunteerId: string) => { + const voluntaryWork = await VoluntaryWork.findOne({ where: { id: workId }, relations: ["volunteerProfiles"] }); + const volunteer = await Volunteer.findOne({ where: { id: volunteerId } }); + + if (!voluntaryWork) { + throw new Error("VoluntaryWork not found"); + } + + if (!volunteer) { + throw new Error("Volunteer not found"); + } + + const index = voluntaryWork.volunteerProfiles.findIndex(profile => profile.id === volunteer.volunteerProfile.id); + + if (index !== -1) { + voluntaryWork.volunteerProfiles.splice(index, 1); + await voluntaryWork.save(); + return "Deregistration successful!"; + } else { + throw new Error("Volunteer is not registered for this voluntary work"); + } +} + + +export { deregisterVoluntaryWork, registerByOrganizationAdmin, registerByVolunteer, putImages, createVoluntaryWork, putFeedback, editVoluntaryWork, putRating, getVoluntaryWork, getVoluntaryWorks, deleteVoluntaryWork } \ No newline at end of file diff --git a/src/db/entities/OrganizationAdmin.ts b/src/db/entities/OrganizationAdmin.ts index 12cf5c63..88032eb6 100644 --- a/src/db/entities/OrganizationAdmin.ts +++ b/src/db/entities/OrganizationAdmin.ts @@ -28,7 +28,7 @@ export class OrganizationAdmin extends BaseEntity { orgProfile: OrganizationProfile; @ManyToOne(() => Role, role => role.orgAdmins) - roles: Role; + roles: Role; @CreateDateColumn({ type: 'timestamp', diff --git a/src/routes/organizationProfile.ts b/src/routes/organizationProfile.ts index 24f507cf..02685780 100644 --- a/src/routes/organizationProfile.ts +++ b/src/routes/organizationProfile.ts @@ -36,7 +36,7 @@ router.put("/:id", authorize("PUT_organizationProfile"),checkAdmin, async (req, }); }); -router.get('/', authorize("GET_organizationProfiles"), async (req, res, next) => { +router.get('/', /*authorize("GET_organizationProfiles"),*/ async (req, res, next) => { const payload = { page: req.query.page?.toString() || '1', pageSize: req.query.pageSize?.toString() || '10', @@ -51,7 +51,7 @@ router.get('/', authorize("GET_organizationProfiles"), async (req, res, next) => }) .catch(error => { console.error(error); - res.status(500).send('Something went wrong'); + res.status(500).send(error); }); }); diff --git a/src/routes/voluntaryWork.ts b/src/routes/voluntaryWork.ts index c0e30de1..db6fd47b 100644 --- a/src/routes/voluntaryWork.ts +++ b/src/routes/voluntaryWork.ts @@ -1,5 +1,5 @@ import express from 'express'; -import { createVoluntaryWork, deleteVoluntaryWork, editVoluntaryWork, getVoluntaryWork, getVoluntaryWorks, putFeedback, putImages, putRating, registerByOrganizationAdmin, registerByVolunteer } from '../controllers/voluntaryWork.js'; +import { createVoluntaryWork, deleteVoluntaryWork, deregisterVoluntaryWork, editVoluntaryWork, getVoluntaryWork, getVoluntaryWorks, putFeedback, putImages, putRating, registerByOrganizationAdmin, registerByVolunteer } from '../controllers/voluntaryWork.js'; import { NSVolunteer } from '../../types/volunteer.js'; import { NSVoluntaryWork } from '../../types/voluntaryWork.js'; import { authorize, checkCreator, checkParticipation } from '../middleware/auth/authorize.js'; @@ -149,18 +149,18 @@ router.put("/images/:id", authorize("PUT_images"), async (req, res, next) => { router.put("/register/:id", authorize("REGISTER_voluntaryWork"), async (req, res, next) => { if (res.locals.volunteer) { registerByVolunteer(Number(req.params.id), res.locals.volunteer["volunteerProfile"]).then(() => { - res.status(201).send("Rating added successfully!!") + res.status(201).send("Registration done successfully!!") }).catch(err => { console.error(err); res.status(500).send(err); }); } else if (res.locals.organizationAdmin) { if (!req.body.volunteerId.toString()) { - throw "volunteer id is required!"; + res.status(400).send("volunteer id is required!"); } registerByOrganizationAdmin(Number(req.params.id), req.body.volunteerId.toString()).then(() => { - res.status(201).send("Rating added successfully!!") + res.status(201).send("Registration done successfully!!") }).catch(err => { console.error(err); res.status(500).send(err); @@ -168,5 +168,15 @@ router.put("/register/:id", authorize("REGISTER_voluntaryWork"), async (req, res } }); +router.put("/deregister/:id", authorize("DEREGISTER_voluntaryWork"), async (req, res, next) => { + + deregisterVoluntaryWork(Number(req.params.id), res.locals.volunteer.id || req.body.volunteerId.toString()).then(() => { + res.status(201).send("Deregistration done successfully!!") + }).catch(err => { + console.error(err); + res.status(500).send(err); + }); +}); + export default router; From 393bda56b5b621dd9437888e317eaa1e0dabd059 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Sat, 7 Oct 2023 08:46:20 +0300 Subject: [PATCH 065/146] Add validation if edited in the put method --- src/controllers/voluntaryWork.ts | 7 +- .../validation/organizationAdmin.ts | 25 ++++++- src/middleware/validation/role.ts | 23 +++++- src/middleware/validation/voluntaryWork.ts | 72 ++++++++++++++++++- src/middleware/validation/volunteer.ts | 51 ++++++++++++- src/routes/organizationAdmin.ts | 6 +- src/routes/role.ts | 4 +- src/routes/voluntaryWork.ts | 11 +-- src/routes/volunteer.ts | 4 +- 9 files changed, 184 insertions(+), 19 deletions(-) diff --git a/src/controllers/voluntaryWork.ts b/src/controllers/voluntaryWork.ts index 4d392d5d..7cbb40fd 100644 --- a/src/controllers/voluntaryWork.ts +++ b/src/controllers/voluntaryWork.ts @@ -261,4 +261,9 @@ const deregisterVoluntaryWork = async (workId: number, volunteerId: string) => { } -export { deregisterVoluntaryWork, registerByOrganizationAdmin, registerByVolunteer, putImages, createVoluntaryWork, putFeedback, editVoluntaryWork, putRating, getVoluntaryWork, getVoluntaryWorks, deleteVoluntaryWork } \ No newline at end of file +export { + deregisterVoluntaryWork, registerByOrganizationAdmin, + registerByVolunteer, putImages, createVoluntaryWork, + putFeedback, editVoluntaryWork, putRating, getVoluntaryWork, + getVoluntaryWorks, deleteVoluntaryWork +} \ No newline at end of file diff --git a/src/middleware/validation/organizationAdmin.ts b/src/middleware/validation/organizationAdmin.ts index d94a2b53..ed9ad04e 100644 --- a/src/middleware/validation/organizationAdmin.ts +++ b/src/middleware/validation/organizationAdmin.ts @@ -24,6 +24,29 @@ const validateOrganizationAdmin = (req: express.Request, } } +const validateAdminEdited = (req: express.Request, + res: express.Response, + next: express.NextFunction +) => { + const organizationAdmin = req.body; + const errorList = []; + + if (organizationAdmin.email){ + if (!EmailValidator.validate(organizationAdmin.email)) { + errorList.push('Email is not Valid'); + } + } + + errorList.push(...isValidPassword(organizationAdmin.password )); + + if (errorList.length) { + res.status(400).send(errorList); + } else { + next(); + } +} + export { - validateOrganizationAdmin + validateOrganizationAdmin, + validateAdminEdited } \ No newline at end of file diff --git a/src/middleware/validation/role.ts b/src/middleware/validation/role.ts index 8bdfd823..8708de53 100644 --- a/src/middleware/validation/role.ts +++ b/src/middleware/validation/role.ts @@ -19,6 +19,27 @@ const validateRole = (req: express.Request, } } +const validateEditedRole = (req: express.Request, + res: express.Response, + next: express.NextFunction +) => { + const role = req.body; + const errorList = []; + + if (role.name){ + if (!['root', 'admin', 'volunteer', 'premium'].includes(role.name)) { + errorList.push('role name unknown!'); + } + } + + if (errorList.length) { + res.status(400).send(errorList); + } else { + next(); + } +} + export { - validateRole + validateRole, + validateEditedRole } \ No newline at end of file diff --git a/src/middleware/validation/voluntaryWork.ts b/src/middleware/validation/voluntaryWork.ts index 02b2157c..ee6a4b7d 100644 --- a/src/middleware/validation/voluntaryWork.ts +++ b/src/middleware/validation/voluntaryWork.ts @@ -2,6 +2,7 @@ import express from 'express'; import { NSVoluntaryWork } from '../../../types/voluntaryWork.js'; import { NSVolunteer } from '../../../types/volunteer.js'; import { getDate, isValidDate } from '../../controllers/index.js'; +import { VoluntaryWork } from '../../db/entities/VoluntaryWork.js'; const validateVoluntaryWork = (req: express.Request, res: express.Response, @@ -25,14 +26,14 @@ const validateVoluntaryWork = (req: express.Request, if (!validDays) { errorList.push("Invalid days !"); } - + if (voluntaryWork.capacity < 1 || voluntaryWork.capacity > 40) { errorList.push("Invalid capacity !"); } if (!isValidDate(voluntaryWork.startedDate) || !isValidDate(voluntaryWork.finishedDate)) { errorList.push("Invalid date !") } - if (getDate(voluntaryWork.startedDate) > getDate(voluntaryWork.finishedDate)){ + if (getDate(voluntaryWork.startedDate) > getDate(voluntaryWork.finishedDate)) { errorList.push("The started date should be before the finished date !"); } @@ -43,6 +44,71 @@ const validateVoluntaryWork = (req: express.Request, } } +const validateEditedVoluntaryWork = async (req: express.Request, + res: express.Response, + next: express.NextFunction +) => { + const voluntaryWork = req.body; + const errorList = []; + + const id = Number(req.params.id.toString()); + const vw = await VoluntaryWork.findOne({where:{id}}); + if(!vw){ + res.status(400).send("Id not valid"); + } + + if (voluntaryWork.status) { + const validStatus = voluntaryWork.status.every((status: string) => Object.values(NSVoluntaryWork.StatusType).includes(status as NSVoluntaryWork.StatusType)); + if (!validStatus) { + errorList.push("Invalid status !"); + } + } + + if (voluntaryWork.time) { + const validTime = voluntaryWork.time.every((time: string) => Object.values(NSVolunteer.AvailableTime).includes(time as NSVolunteer.AvailableTime)); + if (!validTime) { + errorList.push("Invalid time !"); + } + } + + if (voluntaryWork.days) { + const validDays = voluntaryWork.days.every((days: string) => Object.values(NSVolunteer.AvailableDays).includes(days as NSVolunteer.AvailableDays)); + if (!validDays) { + errorList.push("Invalid days !"); + } + } + + if (voluntaryWork.capacity) { + if (voluntaryWork.capacity < 1 || voluntaryWork.capacity > 40) { + errorList.push("Invalid capacity !"); + } + } + if (voluntaryWork.startedDate || voluntaryWork.finishedDate) { + if (!isValidDate(voluntaryWork.startedDate) || !isValidDate(voluntaryWork.finishedDate)) { + errorList.push("Invalid date !") + } + } + if (voluntaryWork.startedDate && voluntaryWork.finishedDate) { + if (getDate(voluntaryWork.startedDate) > getDate(voluntaryWork.finishedDate)) { + errorList.push("The started date should be before the finished date !"); + } + }else if (voluntaryWork.startedDate && vw){ + if (getDate(voluntaryWork.startedDate) > vw.finishedDate) { + errorList.push("The started date should be before the finished date !"); + } + }else if (voluntaryWork.finishedDate && vw){ + if (vw.startedDate > getDate(voluntaryWork.finishedDate)) { + errorList.push("The started date should be before the finished date !"); + } + } + + if (errorList.length) { + res.status(400).send(errorList); + } else { + next(); + } +} export { - validateVoluntaryWork + validateVoluntaryWork, + validateEditedVoluntaryWork } \ No newline at end of file diff --git a/src/middleware/validation/volunteer.ts b/src/middleware/validation/volunteer.ts index 9ae6aa43..e254b473 100644 --- a/src/middleware/validation/volunteer.ts +++ b/src/middleware/validation/volunteer.ts @@ -2,6 +2,7 @@ import express from 'express'; import * as EmailValidator from 'email-validator'; import { isValidPassword } from '../../controllers/index.js'; import { NSVolunteer } from '../../../types/volunteer.js'; +import { Volunteer } from '../../db/entities/Volunteer.js'; const validateVolunteer = (req: express.Request, res: express.Response, next: express.NextFunction) => { @@ -43,7 +44,55 @@ const validateVolunteer = (req: express.Request, res: express.Response, next: ex } }; +const validateEditedVolunteer = async (req: express.Request, res: express.Response, next: express.NextFunction) => { + const volunteer = req.body; + const errorList: string[] = []; + + const id = req.params.id.toString(); + const v = await Volunteer.findOne({ where: { id } }); + if (!v) { + res.status(400).send("Id not valid"); + } + + if (volunteer.email) { + if (!EmailValidator.validate(volunteer.email)) { + errorList.push('Email is not valid.'); + } + } + + if (volunteer.type) { + const validType = Object.values(NSVolunteer.TypeVolunteer).includes(volunteer.type); + if (!validType) { + errorList.push("Invalid type!"); + } + } + + if (volunteer.availableTime) { + const validTime = volunteer.availableTime.every((time: string) => Object.values(NSVolunteer.AvailableTime).includes(time as NSVolunteer.AvailableTime)); + if (!validTime) { + errorList.push("Invalid time!"); + } + } + + if (volunteer.availableDays) { + const validDays = volunteer.availableDays.every((days: string) => Object.values(NSVolunteer.AvailableDays).includes(days as NSVolunteer.AvailableDays)); + if (!validDays) { + errorList.push("Invalid days!"); + } + } + + if (volunteer.password) { + errorList.push(...isValidPassword(volunteer.password)); + } + + if (errorList.length) { + res.status(400).send({ errors: errorList }); + } else { + next(); + } +}; export { - validateVolunteer + validateVolunteer, + validateEditedVolunteer } \ No newline at end of file diff --git a/src/routes/organizationAdmin.ts b/src/routes/organizationAdmin.ts index d7d8cd69..681928b4 100644 --- a/src/routes/organizationAdmin.ts +++ b/src/routes/organizationAdmin.ts @@ -1,7 +1,7 @@ import express from "express"; import { createOrganizationAdmin, deleteOrganizationAdmin, editOrganizationAdmin, getOrganizationAdmins } from "../controllers/organizationAdmin.js"; import { authorize, checkMe } from "../middleware/auth/authorize.js"; -import { validateOrganizationAdmin } from "../middleware/validation/organizationAdmin.js"; +import { validateAdminEdited, validateOrganizationAdmin } from "../middleware/validation/organizationAdmin.js"; const router = express.Router(); @@ -27,8 +27,8 @@ router.delete('/:id', authorize("DELETE_organizationAdmin"), checkMe, async (req }); }); -router.put("/:id", authorize("PUT_organizationAdmin"),checkMe(), async (req, res, next) => { - editOrganizationAdmin({...req.body, id:req.params.id}).then(() => { +router.put("/:id", authorize("PUT_organizationAdmin"), checkMe, validateAdminEdited,async (req, res, next) => { + editOrganizationAdmin({ ...req.body, id: req.params.id }).then(() => { res.status(201).send("Organization Admin edited successfully!!") }).catch(err => { console.error(err); diff --git a/src/routes/role.ts b/src/routes/role.ts index ba0eecd5..c49e4d97 100644 --- a/src/routes/role.ts +++ b/src/routes/role.ts @@ -2,7 +2,7 @@ import express from 'express'; import { createRole, deleteRole, editRole, getRoles } from '../controllers/role.js'; import { NSRole } from '../../types/role.js'; import { authorize } from '../middleware/auth/authorize.js'; -import { validateRole } from '../middleware/validation/role.js'; +import { validateEditedRole, validateRole } from '../middleware/validation/role.js'; var router = express.Router(); @@ -28,7 +28,7 @@ router.delete('/:id', authorize("DELETE_role"), async (req, res) => { }); }) -router.put("/:id", authorize("PUT_role"), async (req, res, next) => { +router.put("/:id", authorize("PUT_role"),validateEditedRole, async (req, res, next) => { editRole({ ...req.body, id: req.params.id?.toString() }).then(() => { res.status(201).send("Role edited successfully!!") }).catch(err => { diff --git a/src/routes/voluntaryWork.ts b/src/routes/voluntaryWork.ts index db6fd47b..a30f0341 100644 --- a/src/routes/voluntaryWork.ts +++ b/src/routes/voluntaryWork.ts @@ -3,7 +3,7 @@ import { createVoluntaryWork, deleteVoluntaryWork, deregisterVoluntaryWork, edit import { NSVolunteer } from '../../types/volunteer.js'; import { NSVoluntaryWork } from '../../types/voluntaryWork.js'; import { authorize, checkCreator, checkParticipation } from '../middleware/auth/authorize.js'; -import { validateVoluntaryWork } from '../middleware/validation/voluntaryWork.js'; +import { validateEditedVoluntaryWork, validateVoluntaryWork } from '../middleware/validation/voluntaryWork.js'; var router = express.Router(); @@ -28,7 +28,7 @@ router.delete('/:id', authorize("DELETE_voluntaryWork"), checkCreator, async (re }); }) -router.put("/:id", authorize("PUT_voluntaryWork"), checkCreator, async (req, res, next) => { +router.put("/:id", authorize("PUT_voluntaryWork"), checkCreator,validateEditedVoluntaryWork, async (req, res, next) => { editVoluntaryWork({ ...req.body, id: req.params.id?.toString() }).then(() => { res.status(201).send("Voluntary Work edited successfully!!") }).catch(err => { @@ -169,7 +169,9 @@ router.put("/register/:id", authorize("REGISTER_voluntaryWork"), async (req, res }); router.put("/deregister/:id", authorize("DEREGISTER_voluntaryWork"), async (req, res, next) => { - + if( res.locals.volunteer.id || req.body.volunteerId.toString()){ + res.status(400).send("Volunteer id is required !"); + } deregisterVoluntaryWork(Number(req.params.id), res.locals.volunteer.id || req.body.volunteerId.toString()).then(() => { res.status(201).send("Deregistration done successfully!!") }).catch(err => { @@ -178,5 +180,4 @@ router.put("/deregister/:id", authorize("DEREGISTER_voluntaryWork"), async (req, }); }); -export default router; - +export default router; \ No newline at end of file diff --git a/src/routes/volunteer.ts b/src/routes/volunteer.ts index 78fce29f..c81f9a5b 100644 --- a/src/routes/volunteer.ts +++ b/src/routes/volunteer.ts @@ -1,7 +1,7 @@ import express from 'express'; import { authorize, checkMe } from '../middleware/auth/authorize.js'; import { authenticate } from '../middleware/auth/authenticate.js'; -import { validateVolunteer } from '../middleware/validation/volunteer.js'; +import { validateEditedVolunteer, validateVolunteer } from '../middleware/validation/volunteer.js'; import { createVolunteer, deleteVolunteer, editVolunteer, getVolunteers, login } from '../controllers/volunteer.js'; import { NSVolunteer } from '../../types/volunteer.js'; @@ -52,7 +52,7 @@ router.delete('/:id', authenticate, authorize("DELETE_volunteer"), checkMe, asyn }); }) -router.put("/:id", authenticate, authorize("POST_volunteer"), checkMe, async (req, res, next) => { +router.put("/:id", authenticate, authorize("POST_volunteer"), checkMe, validateEditedVolunteer,async (req, res, next) => { editVolunteer({ ...req.body, id: req.params.id?.toString() }).then(() => { res.status(201).send("Volunteer edited successfully!!") }).catch(err => { From 471d59db035b509b177184b185bc1999c22bd8a6 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Sat, 7 Oct 2023 08:58:00 +0300 Subject: [PATCH 066/146] Adding validation of id on put methood --- .../validation/organizationAdmin.ts | 9 ++++++++- .../validation/organizationProfile.ts | 17 +++++++++++++++- src/middleware/validation/permission.ts | 17 +++++++++++++++- src/middleware/validation/role.ts | 9 ++++++++- src/middleware/validation/skillTag.ts | 20 ------------------- src/routes/organizationAdmin.ts | 2 +- src/routes/organizationProfile.ts | 4 ++-- src/routes/permission.ts | 4 ++-- 8 files changed, 53 insertions(+), 29 deletions(-) delete mode 100644 src/middleware/validation/skillTag.ts diff --git a/src/middleware/validation/organizationAdmin.ts b/src/middleware/validation/organizationAdmin.ts index ed9ad04e..595a1243 100644 --- a/src/middleware/validation/organizationAdmin.ts +++ b/src/middleware/validation/organizationAdmin.ts @@ -1,6 +1,7 @@ import express from 'express'; import * as EmailValidator from 'email-validator'; import { isValidPassword } from '../../controllers/index.js'; +import { OrganizationAdmin } from '../../db/entities/OrganizationAdmin.js'; const validateOrganizationAdmin = (req: express.Request, @@ -24,13 +25,19 @@ const validateOrganizationAdmin = (req: express.Request, } } -const validateAdminEdited = (req: express.Request, +const validateAdminEdited = async (req: express.Request, res: express.Response, next: express.NextFunction ) => { const organizationAdmin = req.body; const errorList = []; + const id = req.params.id.toString(); + const v = await OrganizationAdmin.findOne({ where: { id } }); + if (!v) { + res.status(400).send("Id not valid"); + } + if (organizationAdmin.email){ if (!EmailValidator.validate(organizationAdmin.email)) { errorList.push('Email is not Valid'); diff --git a/src/middleware/validation/organizationProfile.ts b/src/middleware/validation/organizationProfile.ts index 55690e62..d34c2047 100644 --- a/src/middleware/validation/organizationProfile.ts +++ b/src/middleware/validation/organizationProfile.ts @@ -1,4 +1,5 @@ import express from 'express'; +import { OrganizationProfile } from '../../db/entities/OrganizationProfile.js'; const validateOrganizationProfile = (req: express.Request, res: express.Response, @@ -15,6 +16,20 @@ const validateOrganizationProfile = (req: express.Request, } } +const validateOrgId = async (req: express.Request, + res: express.Response, + next: express.NextFunction +) => { + const id = req.params.id.toString(); + const v = await OrganizationProfile.findOne({ where: { id } }); + if (!v) { + res.status(400).send("Id not valid"); + }else{ + next(); + } +} + export { - validateOrganizationProfile + validateOrganizationProfile, + validateOrgId } \ No newline at end of file diff --git a/src/middleware/validation/permission.ts b/src/middleware/validation/permission.ts index dec76b5f..44cc15c3 100644 --- a/src/middleware/validation/permission.ts +++ b/src/middleware/validation/permission.ts @@ -1,4 +1,5 @@ import express from 'express'; +import { Permission } from '../../db/entities/Permission.js'; const validatePermission = (req: express.Request, res: express.Response, @@ -15,6 +16,20 @@ const validatePermission = (req: express.Request, } } +const validatePermissionId = async (req: express.Request, + res: express.Response, + next: express.NextFunction +) => { + const id = Number(req.params.id.toString()); + const p = await Permission.findOne({ where: { id } }); + if (!p) { + res.status(400).send("Id not valid"); + }else{ + next(); + } +} + export { - validatePermission + validatePermission, + validatePermissionId } \ No newline at end of file diff --git a/src/middleware/validation/role.ts b/src/middleware/validation/role.ts index 8708de53..0eff4143 100644 --- a/src/middleware/validation/role.ts +++ b/src/middleware/validation/role.ts @@ -1,4 +1,5 @@ import express from 'express'; +import { Role } from '../../db/entities/Role.js'; const validateRole = (req: express.Request, res: express.Response, @@ -19,13 +20,19 @@ const validateRole = (req: express.Request, } } -const validateEditedRole = (req: express.Request, +const validateEditedRole = async (req: express.Request, res: express.Response, next: express.NextFunction ) => { const role = req.body; const errorList = []; + const id = Number(req.params.id.toString()); + const r = await Role.findOne({ where: { id } }); + if (!r) { + res.status(400).send("Id not valid"); + } + if (role.name){ if (!['root', 'admin', 'volunteer', 'premium'].includes(role.name)) { errorList.push('role name unknown!'); diff --git a/src/middleware/validation/skillTag.ts b/src/middleware/validation/skillTag.ts deleted file mode 100644 index 63766db7..00000000 --- a/src/middleware/validation/skillTag.ts +++ /dev/null @@ -1,20 +0,0 @@ -import express from 'express'; - -const validatePermission = (req: express.Request, - res: express.Response, - next: express.NextFunction -) => { - const values = ["name"]; - const skillTag = req.body; - const errorList = values.map(key => !skillTag[key] && `${key} is Required!`).filter(Boolean); - - if (errorList.length) { - res.status(400).send(errorList); - } else { - next(); - } -} - -export { - validatePermission -} \ No newline at end of file diff --git a/src/routes/organizationAdmin.ts b/src/routes/organizationAdmin.ts index 681928b4..825b1e2b 100644 --- a/src/routes/organizationAdmin.ts +++ b/src/routes/organizationAdmin.ts @@ -27,7 +27,7 @@ router.delete('/:id', authorize("DELETE_organizationAdmin"), checkMe, async (req }); }); -router.put("/:id", authorize("PUT_organizationAdmin"), checkMe, validateAdminEdited,async (req, res, next) => { +router.put("/:id", authorize("PUT_organizationAdmin"), checkMe, validateAdminEdited, async (req, res, next) => { editOrganizationAdmin({ ...req.body, id: req.params.id }).then(() => { res.status(201).send("Organization Admin edited successfully!!") }).catch(err => { diff --git a/src/routes/organizationProfile.ts b/src/routes/organizationProfile.ts index 02685780..7c689ca9 100644 --- a/src/routes/organizationProfile.ts +++ b/src/routes/organizationProfile.ts @@ -1,7 +1,7 @@ import express from "express"; import { createOrganizationProfile, deleteOrganizationProfile, editOrganizationProfile, getOrganizationProfile } from "../controllers/OrganizationProfile .js"; import { authorize, checkAdmin } from "../middleware/auth/authorize.js"; -import { validateOrganizationProfile } from "../middleware/validation/organizationProfile.js"; +import { validateOrgId, validateOrganizationProfile } from "../middleware/validation/organizationProfile.js"; const router = express.Router(); @@ -27,7 +27,7 @@ router.delete('/:id', authorize("DELETE_organizationProfile"), checkAdmin, async }); }); -router.put("/:id", authorize("PUT_organizationProfile"),checkAdmin, async (req, res, next) => { +router.put("/:id", authorize("PUT_organizationProfile"),checkAdmin,validateOrgId, async (req, res, next) => { editOrganizationProfile(req.body).then(() => { res.status(201).send("Organization Profile edited successfully!!") }).catch(err => { diff --git a/src/routes/permission.ts b/src/routes/permission.ts index edb5ec11..1a0f9aa7 100644 --- a/src/routes/permission.ts +++ b/src/routes/permission.ts @@ -1,7 +1,7 @@ import express from 'express'; import { createPermission, deletePermission, editPermission, getPermissions } from '../controllers/permission.js'; import { authorize } from '../middleware/auth/authorize.js'; -import { validatePermission } from '../middleware/validation/permission.js'; +import { validatePermission, validatePermissionId } from '../middleware/validation/permission.js'; var router = express.Router(); @@ -27,7 +27,7 @@ router.delete('/:id', authorize("DELETE_permission"), async (req, res) => { }); }) -router.put("/:id", authorize("PUT_permission"), async (req, res, next) => { +router.put("/:id", authorize("PUT_permission"), validatePermissionId, async (req, res, next) => { editPermission({ ...req.body, id: req.params.id?.toString() }).then(() => { res.status(201).send("Permission edited successfully!!") }).catch(err => { From 8c5a0dc4a92306b2e2cdf8f253aec7b10176985f Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Sat, 7 Oct 2023 09:02:22 +0300 Subject: [PATCH 067/146] Add DOF attribute for volunteer and orgAdmin and make the volunter type optional --- .vscode/settings.json | 5 +++++ src/db/entities/Volunteer.ts | 3 ++- src/db/entities/VolunteerProfile.ts | 3 +++ src/middleware/validation/volunteer.ts | 8 +++++--- types/volunteer.ts | 2 +- 5 files changed, 16 insertions(+), 5 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..19daeb48 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "cSpell.words": [ + "Deregistration" + ] +} \ No newline at end of file diff --git a/src/db/entities/Volunteer.ts b/src/db/entities/Volunteer.ts index 5f3fa201..e8708825 100644 --- a/src/db/entities/Volunteer.ts +++ b/src/db/entities/Volunteer.ts @@ -26,7 +26,8 @@ export class Volunteer extends BaseEntity { @Column({ type: 'enum', enum: ['volunteer', 'premium'], - default: 'volunteer' + default: 'volunteer', + nullable:true }) type: 'volunteer' | 'premium'; diff --git a/src/db/entities/VolunteerProfile.ts b/src/db/entities/VolunteerProfile.ts index cab56275..26f2dea8 100644 --- a/src/db/entities/VolunteerProfile.ts +++ b/src/db/entities/VolunteerProfile.ts @@ -24,6 +24,9 @@ export class VolunteerProfile extends BaseEntity { @Column({ nullable: false }) availableLocation: string; + @Column({ nullable: true, type: "timestamp" }) + dateOfBirth: Date; + @ManyToMany(() => SkillTag) @JoinTable() skillTags: SkillTag[]; diff --git a/src/middleware/validation/volunteer.ts b/src/middleware/validation/volunteer.ts index e254b473..b7c7e295 100644 --- a/src/middleware/validation/volunteer.ts +++ b/src/middleware/validation/volunteer.ts @@ -20,9 +20,11 @@ const validateVolunteer = (req: express.Request, res: express.Response, next: ex errorList.push('Email is not valid.'); } - const validType = Object.values(NSVolunteer.TypeVolunteer).includes(volunteer.type); - if (!validType) { - errorList.push("Invalid type!"); + if (volunteer.type){ + const validType = Object.values(NSVolunteer.TypeVolunteer).includes(volunteer.type); + if (!validType) { + errorList.push("Invalid type!"); + } } const validTime = volunteer.availableTime.every((time: string) => Object.values(NSVolunteer.AvailableTime).includes(time as NSVolunteer.AvailableTime)); diff --git a/types/volunteer.ts b/types/volunteer.ts index 7de70d71..d464579d 100644 --- a/types/volunteer.ts +++ b/types/volunteer.ts @@ -26,7 +26,7 @@ export namespace NSVolunteer { email: string; password: string; createdAt?: Date; - type: TypeVolunteer; + type?: TypeVolunteer; availableTime: AvailableTime[]; availableLocation: string; availableDays: AvailableDays[]; From b773c0d4043369963fdf5fe2f66a9b478981f597 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Sat, 7 Oct 2023 09:07:20 +0300 Subject: [PATCH 068/146] allow nolnteer to edit password if the old password is correct --- app.ts | 12 ++++++------ src/controllers/volunteer.ts | 21 ++++++++++++++++----- src/routes/organizationProfile.ts | 2 +- 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/app.ts b/app.ts index 554dcb08..72282676 100644 --- a/app.ts +++ b/app.ts @@ -24,12 +24,12 @@ app.use(express.urlencoded({ extended: false })); app.use(cookieParser()); app.use('/', indexRouter); -app.use('/permission',/* authenticate,*/ permissionRouter); -app.use('/role', /*authenticate, */roleRouter); -app.use('/voluntaryWork', /*authenticate,*/ voluntaryWorkRouter); -app.use('/organizationAdmin',/* authenticate, */organizationAdminRouter); -app.use('/organizationProfile',/* authenticate,*/ organizationProfileRouter); -app.use("/volunteer",volunteerRouter ); +app.use('/permission', authenticate, permissionRouter); +app.use('/role', authenticate, roleRouter); +app.use('/voluntaryWork', authenticate, voluntaryWorkRouter); +app.use('/organizationAdmin', authenticate, organizationAdminRouter); +app.use('/organizationProfile', authenticate, organizationProfileRouter); +app.use("/volunteer", volunteerRouter); // catch 404 and forward to error handler app.use(function (req, res, next) { diff --git a/src/controllers/volunteer.ts b/src/controllers/volunteer.ts index 7d4bb6f8..6e2c0330 100644 --- a/src/controllers/volunteer.ts +++ b/src/controllers/volunteer.ts @@ -43,8 +43,9 @@ const deleteVolunteer = async (volunteerId: number) => { return Volunteer.delete(volunteerId); } -const editVolunteer = async (payload: { name: string, id: string, email: string, password: string }) => { +const editVolunteer = async (payload: { name: string, id: string, email: string, oldPassword: string, newPassword: string }) => { const volunteer = await Volunteer.findOne({ where: { id: payload.id } }); + if (volunteer) { if (payload.name) volunteer.name = payload.name; @@ -52,8 +53,18 @@ const editVolunteer = async (payload: { name: string, id: string, email: string, if (payload.email) volunteer.email = payload.email; - if (payload.password) - volunteer.password = await bcrypt.hash(payload.password, 10); + if (payload.newPassword) { + if (!payload.oldPassword) { + throw "Old password is needed !"; + } + + const passwordMatching = await bcrypt.compare(payload.oldPassword, volunteer?.password || ''); + if (passwordMatching) { + volunteer.password = await bcrypt.hash(payload.newPassword, 10); + } else { + throw "The old password isn't correct !" + } + } return volunteer.save(); @@ -100,7 +111,7 @@ const login = async (email: string, name: string, id: string) => { const getVolunteers = async (payload: NSVolunteer.Item & { page: string; pageSize: string }) => { const page = parseInt(payload.page); const pageSize = parseInt(payload.pageSize); - const conditions: Record = {}; + const conditions: Record = {}; if (payload.id) { conditions["id"] = payload.id; @@ -139,7 +150,7 @@ const getVolunteers = async (payload: NSVolunteer.Item & { page: string; pageSiz const hasMatchingSkill = volunteer.volunteerProfile.skillTags.some((skillTag) => payload.skills.includes(skillTag.name)); return hasMatchingSkill; } - return true; + return true; }); const startIndex = (page - 1) * pageSize; const endIndex = startIndex + pageSize; diff --git a/src/routes/organizationProfile.ts b/src/routes/organizationProfile.ts index 7c689ca9..57821222 100644 --- a/src/routes/organizationProfile.ts +++ b/src/routes/organizationProfile.ts @@ -36,7 +36,7 @@ router.put("/:id", authorize("PUT_organizationProfile"),checkAdmin,validateOrgId }); }); -router.get('/', /*authorize("GET_organizationProfiles"),*/ async (req, res, next) => { +router.get('/', authorize("GET_organizationProfiles"), async (req, res, next) => { const payload = { page: req.query.page?.toString() || '1', pageSize: req.query.pageSize?.toString() || '10', From ac1743b9fc61bb8c21d41396d692498595ed7194 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Sat, 7 Oct 2023 20:58:27 +0300 Subject: [PATCH 069/146] Creat s3 configration and upload images to s3 bucket --- app.ts | 4 + package-lock.json | 303 +++++++++++++++++++++++++++++-- package.json | 3 + src/controllers/voluntaryWork.ts | 30 ++- src/routes/permission.ts | 2 +- src/routes/role.ts | 2 +- src/routes/voluntaryWork.ts | 3 +- src/routes/volunteer.ts | 8 +- src/utilites/AWS_configure_S3.ts | 22 +++ 9 files changed, 353 insertions(+), 24 deletions(-) create mode 100644 src/utilites/AWS_configure_S3.ts diff --git a/app.ts b/app.ts index 72282676..66222396 100644 --- a/app.ts +++ b/app.ts @@ -5,6 +5,8 @@ import createError from 'http-errors' import dataSource, { initDB } from './src/db/dataSource.js' import logger from 'morgan' import cookieParser from 'cookie-parser' +import fileUpload from 'express-fileupload'; + import indexRouter from "./src/routes/index.js" import permissionRouter from "./src/routes/permission.js" @@ -22,6 +24,8 @@ const PORT = process.env.PORT || 3000; app.use(express.json()); app.use(express.urlencoded({ extended: false })); app.use(cookieParser()); +app.use(fileUpload({ limits: { fileSize: 50 * 1024 * 1024 } })) + app.use('/', indexRouter); app.use('/permission', authenticate, permissionRouter); diff --git a/package-lock.json b/package-lock.json index 42c353fc..45833f2c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,12 +8,15 @@ "name": "serve-and-shine", "version": "1.0.0", "dependencies": { + "@types/express-fileupload": "^1.4.2", + "aws-sdk": "^2.1472.0", "bcrypt": "^5.1.1", "cookie-parser": "^1.4.6", "debug": "~2.6.9", "dotenv": "^16.3.1", "email-validator": "^2.0.4", "express": "^4.18.2", + "express-fileupload": "^1.4.1", "http-errors": "~1.6.3", "jade": "~1.11.0", "jest": "^29.7.0", @@ -2378,17 +2381,23 @@ "version": "1.19.3", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.3.tgz", "integrity": "sha512-oyl4jvAfTGX9Bt6Or4H9ni1Z447/tQuxnZsytsCaExKlmJiU8sFgnIBRzJUpKwB5eWn9HuBYlUlVA74q/yN0eQ==", - "dev": true, "dependencies": { "@types/connect": "*", "@types/node": "*" } }, + "node_modules/@types/busboy": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@types/busboy/-/busboy-1.5.1.tgz", + "integrity": "sha512-JAymE2skNionWnBUwby3MatzPUw4D/6/7FX1qxBXLzmRnFxmqU0luIof7om0I8R3B/rSr9FKUnFCqxZ/NeGbrw==", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/connect": { "version": "3.4.36", "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.36.tgz", "integrity": "sha512-P63Zd/JUGq+PdrM1lv0Wv5SBYeA2+CORvbrXbngriYY0jzLUWfQMQQxOhjONEz/wlHOAxOdY7CY65rgQdTjq2w==", - "dev": true, "dependencies": { "@types/node": "*" } @@ -2406,7 +2415,6 @@ "version": "4.17.18", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.18.tgz", "integrity": "sha512-Sxv8BSLLgsBYmcnGdGjjEjqET2U+AKAdCRODmMiq02FgjwuV75Ut85DRpvFjyw/Mk0vgUOliGRU0UUmuuZHByQ==", - "dev": true, "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^4.17.33", @@ -2414,11 +2422,19 @@ "@types/serve-static": "*" } }, + "node_modules/@types/express-fileupload": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@types/express-fileupload/-/express-fileupload-1.4.2.tgz", + "integrity": "sha512-m7j9veuCI02m0eyMfmZI7jrVU2CzH43U6EbAuzvCoBdhliXdIndb32cukcRTG4AOQONbe0MBmEcWvXAmQh9IMg==", + "dependencies": { + "@types/busboy": "*", + "@types/express": "*" + } + }, "node_modules/@types/express-serve-static-core": { "version": "4.17.37", "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.37.tgz", "integrity": "sha512-ZohaCYTgGFcOP7u6aJOhY9uIZQgZ2vxC2yWoArY+FeDXlqeH66ZVBjgvg+RLVAS/DWNq4Ap9ZXu1+SUQiiWYMg==", - "dev": true, "dependencies": { "@types/node": "*", "@types/qs": "*", @@ -2437,8 +2453,7 @@ "node_modules/@types/http-errors": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.2.tgz", - "integrity": "sha512-lPG6KlZs88gef6aD85z3HNkztpj7w2R7HmR3gygjfXCQmsLloWNARFkMuzKiiY8FGdh1XDpgBdrSf4aKDiA7Kg==", - "dev": true + "integrity": "sha512-lPG6KlZs88gef6aD85z3HNkztpj7w2R7HmR3gygjfXCQmsLloWNARFkMuzKiiY8FGdh1XDpgBdrSf4aKDiA7Kg==" }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.4", @@ -2483,8 +2498,7 @@ "node_modules/@types/mime": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", - "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", - "dev": true + "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" }, "node_modules/@types/morgan": { "version": "1.9.6", @@ -2503,20 +2517,17 @@ "node_modules/@types/qs": { "version": "6.9.8", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.8.tgz", - "integrity": "sha512-u95svzDlTysU5xecFNTgfFG5RUWu1A9P0VzgpcIiGZA9iraHOdSzcxMxQ55DyeRaGCSxQi7LxXDI4rzq/MYfdg==", - "dev": true + "integrity": "sha512-u95svzDlTysU5xecFNTgfFG5RUWu1A9P0VzgpcIiGZA9iraHOdSzcxMxQ55DyeRaGCSxQi7LxXDI4rzq/MYfdg==" }, "node_modules/@types/range-parser": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", - "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", - "dev": true + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" }, "node_modules/@types/send": { "version": "0.17.2", "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.2.tgz", "integrity": "sha512-aAG6yRf6r0wQ29bkS+x97BIs64ZLxeE/ARwyS6wrldMm3C1MdKwCcnnEwMC1slI8wuxJOpiUH9MioC0A0i+GJw==", - "dev": true, "dependencies": { "@types/mime": "^1", "@types/node": "*" @@ -2526,7 +2537,6 @@ "version": "1.15.3", "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.3.tgz", "integrity": "sha512-yVRvFsEMrv7s0lGhzrggJjNOSmZCdgCjw9xWrPr/kNNLp6FaDfMC1KaYl3TSJ0c58bECwNBMoQrZJ8hA8E1eFg==", - "dev": true, "dependencies": { "@types/http-errors": "*", "@types/mime": "*", @@ -2749,6 +2759,60 @@ "resolved": "https://registry.npmjs.org/asap/-/asap-1.0.0.tgz", "integrity": "sha512-Ej9qjcXY+8Tuy1cNqiwNMwFRXOy9UwgTeMA8LxreodygIPV48lx8PU1ecFxb5ZeU1DpMKxiq6vGLTxcitWZPbA==" }, + "node_modules/available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/aws-sdk": { + "version": "2.1472.0", + "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1472.0.tgz", + "integrity": "sha512-U7kAHRbvTy753IXKV8Oom/AqlqnsbXG+Kw5gRbKi6VcsZ3hR/EpNMzdRXTWO5U415bnLWGo8WAqIz67PIaaKsw==", + "dependencies": { + "buffer": "4.9.2", + "events": "1.1.1", + "ieee754": "1.1.13", + "jmespath": "0.16.0", + "querystring": "0.2.0", + "sax": "1.2.1", + "url": "0.10.3", + "util": "^0.12.4", + "uuid": "8.0.0", + "xml2js": "0.5.0" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/aws-sdk/node_modules/buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "dependencies": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "node_modules/aws-sdk/node_modules/ieee754": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" + }, + "node_modules/aws-sdk/node_modules/uuid": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.0.0.tgz", + "integrity": "sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/babel-jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", @@ -3111,6 +3175,17 @@ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" }, + "node_modules/busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "dependencies": { + "streamsearch": "^1.1.0" + }, + "engines": { + "node": ">=10.16.0" + } + }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -3793,6 +3868,14 @@ "node": ">= 0.6" } }, + "node_modules/events": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", + "integrity": "sha512-kEcvvCBByWXGnZy6JUlgAp2gBIUjfCAV6P6TgT1/aaQKcmuAEC4OZTV1I4EWQLz2gxZw76atuVyvHhTxvi0Flw==", + "engines": { + "node": ">=0.4.x" + } + }, "node_modules/execa": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", @@ -3879,6 +3962,17 @@ "node": ">= 0.10.0" } }, + "node_modules/express-fileupload": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/express-fileupload/-/express-fileupload-1.4.1.tgz", + "integrity": "sha512-9F6SkbxbEOA9cYOBZ8tnn238jL+bGfacQuUO/JqPWp5t+piUcoDcESvKwAXsQV7IHGxmI5bMj3QxMWOKOIsMCg==", + "dependencies": { + "busboy": "^1.6.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/express/node_modules/cookie": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", @@ -3960,6 +4054,14 @@ "node": ">=8" } }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dependencies": { + "is-callable": "^1.1.3" + } + }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -4128,6 +4230,17 @@ "node": ">=4" } }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -4179,6 +4292,20 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/has-unicode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", @@ -4357,6 +4484,21 @@ "node": ">= 0.10" } }, + "node_modules/is-arguments": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", @@ -4379,6 +4521,17 @@ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-core-module": { "version": "2.13.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", @@ -4415,6 +4568,20 @@ "node": ">=6" } }, + "node_modules/is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -4451,6 +4618,20 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-typed-array": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", + "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", + "dependencies": { + "which-typed-array": "^1.1.11" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -5110,6 +5291,14 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jmespath": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.16.0.tgz", + "integrity": "sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==", + "engines": { + "node": ">= 0.6.0" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -5998,6 +6187,11 @@ "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", "dev": true }, + "node_modules/punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==" + }, "node_modules/pure-rand": { "version": "6.0.4", "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.4.tgz", @@ -6027,6 +6221,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==", + "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", + "engines": { + "node": ">=0.4.x" + } + }, "node_modules/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", @@ -6297,6 +6500,11 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "node_modules/sax": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", + "integrity": "sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA==" + }, "node_modules/semver": { "version": "7.5.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", @@ -6532,6 +6740,14 @@ "node": ">= 0.8" } }, + "node_modules/streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -7184,6 +7400,27 @@ "browserslist": ">= 4.21.0" } }, + "node_modules/url": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", + "integrity": "sha512-hzSUW2q06EqL1gKM/a+obYHLIO6ct2hwPuviqTTOcfFVc61UbfJ2Q32+uGL/HCPxKqrdGB5QUwIe7UqlDgwsOQ==", + "dependencies": { + "punycode": "1.3.2", + "querystring": "0.2.0" + } + }, + "node_modules/util": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", + "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", + "dependencies": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "which-typed-array": "^1.1.2" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -7274,6 +7511,24 @@ "node": ">= 8" } }, + "node_modules/which-typed-array": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz", + "integrity": "sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==", + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/wide-align": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", @@ -7351,6 +7606,26 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, + "node_modules/xml2js": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz", + "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==", + "dependencies": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", + "engines": { + "node": ">=4.0" + } + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", diff --git a/package.json b/package.json index 542e3c0c..1dea7d67 100644 --- a/package.json +++ b/package.json @@ -13,12 +13,15 @@ "test": "tsc && jest" }, "dependencies": { + "@types/express-fileupload": "^1.4.2", + "aws-sdk": "^2.1472.0", "bcrypt": "^5.1.1", "cookie-parser": "^1.4.6", "debug": "~2.6.9", "dotenv": "^16.3.1", "email-validator": "^2.0.4", "express": "^4.18.2", + "express-fileupload": "^1.4.1", "http-errors": "~1.6.3", "jade": "~1.11.0", "jest": "^29.7.0", diff --git a/src/controllers/voluntaryWork.ts b/src/controllers/voluntaryWork.ts index 7cbb40fd..403be4bd 100644 --- a/src/controllers/voluntaryWork.ts +++ b/src/controllers/voluntaryWork.ts @@ -5,6 +5,8 @@ import { VoluntaryWork } from "../db/entities/VoluntaryWork.js"; import { getDate } from "./index.js"; import { Volunteer } from "../db/entities/Volunteer.js"; import { VolunteerProfile } from "../db/entities/VolunteerProfile.js"; +import { UploadedFile } from "express-fileupload"; +import { configureS3Bucket } from "../utilites/AWS_configure_S3.js"; const createVoluntaryWork = async (payload: NSVoluntaryWork.Item) => { let payloadDate = { ...payload, startedDate: getDate(payload.startedDate), finishedDate: getDate(payload.finishedDate) }; @@ -185,11 +187,33 @@ const putFeedback = async (id: number, feedback: string) => { } } -const putImages = async (id: number, images: string[]) => { +const putImages = async (id: number, uploadedFiles: UploadedFile[]) => { let voluntaryWork = await VoluntaryWork.findOne({ where: { id } }); if (voluntaryWork) { - voluntaryWork.images.push(...images); - await voluntaryWork.save(); + + try { + const S3 = await configureS3Bucket(); + const imageUrls = []; + + for (const file of uploadedFiles) { + const uploadParams = { + Bucket: process.env.AWS_BUCKET_NAME || '', + Body: Buffer.from(file.data), + Key: `${Date.now().toString()}.png`, + ACL: 'public-read', + }; + + const data = await S3.upload(uploadParams).promise(); + imageUrls.push(data.Location); + } + voluntaryWork.images.push(...imageUrls); + await voluntaryWork.save(); + } + catch(err){ + console.log(err); + return "Internet Error!"; + } + } else { throw "VoluntaryWork not found :("; } diff --git a/src/routes/permission.ts b/src/routes/permission.ts index 1a0f9aa7..de03d593 100644 --- a/src/routes/permission.ts +++ b/src/routes/permission.ts @@ -5,7 +5,7 @@ import { validatePermission, validatePermissionId } from '../middleware/validati var router = express.Router(); -router.post('/', authorize("GET_permissions"), validatePermission, (req, res, next) => { +router.post('/', authorize("POST_permissions"), validatePermission, (req, res, next) => { createPermission(req.body).then(() => { res.status(201).send("Permission created successfully!!") }).catch(err => { diff --git a/src/routes/role.ts b/src/routes/role.ts index c49e4d97..6f141ed5 100644 --- a/src/routes/role.ts +++ b/src/routes/role.ts @@ -37,7 +37,7 @@ router.put("/:id", authorize("PUT_role"),validateEditedRole, async (req, res, ne }); }); -router.get('/', authorize("DELETE_role"), async (req, res, next) => { +router.get('/', authorize("GET_roles"), async (req, res, next) => { const payload = { page: req.query.page?.toString() || '1', pageSize: req.query.pageSize?.toString() || '10', diff --git a/src/routes/voluntaryWork.ts b/src/routes/voluntaryWork.ts index a30f0341..b09a2efe 100644 --- a/src/routes/voluntaryWork.ts +++ b/src/routes/voluntaryWork.ts @@ -4,6 +4,7 @@ import { NSVolunteer } from '../../types/volunteer.js'; import { NSVoluntaryWork } from '../../types/voluntaryWork.js'; import { authorize, checkCreator, checkParticipation } from '../middleware/auth/authorize.js'; import { validateEditedVoluntaryWork, validateVoluntaryWork } from '../middleware/validation/voluntaryWork.js'; +import { UploadedFile } from 'express-fileupload'; var router = express.Router(); @@ -138,7 +139,7 @@ router.put("/feedback/:id", authorize("PUT_feedback"), checkParticipation, async }); router.put("/images/:id", authorize("PUT_images"), async (req, res, next) => { - putImages(Number(req.params.id), req.body.images).then(() => { + putImages(Number(req.params.id), ((Array.isArray(req.files?.image) ? req.files?.image : [req.files?.image]).filter(Boolean)) as UploadedFile[]).then(() => { res.status(201).send("Images added successfully!!") }).catch(err => { console.error(err); diff --git a/src/routes/volunteer.ts b/src/routes/volunteer.ts index c81f9a5b..17217eb1 100644 --- a/src/routes/volunteer.ts +++ b/src/routes/volunteer.ts @@ -52,7 +52,7 @@ router.delete('/:id', authenticate, authorize("DELETE_volunteer"), checkMe, asyn }); }) -router.put("/:id", authenticate, authorize("POST_volunteer"), checkMe, validateEditedVolunteer,async (req, res, next) => { +router.put("/:id", authenticate, authorize("POST_volunteer"), checkMe, validateEditedVolunteer, async (req, res, next) => { editVolunteer({ ...req.body, id: req.params.id?.toString() }).then(() => { res.status(201).send("Volunteer edited successfully!!") }).catch(err => { @@ -65,7 +65,7 @@ router.get('/', authenticate, authorize("GET_volunteers"), async (req, res, next const payload = { page: req.query.page?.toString() || '1', pageSize: req.query.pageSize?.toString() || '10', - id: req.query.id?.toString()|| "", + id: req.query.id?.toString() || "", name: req.query.name?.toString() || "", email: req.query.email?.toString() || "", availableLocation: req.query.availableLocation?.toString() || "", @@ -73,7 +73,7 @@ router.get('/', authenticate, authorize("GET_volunteers"), async (req, res, next type: req.query.status as NSVolunteer.TypeVolunteer, availableDays: (Array.isArray(req.query.availableDays) ? req.query.availableDays : [req.query.availableDays]).filter(Boolean) as NSVolunteer.AvailableDays[], availableTime: ((Array.isArray(req.query.availableTime) ? req.query.availableTime : [req.query.availableTime]).filter(Boolean)) as NSVolunteer.AvailableTime[], - password:"" + password: "" }; getVolunteers(payload) @@ -97,7 +97,7 @@ router.get("/logout", authenticate, (req, res, next) => { res.send("Logout correctly!"); }) -router.get('/me', authenticate, async (req, res, next) => { +router.get('/me', authenticate, authorize("GET_me"), async (req, res, next) => { if (res.locals.volunteer) { res.send(res.locals.volunteer); } else if (res.locals.organizationAdmin) { diff --git a/src/utilites/AWS_configure_S3.ts b/src/utilites/AWS_configure_S3.ts new file mode 100644 index 00000000..ffc1c958 --- /dev/null +++ b/src/utilites/AWS_configure_S3.ts @@ -0,0 +1,22 @@ +import AWS from 'aws-sdk'; + +const configureS3Bucket = async () => { + const accessKeyId = process.env.AWS_ACCESS_KEY_ID; + const secretAccessKey = process.env.AWS_SECRET_ACCESS_KEY; + + if (!accessKeyId || !secretAccessKey) { + throw 'AWS information to concent are missing :(' + } + + AWS.config.update({ + credentials: { + accessKeyId, + secretAccessKey, + }, + region: process.env.AWS_REGION, + }); + + return new AWS.S3(); +} + +export { configureS3Bucket }; \ No newline at end of file From def8a9486c7b878ad0d19087ffe38115f5c59f5d Mon Sep 17 00:00:00 2001 From: TarteelTamimi Date: Sat, 7 Oct 2023 22:56:52 +0300 Subject: [PATCH 070/146] complete error handling --- .gitignore | 3 +- app.ts | 47 +++++++++---- src/controllers/OrganizationProfile .ts | 5 +- src/controllers/organizationAdmin.ts | 9 +-- src/controllers/permission.ts | 3 +- src/controllers/role.ts | 3 +- src/controllers/voluntaryWork.ts | 19 ++--- src/controllers/volunteer.ts | 15 +++- src/db/entities/VoluntaryWork.ts | 2 +- src/middleware/auth/authenticate.ts | 7 +- src/middleware/auth/authorize.ts | 13 ++-- .../validation/organizationAdmin.ts | 4 +- .../validation/organizationProfile.ts | 4 +- src/middleware/validation/permission.ts | 4 +- src/middleware/validation/role.ts | 4 +- src/middleware/validation/voluntaryWork.ts | 4 +- src/middleware/validation/volunteer.ts | 6 +- src/routes/organizationAdmin.ts | 30 ++++---- src/routes/organizationProfile.ts | 28 ++++---- src/routes/permission.ts | 28 ++++---- src/routes/role.ts | 28 ++++---- src/routes/voluntaryWork.ts | 70 +++++++++++-------- src/routes/volunteer.ts | 28 ++++---- 23 files changed, 221 insertions(+), 143 deletions(-) diff --git a/.gitignore b/.gitignore index a0d218e3..fb86b3ce 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ node_modules dist -.env \ No newline at end of file +.env +.env.test \ No newline at end of file diff --git a/app.ts b/app.ts index 72282676..42bf0241 100644 --- a/app.ts +++ b/app.ts @@ -23,28 +23,45 @@ app.use(express.json()); app.use(express.urlencoded({ extended: false })); app.use(cookieParser()); -app.use('/', indexRouter); -app.use('/permission', authenticate, permissionRouter); -app.use('/role', authenticate, roleRouter); -app.use('/voluntaryWork', authenticate, voluntaryWorkRouter); -app.use('/organizationAdmin', authenticate, organizationAdminRouter); -app.use('/organizationProfile', authenticate, organizationProfileRouter); -app.use("/volunteer", volunteerRouter); - // catch 404 and forward to error handler app.use(function (req, res, next) { next(createError(404)); }); +const errorHandler = ( + error: any, + req: express.Request, + res: express.Response, + next: express.NextFunction) => { + if (error.status == 404) { + res.status(404).send("Something is not found"); + } else if (error.status == 401) { + res.status(401).send("You are unautharized"); + } else if (error.status == 403) { + res.status(401).send("You don't have the permission"); + } else { + res.status(500).send('Something went wrong'); + } +} + // error handler -app.use(function (err: any, req: any, res: any, next: any) { - // set locals, only providing error in development - res.locals.message = err.message; - res.locals.error = req.app.get('env') === 'development' ? err : {}; +// app.use(function (err: any, req: any, res: any, next: any) { +// // set locals, only providing error in development +// res.locals.message = err.message; +// res.locals.error = req.app.get('env') === 'development' ? err : {}; - // render the error page - res.status(err.status || 500).send({ error: err.message }); -}); +// // render the error page +// res.status(err.status || 500).send({ error: err.message }); +// }); + +app.use('/', indexRouter); +app.use('/permission', authenticate, permissionRouter); +app.use('/role', authenticate, roleRouter); +app.use('/voluntaryWork', authenticate, voluntaryWorkRouter); +app.use('/organizationAdmin', authenticate, organizationAdminRouter); +app.use('/organizationProfile', authenticate, organizationProfileRouter); +app.use("/volunteer", volunteerRouter); +app.use(errorHandler); app.listen(PORT, () => { logger(`App is listening on port ${PORT}`); diff --git a/src/controllers/OrganizationProfile .ts b/src/controllers/OrganizationProfile .ts index c4cf8c13..f8185397 100644 --- a/src/controllers/OrganizationProfile .ts +++ b/src/controllers/OrganizationProfile .ts @@ -1,6 +1,7 @@ import { NSOrganizationProfile } from "../../types/organizationProfile.js"; import { OrganizationAdmin } from "../db/entities/OrganizationAdmin.js"; import { OrganizationProfile } from "../db/entities/OrganizationProfile.js"; +import createError from 'http-errors'; const createOrganizationProfile = async (payload: NSOrganizationProfile.Item) => { @@ -16,7 +17,7 @@ const editOrganizationProfile = async (payload: { id: string, name: string, desc profile = Object.assign(profile, payload); return profile.save(); } else { - throw "Organization profile not found :("; + throw createError(404); } } @@ -49,7 +50,7 @@ const getOrganizationProfile = async (payload: { if (admin) { return admin; } else { - throw "Admin name not found :("; + throw createError(404); } } diff --git a/src/controllers/organizationAdmin.ts b/src/controllers/organizationAdmin.ts index 21d1d8fa..c1823a1f 100644 --- a/src/controllers/organizationAdmin.ts +++ b/src/controllers/organizationAdmin.ts @@ -2,6 +2,7 @@ import { NSOrganizationAdmin } from "../../types/organizationAdmin.js"; import { OrganizationAdmin } from "../db/entities/OrganizationAdmin.js"; import { OrganizationProfile } from "../db/entities/OrganizationProfile.js"; import bcrypt from 'bcrypt'; +import createError from 'http-errors'; const createOrganizationAdmin = async (payload: NSOrganizationAdmin.Item) => { @@ -15,7 +16,7 @@ const createOrganizationAdmin = async (payload: NSOrganizationAdmin.Item) => { newOrganizationAdmin.orgProfile = organization; return newOrganizationAdmin.save(); } else { - throw "Organization not found :("; + throw createError(404); } } @@ -46,7 +47,7 @@ const getOrganizationAdmins = async (payload: { return await OrganizationAdmin.findOne({ where: { orgProfile: { id: organization.id } } }); } else { - throw "Organization name not found :("; + throw createError(404); } } @@ -66,7 +67,7 @@ const getOrganizationAdmins = async (payload: { }; } -const deleteOrganizationAdmin = async (adminId: number) => { +const deleteOrganizationAdmin = async (adminId: string) => { return OrganizationAdmin.delete(adminId); } @@ -104,7 +105,7 @@ const editOrganizationAdmin = async (payload: { id: string, name: string, email: } else { - throw "Organization admin not found :("; + throw createError(404); } } diff --git a/src/controllers/permission.ts b/src/controllers/permission.ts index fc4bb95a..f8c4c50f 100644 --- a/src/controllers/permission.ts +++ b/src/controllers/permission.ts @@ -1,5 +1,6 @@ import { NSPermission } from "../../types/permission.js"; import { Permission } from "../db/entities/Permission.js" +import createError from 'http-errors'; const createPermission = async (payload: NSPermission.Item) => { try { @@ -24,7 +25,7 @@ const editPermission = async (payload: { name: string, id: number }) => { permission.name = payload.name; return permission.save(); } else { - throw "Permission not found :("; + throw createError(404); } } diff --git a/src/controllers/role.ts b/src/controllers/role.ts index c50259a1..c14bb3d3 100644 --- a/src/controllers/role.ts +++ b/src/controllers/role.ts @@ -2,6 +2,7 @@ import { In } from "typeorm"; import { NSRole } from "../../types/role.js"; import { Permission } from "../db/entities/Permission.js"; import { Role } from "../db/entities/Role.js"; +import createError from 'http-errors'; const createRole = async (payload: NSRole.Item) => { try { @@ -30,7 +31,7 @@ const editRole = async (payload: { name: NSRole.Type, id: number }) => { return role.save(); } else { - throw "Role not found :("; + throw createError(404); } } diff --git a/src/controllers/voluntaryWork.ts b/src/controllers/voluntaryWork.ts index 7cbb40fd..855c52b5 100644 --- a/src/controllers/voluntaryWork.ts +++ b/src/controllers/voluntaryWork.ts @@ -5,6 +5,7 @@ import { VoluntaryWork } from "../db/entities/VoluntaryWork.js"; import { getDate } from "./index.js"; import { Volunteer } from "../db/entities/Volunteer.js"; import { VolunteerProfile } from "../db/entities/VolunteerProfile.js"; +import createError from 'http-errors'; const createVoluntaryWork = async (payload: NSVoluntaryWork.Item) => { let payloadDate = { ...payload, startedDate: getDate(payload.startedDate), finishedDate: getDate(payload.finishedDate) }; @@ -53,7 +54,7 @@ const editVoluntaryWork = async (payload: NSVoluntaryWork.Edit) => { return voluntaryWork.save(); } else { - throw "VoluntaryWork not found :("; + throw createError(404); } } @@ -171,7 +172,7 @@ const putRating = async (id: number, rating: number) => { voluntaryWork.rating /= 2; return voluntaryWork.save(); } else { - throw "VoluntaryWork not found :("; + throw createError(404); } } @@ -181,7 +182,7 @@ const putFeedback = async (id: number, feedback: string) => { voluntaryWork.feedback.push(feedback); await voluntaryWork.save(); } else { - throw "VoluntaryWork not found :("; + throw createError(404); } } @@ -191,14 +192,14 @@ const putImages = async (id: number, images: string[]) => { voluntaryWork.images.push(...images); await voluntaryWork.save(); } else { - throw "VoluntaryWork not found :("; + throw createError(404); } } const registerByVolunteer = async (workId: number, volunteerProfile: Volunteer["volunteerProfile"]) => { const voluntaryWork = await VoluntaryWork.findOne({ where: { id: workId } }); if (!voluntaryWork) { - throw new Error("VoluntaryWork not found"); + throw createError(404); } if ( @@ -225,10 +226,10 @@ const registerByOrganizationAdmin = async (workId: number, volunteerId: string) const volunteer = await Volunteer.findOne({ where: { id: volunteerId } }); if (!voluntaryWork) { - throw new Error("VoluntaryWork not found"); + throw createError(404); } if (!volunteer) { - throw new Error("Volunteer not found"); + throw createError(404); } voluntaryWork.volunteerProfiles.push(volunteer.volunteerProfile); @@ -242,11 +243,11 @@ const deregisterVoluntaryWork = async (workId: number, volunteerId: string) => { const volunteer = await Volunteer.findOne({ where: { id: volunteerId } }); if (!voluntaryWork) { - throw new Error("VoluntaryWork not found"); + throw createError(404); } if (!volunteer) { - throw new Error("Volunteer not found"); + throw createError(404); } const index = voluntaryWork.volunteerProfiles.findIndex(profile => profile.id === volunteer.volunteerProfile.id); diff --git a/src/controllers/volunteer.ts b/src/controllers/volunteer.ts index 6e2c0330..88819740 100644 --- a/src/controllers/volunteer.ts +++ b/src/controllers/volunteer.ts @@ -7,6 +7,7 @@ import jwt from 'jsonwebtoken'; import bcrypt from 'bcrypt'; import { SkillTag } from "../db/entities/SkillTag.js"; import { In, Like } from "typeorm"; +import createError from 'http-errors'; const createVolunteer = async (payload: NSVolunteer.Item) => { @@ -39,8 +40,16 @@ const createVolunteer = async (payload: NSVolunteer.Item) => { }); }; -const deleteVolunteer = async (volunteerId: number) => { - return Volunteer.delete(volunteerId); +const deleteVolunteer = async (volunteerId: string) => { + const volunteer = await Volunteer.findOne({ + where: { id: volunteerId }, + }); + + if (volunteer) { + return Volunteer.delete(volunteerId); + } else { + throw createError(404); + } } const editVolunteer = async (payload: { name: string, id: string, email: string, oldPassword: string, newPassword: string }) => { @@ -69,7 +78,7 @@ const editVolunteer = async (payload: { name: string, id: string, email: string, return volunteer.save(); } else { - throw "Volunteer not found :("; + throw createError(404); } } diff --git a/src/db/entities/VoluntaryWork.ts b/src/db/entities/VoluntaryWork.ts index 03267a94..4a40343b 100644 --- a/src/db/entities/VoluntaryWork.ts +++ b/src/db/entities/VoluntaryWork.ts @@ -34,7 +34,7 @@ export class VoluntaryWork extends BaseEntity { @Column({ nullable: false, type: "timestamp" }) startedDate: Date; - @Column({ nullable: false, type: "timestamp" }) + @Column({ nullable: true, type: "timestamp" }) finishedDate: Date; @Column({ diff --git a/src/middleware/auth/authenticate.ts b/src/middleware/auth/authenticate.ts index cbee6139..729db7de 100644 --- a/src/middleware/auth/authenticate.ts +++ b/src/middleware/auth/authenticate.ts @@ -2,6 +2,7 @@ import express from 'express'; import jwt, { JwtPayload } from 'jsonwebtoken'; import { OrganizationAdmin } from '../../db/entities/OrganizationAdmin.js'; import { Volunteer } from '../../db/entities/Volunteer.js'; +import createError from 'http-errors'; const authenticate = async ( req: express.Request, @@ -36,10 +37,12 @@ const authenticate = async ( res.locals.volunteer = volunteer; next(); } else { - res.status(401).send("You are Unauthorized!"); + //res.status(401).send("You are Unauthorized!"); + next(createError(401)); } } else { - res.status(401).send("You are Unauthorized!"); + //res.status(401).send("You are Unauthorized!"); + next(createError(401)); } } diff --git a/src/middleware/auth/authorize.ts b/src/middleware/auth/authorize.ts index 1f8a9395..cc543c91 100644 --- a/src/middleware/auth/authorize.ts +++ b/src/middleware/auth/authorize.ts @@ -5,6 +5,7 @@ import { Volunteer } from '../../db/entities/Volunteer.js'; import { OrganizationProfile } from '../../db/entities/OrganizationProfile.js'; import { VoluntaryWork } from '../../db/entities/VoluntaryWork.js'; import { VolunteerProfile } from '../../db/entities/VolunteerProfile.js'; +import createError from 'http-errors'; const authorize = (api: string) => { return async ( @@ -43,13 +44,13 @@ const checkMe = () => { const id = req.params.id; if (res.locals.volunteer) { if (res.locals.volunteer.id == id) { - next() + next(createError(403)); } } else if (res.locals.organizationAdmin) { if (res.locals.organizationAdmin.id == id) { next(); } else { - res.status(403).send("You don't have the permission to access this resource!"); + next(createError(401)); } } } @@ -69,7 +70,7 @@ const checkAdmin = () => { next(); } } else { - res.status(403).send("You don't have the permission to access this resource!"); + next() } } } @@ -92,7 +93,7 @@ const checkCreator = () => { next(); } } else { - res.status(403).send("You don't have the permission to access this resource!"); + next(createError(401)); } } } @@ -108,7 +109,7 @@ const c1heckParticipation = () => { if(res.locals.volunteer) { const volunteer:Volunteer=res.locals.volunteer; }else { - res.status(403).send("You don't have the permission to access this resource!"); + next(createError(401)); } } } @@ -136,7 +137,7 @@ const checkParticipation = () => { } } } - res.status(403).send("You don't have permission to access this resource."); + next(createError(401)); }; }; diff --git a/src/middleware/validation/organizationAdmin.ts b/src/middleware/validation/organizationAdmin.ts index 595a1243..1cdf85c1 100644 --- a/src/middleware/validation/organizationAdmin.ts +++ b/src/middleware/validation/organizationAdmin.ts @@ -2,6 +2,7 @@ import express from 'express'; import * as EmailValidator from 'email-validator'; import { isValidPassword } from '../../controllers/index.js'; import { OrganizationAdmin } from '../../db/entities/OrganizationAdmin.js'; +import createError from 'http-errors'; const validateOrganizationAdmin = (req: express.Request, @@ -35,7 +36,8 @@ const validateAdminEdited = async (req: express.Request, const id = req.params.id.toString(); const v = await OrganizationAdmin.findOne({ where: { id } }); if (!v) { - res.status(400).send("Id not valid"); + //res.status(400).send("Id not valid"); + next(createError(404)); } if (organizationAdmin.email){ diff --git a/src/middleware/validation/organizationProfile.ts b/src/middleware/validation/organizationProfile.ts index d34c2047..7e227350 100644 --- a/src/middleware/validation/organizationProfile.ts +++ b/src/middleware/validation/organizationProfile.ts @@ -1,5 +1,6 @@ import express from 'express'; import { OrganizationProfile } from '../../db/entities/OrganizationProfile.js'; +import createError from 'http-errors'; const validateOrganizationProfile = (req: express.Request, res: express.Response, @@ -23,7 +24,8 @@ const validateOrgId = async (req: express.Request, const id = req.params.id.toString(); const v = await OrganizationProfile.findOne({ where: { id } }); if (!v) { - res.status(400).send("Id not valid"); + //res.status(400).send("Id not valid"); + next(createError(404)); }else{ next(); } diff --git a/src/middleware/validation/permission.ts b/src/middleware/validation/permission.ts index 44cc15c3..ca9b07f9 100644 --- a/src/middleware/validation/permission.ts +++ b/src/middleware/validation/permission.ts @@ -1,5 +1,6 @@ import express from 'express'; import { Permission } from '../../db/entities/Permission.js'; +import createError from 'http-errors'; const validatePermission = (req: express.Request, res: express.Response, @@ -23,7 +24,8 @@ const validatePermissionId = async (req: express.Request, const id = Number(req.params.id.toString()); const p = await Permission.findOne({ where: { id } }); if (!p) { - res.status(400).send("Id not valid"); + //res.status(400).send("Id not valid"); + next(createError(404)); }else{ next(); } diff --git a/src/middleware/validation/role.ts b/src/middleware/validation/role.ts index 0eff4143..364dff09 100644 --- a/src/middleware/validation/role.ts +++ b/src/middleware/validation/role.ts @@ -1,5 +1,6 @@ import express from 'express'; import { Role } from '../../db/entities/Role.js'; +import createError from 'http-errors'; const validateRole = (req: express.Request, res: express.Response, @@ -30,7 +31,8 @@ const validateEditedRole = async (req: express.Request, const id = Number(req.params.id.toString()); const r = await Role.findOne({ where: { id } }); if (!r) { - res.status(400).send("Id not valid"); + //res.status(400).send("Id not valid"); + next(createError(404)); } if (role.name){ diff --git a/src/middleware/validation/voluntaryWork.ts b/src/middleware/validation/voluntaryWork.ts index ee6a4b7d..d84c80fd 100644 --- a/src/middleware/validation/voluntaryWork.ts +++ b/src/middleware/validation/voluntaryWork.ts @@ -3,6 +3,7 @@ import { NSVoluntaryWork } from '../../../types/voluntaryWork.js'; import { NSVolunteer } from '../../../types/volunteer.js'; import { getDate, isValidDate } from '../../controllers/index.js'; import { VoluntaryWork } from '../../db/entities/VoluntaryWork.js'; +import createError from 'http-errors'; const validateVoluntaryWork = (req: express.Request, res: express.Response, @@ -54,7 +55,8 @@ const validateEditedVoluntaryWork = async (req: express.Request, const id = Number(req.params.id.toString()); const vw = await VoluntaryWork.findOne({where:{id}}); if(!vw){ - res.status(400).send("Id not valid"); + //res.status(400).send("Id not valid"); + next(createError(404)); } if (voluntaryWork.status) { diff --git a/src/middleware/validation/volunteer.ts b/src/middleware/validation/volunteer.ts index b7c7e295..a1f4a31d 100644 --- a/src/middleware/validation/volunteer.ts +++ b/src/middleware/validation/volunteer.ts @@ -3,6 +3,7 @@ import * as EmailValidator from 'email-validator'; import { isValidPassword } from '../../controllers/index.js'; import { NSVolunteer } from '../../../types/volunteer.js'; import { Volunteer } from '../../db/entities/Volunteer.js'; +import createError from 'http-errors' const validateVolunteer = (req: express.Request, res: express.Response, next: express.NextFunction) => { @@ -20,7 +21,7 @@ const validateVolunteer = (req: express.Request, res: express.Response, next: ex errorList.push('Email is not valid.'); } - if (volunteer.type){ + if (volunteer.type) { const validType = Object.values(NSVolunteer.TypeVolunteer).includes(volunteer.type); if (!validType) { errorList.push("Invalid type!"); @@ -53,7 +54,8 @@ const validateEditedVolunteer = async (req: express.Request, res: express.Respon const id = req.params.id.toString(); const v = await Volunteer.findOne({ where: { id } }); if (!v) { - res.status(400).send("Id not valid"); + //res.status(400).send("Id not valid"); + next(createError(404)); } if (volunteer.email) { diff --git a/src/routes/organizationAdmin.ts b/src/routes/organizationAdmin.ts index 825b1e2b..b215f177 100644 --- a/src/routes/organizationAdmin.ts +++ b/src/routes/organizationAdmin.ts @@ -9,21 +9,23 @@ router.post('/', authorize("POST_organizationAdmin"), validateOrganizationAdmin, createOrganizationAdmin(req.body).then(() => { res.status(201).send("Organization Admin created successfully!!") }).catch(err => { - console.error(err); - res.status(500).send(err); + // console.error(err); + // res.status(500).send(err); + next(err); }); }); -router.delete('/:id', authorize("DELETE_organizationAdmin"), checkMe, async (req, res) => { - const id = Number(req.params.id?.toString()); +router.delete('/:id', authorize("DELETE_organizationAdmin"), checkMe, async (req, res, next) => { + const id = req.params.id?.toString(); deleteOrganizationAdmin(id) .then(data => { - res.send(data); + res.send("Deleted"); }) - .catch(error => { - console.error(error); - res.status(500).send('Something went wrong'); + .catch(err => { + // console.error(error); + // res.status(500).send('Something went wrong'); + next(err); }); }); @@ -31,8 +33,9 @@ router.put("/:id", authorize("PUT_organizationAdmin"), checkMe, validateAdminEdi editOrganizationAdmin({ ...req.body, id: req.params.id }).then(() => { res.status(201).send("Organization Admin edited successfully!!") }).catch(err => { - console.error(err); - res.status(500).send(err); + // console.error(err); + // res.status(500).send(err); + next(err); }); }); @@ -50,9 +53,10 @@ router.get('/', authorize("GET_organizationAdmins"), async (req, res, next) => { .then(data => { res.send(data); }) - .catch(error => { - console.error(error); - res.status(500).send(error); + .catch(err => { + // console.error(error); + // res.status(500).send(error); + next(err); }); }); diff --git a/src/routes/organizationProfile.ts b/src/routes/organizationProfile.ts index 57821222..4d3e070e 100644 --- a/src/routes/organizationProfile.ts +++ b/src/routes/organizationProfile.ts @@ -9,21 +9,23 @@ router.post('/', authorize("POST_organizationProfile"), validateOrganizationProf createOrganizationProfile(req.body).then(() => { res.status(201).send("Organization Profile created successfully!!") }).catch(err => { - console.error(err); - res.status(500).send(err); + // console.error(err); + // res.status(500).send(err); + next(err); }); }); -router.delete('/:id', authorize("DELETE_organizationProfile"), checkAdmin, async (req, res) => { +router.delete('/:id', authorize("DELETE_organizationProfile"), checkAdmin, async (req, res, next) => { const id = Number(req.params.id?.toString()); deleteOrganizationProfile(id) .then(data => { - res.send(data); + res.send("Deleted"); }) - .catch(error => { - console.error(error); - res.status(500).send('Something went wrong'); + .catch(err => { + // console.error(error); + // res.status(500).send('Something went wrong'); + next(err); }); }); @@ -31,8 +33,9 @@ router.put("/:id", authorize("PUT_organizationProfile"),checkAdmin,validateOrgId editOrganizationProfile(req.body).then(() => { res.status(201).send("Organization Profile edited successfully!!") }).catch(err => { - console.error(err); - res.status(500).send(err); + // console.error(err); + // res.status(500).send(err); + next(err); }); }); @@ -49,9 +52,10 @@ router.get('/', authorize("GET_organizationProfiles"), async (req, res, next) => .then(data => { res.send(data); }) - .catch(error => { - console.error(error); - res.status(500).send(error); + .catch(err => { + // console.error(error); + // res.status(500).send(error); + next(err); }); }); diff --git a/src/routes/permission.ts b/src/routes/permission.ts index 1a0f9aa7..a86487dd 100644 --- a/src/routes/permission.ts +++ b/src/routes/permission.ts @@ -9,21 +9,23 @@ router.post('/', authorize("GET_permissions"), validatePermission, (req, res, ne createPermission(req.body).then(() => { res.status(201).send("Permission created successfully!!") }).catch(err => { - console.error(err); - res.status(500).send(err); + // console.error(err); + // res.status(500).send(err); + next(err); }); }); -router.delete('/:id', authorize("DELETE_permission"), async (req, res) => { +router.delete('/:id', authorize("DELETE_permission"), async (req, res, next) => { const id = Number(req.params.id?.toString()); deletePermission(id) .then(data => { - res.send(data); + res.send("Deleted"); }) - .catch(error => { - console.error(error); - res.status(500).send('Something went wrong'); + .catch(err => { + // console.error(error); + // res.status(500).send('Something went wrong'); + next(err); }); }) @@ -31,8 +33,9 @@ router.put("/:id", authorize("PUT_permission"), validatePermissionId, async (req editPermission({ ...req.body, id: req.params.id?.toString() }).then(() => { res.status(201).send("Permission edited successfully!!") }).catch(err => { - console.error(err); - res.status(500).send(err); + // console.error(err); + // res.status(500).send(err); + next(err); }); }); @@ -48,9 +51,10 @@ router.get('/', authorize("GET_permissions"), async (req, res, next) => { .then(data => { res.send(data); }) - .catch(error => { - console.error(error); - res.status(500).send('Something went wrong'); + .catch(err => { + // console.error(error); + // res.status(500).send('Something went wrong'); + next(err); }); }); diff --git a/src/routes/role.ts b/src/routes/role.ts index c49e4d97..f6d4c27b 100644 --- a/src/routes/role.ts +++ b/src/routes/role.ts @@ -10,21 +10,23 @@ router.post('/', authorize("POST_role"), validateRole, (req, res, next) => { createRole(req.body).then(() => { res.status(201).send("Role created successfully!!") }).catch(err => { - console.error(err); - res.status(500).send(err); + // console.error(err); + // res.status(500).send(err); + next(err); }); }); -router.delete('/:id', authorize("DELETE_role"), async (req, res) => { +router.delete('/:id', authorize("DELETE_role"), async (req, res, next) => { const id = Number(req.params.id?.toString()); deleteRole(id) .then(data => { - res.send(data); + res.send("Deleted"); }) - .catch(error => { - console.error(error); - res.status(500).send('Something went wrong'); + .catch(err => { + // console.error(error); + // res.status(500).send('Something went wrong'); + next(err); }); }) @@ -32,8 +34,9 @@ router.put("/:id", authorize("PUT_role"),validateEditedRole, async (req, res, ne editRole({ ...req.body, id: req.params.id?.toString() }).then(() => { res.status(201).send("Role edited successfully!!") }).catch(err => { - console.error(err); - res.status(500).send(err); + // console.error(err); + // res.status(500).send(err); + next(err); }); }); @@ -49,9 +52,10 @@ router.get('/', authorize("DELETE_role"), async (req, res, next) => { .then(data => { res.send(data); }) - .catch(error => { - console.error(error); - res.status(500).send('Something went wrong'); + .catch(err => { + // console.error(error); + // res.status(500).send('Something went wrong'); + next(err); }); }); diff --git a/src/routes/voluntaryWork.ts b/src/routes/voluntaryWork.ts index a30f0341..91746d70 100644 --- a/src/routes/voluntaryWork.ts +++ b/src/routes/voluntaryWork.ts @@ -11,20 +11,22 @@ router.post('/', authorize("POST_voluntaryWork"), validateVoluntaryWork, (req, r createVoluntaryWork({ ...req.body, creatorId: res.locals.volunteer.id || res.locals.organizationAdmin.id }).then(() => { res.status(201).send("Voluntary work created successfully!!") }).catch(err => { - console.error(err); - res.status(500).send(err); + // console.error(err); + // res.status(500).send(err); + next(err); }); }); -router.delete('/:id', authorize("DELETE_voluntaryWork"), checkCreator, async (req, res) => { +router.delete('/:id', authorize("DELETE_voluntaryWork"), checkCreator, async (req, res, next) => { const id = Number(req.params.id?.toString()); deleteVoluntaryWork(id) .then(data => { - res.send(data); + res.send("Deleted"); }) - .catch(error => { - res.status(500).send('Something went wrong'); + .catch(err => { + // res.status(500).send('Something went wrong'); + next(err); }); }) @@ -32,8 +34,9 @@ router.put("/:id", authorize("PUT_voluntaryWork"), checkCreator,validateEditedVo editVoluntaryWork({ ...req.body, id: req.params.id?.toString() }).then(() => { res.status(201).send("Voluntary Work edited successfully!!") }).catch(err => { - console.error(err); - res.status(500).send(err); + // console.error(err); + // res.status(500).send(err); + next(err); }); }); @@ -66,9 +69,10 @@ router.get('/', authorize("GET_voluntaryWorks"), async (req, res, next) => { .then(data => { res.send(data); }) - .catch(error => { - console.error(error); - res.status(500).send('Something went wrong'); + .catch(err => { + // console.error(error); + // res.status(500).send('Something went wrong'); + next(err); }); }); @@ -101,9 +105,10 @@ router.get('/analysis', authorize("GET_analysis"), async (req, res, next) => { .then(data => { res.send(data); }) - .catch(error => { - console.error(error); - res.status(500).send('Something went wrong'); + .catch(err => { + // console.error(error); + // res.status(500).send('Something went wrong'); + next(err); }); }); @@ -113,9 +118,10 @@ router.get('/recommendation', authorize("GET_recommendation"), async (req, res, .then(data => { res.send(data); }) - .catch(error => { - console.error(error); - res.status(500).send('Something went wrong'); + .catch(err => { + // console.error(error); + // res.status(500).send('Something went wrong'); + next(err); }); }); @@ -123,8 +129,9 @@ router.put("/rating/:id", authorize("PUT_rating"), checkParticipation, async (re putRating(Number(req.params.id), Number(req.body.rating)).then(() => { res.status(201).send("Rating added successfully!!") }).catch(err => { - console.error(err); - res.status(500).send(err); + // console.error(err); + // res.status(500).send(err); + next(err); }); }); @@ -132,8 +139,9 @@ router.put("/feedback/:id", authorize("PUT_feedback"), checkParticipation, async putFeedback(Number(req.params.id), req.body.feedback).then(() => { res.status(201).send("Feedback added successfully!!") }).catch(err => { - console.error(err); - res.status(500).send(err); + // console.error(err); + // res.status(500).send(err); + next(err); }); }); @@ -141,8 +149,9 @@ router.put("/images/:id", authorize("PUT_images"), async (req, res, next) => { putImages(Number(req.params.id), req.body.images).then(() => { res.status(201).send("Images added successfully!!") }).catch(err => { - console.error(err); - res.status(500).send(err); + // console.error(err); + // res.status(500).send(err); + next(err); }); }); @@ -151,8 +160,9 @@ router.put("/register/:id", authorize("REGISTER_voluntaryWork"), async (req, res registerByVolunteer(Number(req.params.id), res.locals.volunteer["volunteerProfile"]).then(() => { res.status(201).send("Registration done successfully!!") }).catch(err => { - console.error(err); - res.status(500).send(err); + // console.error(err); + // res.status(500).send(err); + next(err); }); } else if (res.locals.organizationAdmin) { if (!req.body.volunteerId.toString()) { @@ -162,8 +172,9 @@ router.put("/register/:id", authorize("REGISTER_voluntaryWork"), async (req, res registerByOrganizationAdmin(Number(req.params.id), req.body.volunteerId.toString()).then(() => { res.status(201).send("Registration done successfully!!") }).catch(err => { - console.error(err); - res.status(500).send(err); + // console.error(err); + // res.status(500).send(err); + next(err); }); } }); @@ -175,8 +186,9 @@ router.put("/deregister/:id", authorize("DEREGISTER_voluntaryWork"), async (req, deregisterVoluntaryWork(Number(req.params.id), res.locals.volunteer.id || req.body.volunteerId.toString()).then(() => { res.status(201).send("Deregistration done successfully!!") }).catch(err => { - console.error(err); - res.status(500).send(err); + // console.error(err); + // res.status(500).send(err); + next(err); }); }); diff --git a/src/routes/volunteer.ts b/src/routes/volunteer.ts index c81f9a5b..3a032ec5 100644 --- a/src/routes/volunteer.ts +++ b/src/routes/volunteer.ts @@ -11,8 +11,9 @@ router.post('/register', validateVolunteer, (req, res, next) => { createVolunteer(req.body).then(() => { res.status(201).send("Volunteer created successfully!!") }).catch(err => { - console.error(err); - res.status(500).send(err); + // console.error(err); + // res.status(500).send(err); + next(err); }); }); @@ -39,16 +40,15 @@ router.post('/login', (req, res, next) => { }) }); -router.delete('/:id', authenticate, authorize("DELETE_volunteer"), checkMe, async (req, res) => { - const id = Number(req.params.id?.toString()); +router.delete('/:id', authenticate, authorize("DELETE_volunteer"), checkMe, async (req, res, next) => { + const id = req.params.id?.toString(); deleteVolunteer(id) .then(data => { - res.send(data); + res.send("Deleted"); }) .catch(error => { - console.error(error); - res.status(500).send('Something went wrong'); + next(error); }); }) @@ -56,12 +56,13 @@ router.put("/:id", authenticate, authorize("POST_volunteer"), checkMe, validateE editVolunteer({ ...req.body, id: req.params.id?.toString() }).then(() => { res.status(201).send("Volunteer edited successfully!!") }).catch(err => { - console.error(err); - res.status(500).send(err); + // console.error(err); + // res.status(500).send(err); + next(err); }); }); -router.get('/', authenticate, authorize("GET_volunteers"), async (req, res, next) => { +router.get('/', /*authenticate, authorize("GET_volunteers"), */async (req, res, next) => { const payload = { page: req.query.page?.toString() || '1', pageSize: req.query.pageSize?.toString() || '10', @@ -80,9 +81,10 @@ router.get('/', authenticate, authorize("GET_volunteers"), async (req, res, next .then(data => { res.send(data); }) - .catch(error => { - console.error(error); - res.status(500).send('Something went wrong'); + .catch(err => { + // console.error(error); + // res.status(500).send('Something went wrong'); + next(err); }); }); From 9f7bb189c417c5a14a032264f6c07b6bae5a7b06 Mon Sep 17 00:00:00 2001 From: TarteelTamimi Date: Sat, 7 Oct 2023 23:14:09 +0300 Subject: [PATCH 071/146] solve the conflict --- src/controllers/voluntaryWork.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/controllers/voluntaryWork.ts b/src/controllers/voluntaryWork.ts index 855c52b5..083f66c1 100644 --- a/src/controllers/voluntaryWork.ts +++ b/src/controllers/voluntaryWork.ts @@ -4,7 +4,12 @@ import { SkillTag } from "../db/entities/SkillTag.js"; import { VoluntaryWork } from "../db/entities/VoluntaryWork.js"; import { getDate } from "./index.js"; import { Volunteer } from "../db/entities/Volunteer.js"; -import { VolunteerProfile } from "../db/entities/VolunteerProfile.js"; + + + + + + import createError from 'http-errors'; const createVoluntaryWork = async (payload: NSVoluntaryWork.Item) => { From 2c020e915f3a7967c4f5dafea3f373341f8ce109 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Sun, 8 Oct 2023 07:44:16 +0300 Subject: [PATCH 072/146] Edit the cookies and error handler --- .env.test | 7 ---- app.ts | 41 ++++----------------- src/controllers/volunteer.ts | 2 +- src/middleware/auth/authenticate.ts | 12 +++++- src/middleware/errorHandler/errorHandler.ts | 21 +++++++++++ src/routes/volunteer.ts | 7 +--- 6 files changed, 41 insertions(+), 49 deletions(-) delete mode 100644 .env.test create mode 100644 src/middleware/errorHandler/errorHandler.ts diff --git a/.env.test b/.env.test deleted file mode 100644 index e38aa90e..00000000 --- a/.env.test +++ /dev/null @@ -1,7 +0,0 @@ -# PORT=3001 -# SECRET_KEY=iugf97$oifh0823!nfoeih80239u$k%lih0f820nfm409 -# DB_HOST=localhost -# DB_PORT=3306 -# DB_USERNAME=root -# DB_PASSWORD="" -# DB_NAME=serve-and-shine \ No newline at end of file diff --git a/app.ts b/app.ts index 740261b3..5166994c 100644 --- a/app.ts +++ b/app.ts @@ -7,7 +7,6 @@ import logger from 'morgan' import cookieParser from 'cookie-parser' import fileUpload from 'express-fileupload'; - import indexRouter from "./src/routes/index.js" import permissionRouter from "./src/routes/permission.js" import roleRouter from "./src/routes/role.js" @@ -16,6 +15,7 @@ import organizationAdminRouter from "./src/routes/organizationAdmin.js" import organizationProfileRouter from "./src/routes/organizationProfile.js" import volunteerRouter from "./src/routes/volunteer.js" import { authenticate } from "./src/middleware/auth/authenticate.js" +import { errorHandler } from "./src/middleware/errorHandler/errorHandler.js" const app = express(); dotenv.config(); @@ -24,39 +24,7 @@ const PORT = process.env.PORT || 3000; app.use(express.json()); app.use(express.urlencoded({ extended: false })); app.use(cookieParser()); -app.use(fileUpload({ limits: { fileSize: 50 * 1024 * 1024 } })) - - -// catch 404 and forward to error handler -app.use(function (req, res, next) { - next(createError(404)); -}); - -const errorHandler = ( - error: any, - req: express.Request, - res: express.Response, - next: express.NextFunction) => { - if (error.status == 404) { - res.status(404).send("Something is not found"); - } else if (error.status == 401) { - res.status(401).send("You are unautharized"); - } else if (error.status == 403) { - res.status(401).send("You don't have the permission"); - } else { - res.status(500).send('Something went wrong'); - } -} - -// error handler -// app.use(function (err: any, req: any, res: any, next: any) { -// // set locals, only providing error in development -// res.locals.message = err.message; -// res.locals.error = req.app.get('env') === 'development' ? err : {}; - -// // render the error page -// res.status(err.status || 500).send({ error: err.message }); -// }); +app.use(fileUpload({ limits: { fileSize: 50 * 1024 * 1024 } })); app.use('/', indexRouter); app.use('/permission', authenticate, permissionRouter); @@ -65,6 +33,11 @@ app.use('/voluntaryWork', authenticate, voluntaryWorkRouter); app.use('/organizationAdmin', authenticate, organizationAdminRouter); app.use('/organizationProfile', authenticate, organizationProfileRouter); app.use("/volunteer", volunteerRouter); + +// catch 404 and forward to error handler +app.use(function (req, res, next) { + next(createError(404)); +}); app.use(errorHandler); app.listen(PORT, () => { diff --git a/src/controllers/volunteer.ts b/src/controllers/volunteer.ts index 88819740..b87bd891 100644 --- a/src/controllers/volunteer.ts +++ b/src/controllers/volunteer.ts @@ -109,7 +109,7 @@ const login = async (email: string, name: string, id: string) => { { expiresIn: "15m" } - ); + ); return token; } else { throw ("Invalid email or name or id !"); diff --git a/src/middleware/auth/authenticate.ts b/src/middleware/auth/authenticate.ts index 729db7de..48c1d48a 100644 --- a/src/middleware/auth/authenticate.ts +++ b/src/middleware/auth/authenticate.ts @@ -18,7 +18,7 @@ const authenticate = async ( tokenIsValid = null; } - if (tokenIsValid ) { + if (tokenIsValid) { const decoded = tokenIsValid as JwtPayload; const organizationAdmin = await OrganizationAdmin.findOne({ @@ -32,9 +32,19 @@ const authenticate = async ( if (organizationAdmin) { res.locals.organizationAdmin = organizationAdmin; + res.cookie('name', res.locals.organizationAdmin.name, { + httpOnly: true, + maxAge: 15 * 60 * 1000, + sameSite: "lax" // Protect against CSRF attacks + }); next(); } else if (volunteer) { res.locals.volunteer = volunteer; + res.cookie('name', res.locals.volunteer.name, { + httpOnly: true, + maxAge: 15 * 60 * 1000, + sameSite: "lax" // Protect against CSRF attacks + }); next(); } else { //res.status(401).send("You are Unauthorized!"); diff --git a/src/middleware/errorHandler/errorHandler.ts b/src/middleware/errorHandler/errorHandler.ts new file mode 100644 index 00000000..ef22105c --- /dev/null +++ b/src/middleware/errorHandler/errorHandler.ts @@ -0,0 +1,21 @@ +import express from "express" + +const errorHandler = ( + error: any, + req: express.Request, + res: express.Response, + next: express.NextFunction) => { + if (error.status == 404) { + res.status(404).send("Something is not found"); + } else if (error.status == 401) { + res.status(401).send("You are unauthorized"); + } else if (error.status == 403) { + res.status(401).send("You don't have the permission"); + } else { + res.status(500).send('Something went wrong'); + } +} + +export { + errorHandler +} \ No newline at end of file diff --git a/src/routes/volunteer.ts b/src/routes/volunteer.ts index 5a5eaff8..86fbbc42 100644 --- a/src/routes/volunteer.ts +++ b/src/routes/volunteer.ts @@ -28,12 +28,7 @@ router.post('/login', (req, res, next) => { maxAge: 15 * 60 * 1000, sameSite: "lax" // Protect against CSRF attacks }); - res.cookie('name', res.locals.volunteer.name || res.locals.organizationAdmin.name, { - httpOnly: true, - maxAge: 15 * 60 * 1000, - sameSite: "lax" // Protect against CSRF attacks - }); - res.status(201).send(data); + res.status(201).send("You logged in successfully !"); }) .catch(err => { res.status(401).send(err); From 10b0eec81eea741543af7a7ee351ca84e2366b68 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Sun, 8 Oct 2023 07:50:29 +0300 Subject: [PATCH 073/146] Edit creat volunteer so the normal user can only creat volunteer, while the premiume can only created by admin or root --- src/routes/volunteer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/volunteer.ts b/src/routes/volunteer.ts index 86fbbc42..60dc61f3 100644 --- a/src/routes/volunteer.ts +++ b/src/routes/volunteer.ts @@ -8,7 +8,7 @@ import { NSVolunteer } from '../../types/volunteer.js'; var router = express.Router(); router.post('/register', validateVolunteer, (req, res, next) => { - createVolunteer(req.body).then(() => { + createVolunteer({...req.body,type:"volunteer" }).then(() => { res.status(201).send("Volunteer created successfully!!") }).catch(err => { // console.error(err); From e716284b85efc7cc62221d0a110bcffa2ddc3977 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Sun, 8 Oct 2023 08:28:59 +0300 Subject: [PATCH 074/146] Assigne a role to vilunteer when creating --- src/controllers/volunteer.ts | 12 +++++++++--- src/middleware/auth/authenticate.ts | 4 ++-- src/middleware/auth/authorize.ts | 6 +++--- src/middleware/validation/volunteer.ts | 3 ++- src/routes/volunteer.ts | 12 ++++++------ 5 files changed, 22 insertions(+), 15 deletions(-) diff --git a/src/controllers/volunteer.ts b/src/controllers/volunteer.ts index b87bd891..732cbb3a 100644 --- a/src/controllers/volunteer.ts +++ b/src/controllers/volunteer.ts @@ -8,6 +8,7 @@ import bcrypt from 'bcrypt'; import { SkillTag } from "../db/entities/SkillTag.js"; import { In, Like } from "typeorm"; import createError from 'http-errors'; +import { Role } from "../db/entities/Role.js"; const createVolunteer = async (payload: NSVolunteer.Item) => { @@ -34,8 +35,13 @@ const createVolunteer = async (payload: NSVolunteer.Item) => { await transaction.save(profile); const newVolunteer = Volunteer.create(payload); - newVolunteer.volunteerProfile = profile; + + const role = await Role.findOne({where:{name:payload.type}}); + if (role){ + newVolunteer.roles = [role]; + } + await transaction.save(newVolunteer); }); }; @@ -98,7 +104,7 @@ const login = async (email: string, name: string, id: string) => { { email, name, id }, process.env.SECRET_KEY || '', { - expiresIn: "15m" + expiresIn: "1d" } ); return token; @@ -107,7 +113,7 @@ const login = async (email: string, name: string, id: string) => { { email, name, id }, process.env.SECRET_KEY || '', { - expiresIn: "15m" + expiresIn: "1d" } ); return token; diff --git a/src/middleware/auth/authenticate.ts b/src/middleware/auth/authenticate.ts index 48c1d48a..32ef8696 100644 --- a/src/middleware/auth/authenticate.ts +++ b/src/middleware/auth/authenticate.ts @@ -34,7 +34,7 @@ const authenticate = async ( res.locals.organizationAdmin = organizationAdmin; res.cookie('name', res.locals.organizationAdmin.name, { httpOnly: true, - maxAge: 15 * 60 * 1000, + maxAge: 60 * 24 * 60 * 1000, sameSite: "lax" // Protect against CSRF attacks }); next(); @@ -42,7 +42,7 @@ const authenticate = async ( res.locals.volunteer = volunteer; res.cookie('name', res.locals.volunteer.name, { httpOnly: true, - maxAge: 15 * 60 * 1000, + maxAge: 60 * 24* 60 * 1000, sameSite: "lax" // Protect against CSRF attacks }); next(); diff --git a/src/middleware/auth/authorize.ts b/src/middleware/auth/authorize.ts index cc543c91..c5d968c0 100644 --- a/src/middleware/auth/authorize.ts +++ b/src/middleware/auth/authorize.ts @@ -12,8 +12,7 @@ const authorize = (api: string) => { req: express.Request, res: express.Response, next: express.NextFunction - ) => { - + ) => { const permissions: NSPermission.Item[] = []; if (res.locals.organizationAdmin) { @@ -42,9 +41,10 @@ const checkMe = () => { next: express.NextFunction ) => { const id = req.params.id; + if (res.locals.volunteer) { if (res.locals.volunteer.id == id) { - next(createError(403)); + next(); } } else if (res.locals.organizationAdmin) { if (res.locals.organizationAdmin.id == id) { diff --git a/src/middleware/validation/volunteer.ts b/src/middleware/validation/volunteer.ts index a1f4a31d..9a2e4b4b 100644 --- a/src/middleware/validation/volunteer.ts +++ b/src/middleware/validation/volunteer.ts @@ -8,9 +8,10 @@ import createError from 'http-errors' const validateVolunteer = (req: express.Request, res: express.Response, next: express.NextFunction) => { const volunteer = req.body; + volunteer.type = "volunteer"; const errorList: string[] = []; - const requiredFields = ["name", "email", "password", "type", "availableTime", "availableLocation", "availableDays", "skills"]; + const requiredFields = ["name", "email", "password", "availableTime", "availableLocation", "availableDays", "skills"]; requiredFields.forEach((field) => { if (!volunteer[field]) { errorList.push(`${field} is required.`); diff --git a/src/routes/volunteer.ts b/src/routes/volunteer.ts index 60dc61f3..063e5785 100644 --- a/src/routes/volunteer.ts +++ b/src/routes/volunteer.ts @@ -25,7 +25,7 @@ router.post('/login', (req, res, next) => { .then(data => { res.cookie('myApp', data, { httpOnly: true, - maxAge: 15 * 60 * 1000, + maxAge: 60 *24 * 60 * 1000, sameSite: "lax" // Protect against CSRF attacks }); res.status(201).send("You logged in successfully !"); @@ -35,19 +35,19 @@ router.post('/login', (req, res, next) => { }) }); -router.delete('/:id', authenticate, authorize("DELETE_volunteer"), checkMe, async (req, res, next) => { +router.delete('/:id', authenticate, authorize("DELETE_volunteer"), checkMe(), async (req, res, next) => { const id = req.params.id?.toString(); deleteVolunteer(id) .then(data => { - res.send("Deleted"); + res.send(data); }) .catch(error => { next(error); }); }) -router.put("/:id", authenticate, authorize("POST_volunteer"), checkMe, validateEditedVolunteer, async (req, res, next) => { +router.put("/:id", authenticate, authorize("PUT_volunteer"), checkMe(), validateEditedVolunteer, async (req, res, next) => { editVolunteer({ ...req.body, id: req.params.id?.toString() }).then(() => { res.status(201).send("Volunteer edited successfully!!") }).catch(err => { @@ -57,7 +57,7 @@ router.put("/:id", authenticate, authorize("POST_volunteer"), checkMe, validateE }); }); -router.get('/', /*authenticate, authorize("GET_volunteers"), */async (req, res, next) => { +router.get('/', authenticate, authorize("GET_volunteers"), async (req, res, next) => { const payload = { page: req.query.page?.toString() || '1', pageSize: req.query.pageSize?.toString() || '10', @@ -91,7 +91,7 @@ router.get("/logout", authenticate, (req, res, next) => { maxAge: -1 }) - res.send("Logout correctly!"); + res.send("You logged out successfully !"); }) router.get('/me', authenticate, authorize("GET_me"), async (req, res, next) => { From cb38814daf8ba22c040016a594b7952133a83536 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Sun, 8 Oct 2023 09:56:37 +0300 Subject: [PATCH 075/146] Edit the returned attribute for volunteer and the atrributes for related entites --- src/controllers/volunteer.ts | 40 ++++++++++++++++++++++++++++++++---- src/db/entities/SkillTag.ts | 2 +- src/routes/volunteer.ts | 2 +- 3 files changed, 38 insertions(+), 6 deletions(-) diff --git a/src/controllers/volunteer.ts b/src/controllers/volunteer.ts index 732cbb3a..1f1ea151 100644 --- a/src/controllers/volunteer.ts +++ b/src/controllers/volunteer.ts @@ -41,7 +41,7 @@ const createVolunteer = async (payload: NSVolunteer.Item) => { if (role){ newVolunteer.roles = [role]; } - + await transaction.save(newVolunteer); }); }; @@ -127,7 +127,7 @@ const getVolunteers = async (payload: NSVolunteer.Item & { page: string; pageSiz const page = parseInt(payload.page); const pageSize = parseInt(payload.pageSize); const conditions: Record = {}; - + if (payload.id) { conditions["id"] = payload.id; } @@ -143,7 +143,7 @@ const getVolunteers = async (payload: NSVolunteer.Item & { page: string; pageSiz if (payload.availableLocation) { conditions["availableLocation"] = payload.availableLocation; } - if (payload.type) { + if (payload.type) { conditions["type"] = payload.type; } if (payload.availableDays.length > 0) { @@ -158,9 +158,37 @@ const getVolunteers = async (payload: NSVolunteer.Item & { page: string; pageSiz "volunteerProfile.skillTags", "volunteerProfile" ], + select: [ + "name", + "email", + "type", + "volunteerProfile" + ], }); - const filteredVolunteers = volunteers.filter((volunteer) => { + const processedVolunteers = volunteers.map((volunteer) => { + // Create a new volunteer object with the desired properties + const processedVolunteer = { + name: volunteer.name, + email: volunteer.email, + type: volunteer.type, + createdAt: volunteer.createdAt, + volunteerProfile: { + availableTime: volunteer.volunteerProfile?.availableTime, + availableDays: volunteer.volunteerProfile?.availableDays, + availableLocation: volunteer.volunteerProfile?.availableLocation, + dateOfBirth: volunteer.volunteerProfile?.dateOfBirth, + roles:volunteer.volunteerProfile?.roles, + skillTags: volunteer.volunteerProfile?.skillTags?.map((skillTag) => { + return { name: skillTag.name }; + }), + }, + }; + + return processedVolunteer; + }); + + const filteredVolunteers = processedVolunteers.filter((volunteer) => { if (payload.skills.length > 0) { const hasMatchingSkill = volunteer.volunteerProfile.skillTags.some((skillTag) => payload.skills.includes(skillTag.name)); return hasMatchingSkill; @@ -179,5 +207,9 @@ const getVolunteers = async (payload: NSVolunteer.Item & { page: string; pageSiz }; }; +// "availableTime", +// "availableLocation", +// "availableDays", + export { getVolunteers, login, createVolunteer, deleteVolunteer, editVolunteer } diff --git a/src/db/entities/SkillTag.ts b/src/db/entities/SkillTag.ts index 554e0f1f..66f8d9b9 100644 --- a/src/db/entities/SkillTag.ts +++ b/src/db/entities/SkillTag.ts @@ -16,7 +16,7 @@ export class SkillTag extends BaseEntity { @ManyToMany(() => VoluntaryWork) @JoinTable() - roles: VoluntaryWork[]; + voluntaryWorks: VoluntaryWork[]; @CreateDateColumn({ type: 'timestamp', diff --git a/src/routes/volunteer.ts b/src/routes/volunteer.ts index 063e5785..99954c4e 100644 --- a/src/routes/volunteer.ts +++ b/src/routes/volunteer.ts @@ -66,7 +66,7 @@ router.get('/', authenticate, authorize("GET_volunteers"), async (req, res, next email: req.query.email?.toString() || "", availableLocation: req.query.availableLocation?.toString() || "", skills: ((Array.isArray(req.query.skills) ? req.query.skills : [req.query.skills]).filter(Boolean)) as string[], - type: req.query.status as NSVolunteer.TypeVolunteer, + type: req.query.type as NSVolunteer.TypeVolunteer, availableDays: (Array.isArray(req.query.availableDays) ? req.query.availableDays : [req.query.availableDays]).filter(Boolean) as NSVolunteer.AvailableDays[], availableTime: ((Array.isArray(req.query.availableTime) ? req.query.availableTime : [req.query.availableTime]).filter(Boolean)) as NSVolunteer.AvailableTime[], password: "" From 607b7f1efab73205a6c1eca16c9775652738a5bf Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Sun, 8 Oct 2023 11:52:52 +0300 Subject: [PATCH 076/146] Edit the authorization for all endpoins --- src/controllers/OrganizationProfile .ts | 3 +- src/controllers/volunteer.ts | 2 +- src/middleware/auth/authorize.ts | 149 ++++++++++-------------- src/routes/organizationAdmin.ts | 6 +- src/routes/organizationProfile.ts | 6 +- src/routes/permission.ts | 2 +- src/routes/role.ts | 2 +- src/routes/voluntaryWork.ts | 2 +- src/routes/volunteer.ts | 4 +- types/organizationProfile.ts | 1 - 10 files changed, 75 insertions(+), 102 deletions(-) diff --git a/src/controllers/OrganizationProfile .ts b/src/controllers/OrganizationProfile .ts index f8185397..202ec39a 100644 --- a/src/controllers/OrganizationProfile .ts +++ b/src/controllers/OrganizationProfile .ts @@ -4,8 +4,7 @@ import { OrganizationProfile } from "../db/entities/OrganizationProfile.js"; import createError from 'http-errors'; const createOrganizationProfile = async (payload: NSOrganizationProfile.Item) => { - - const newOrganizationProfile = OrganizationProfile.create(payload); + const newOrganizationProfile = OrganizationProfile.create({name:payload.name,description:payload.description }); return newOrganizationProfile.save(); } diff --git a/src/controllers/volunteer.ts b/src/controllers/volunteer.ts index 1f1ea151..cff4a322 100644 --- a/src/controllers/volunteer.ts +++ b/src/controllers/volunteer.ts @@ -141,7 +141,7 @@ const getVolunteers = async (payload: NSVolunteer.Item & { page: string; pageSiz conditions["availableTime"] = In(payload.availableTime); } if (payload.availableLocation) { - conditions["availableLocation"] = payload.availableLocation; + conditions["availableLocation"] = Like(`%${payload.availableLocation}%`); } if (payload.type) { conditions["type"] = payload.type; diff --git a/src/middleware/auth/authorize.ts b/src/middleware/auth/authorize.ts index c5d968c0..19691c12 100644 --- a/src/middleware/auth/authorize.ts +++ b/src/middleware/auth/authorize.ts @@ -12,7 +12,7 @@ const authorize = (api: string) => { req: express.Request, res: express.Response, next: express.NextFunction - ) => { + ) => { const permissions: NSPermission.Item[] = []; if (res.locals.organizationAdmin) { @@ -26,121 +26,96 @@ const authorize = (api: string) => { }); } - if (permissions?.filter(p => p.name === api).length > 0 || (/^PUT_.+/.test(api)) || (/^DELETE_.+/.test(api))) { + if (permissions?.filter(p => p.name === api).length > 0) { next(); + } else if ((/^PUT_.+/.test(api)) || (/^DELETE_.+/.test(api))) { + if ((/organizationProfile$/.test(api))) { + checkAdmin(req, res, next); + } else if ((/organizationAdmin$/.test(api)) || (/volunteer$/.test(api))) { + checkMe(req, res, next); + } else if ((/voluntaryWork$/.test(api))) { + checkCreator(req, res, next); + } } else { res.status(403).send("You don't have the permission to access this resource!"); } } } -const checkMe = () => { - return ( - req: express.Request, - res: express.Response, - next: express.NextFunction - ) => { - const id = req.params.id; +const checkMe = (req: express.Request, res: express.Response, next: express.NextFunction) => { - if (res.locals.volunteer) { - if (res.locals.volunteer.id == id) { - next(); - } - } else if (res.locals.organizationAdmin) { - if (res.locals.organizationAdmin.id == id) { - next(); - } else { - next(createError(401)); - } + const id = req.params.id; + if (res.locals.volunteer) { + if (res.locals.volunteer.id == id) { + next(); } - } -} - -const checkAdmin = () => { - return async ( - req: express.Request, - res: express.Response, - next: express.NextFunction - ) => { - const id = req.params.id; - let organizationProfile = await OrganizationProfile.findOne({ where: { id } }); - const admin = await OrganizationAdmin.findOne({ where: { orgProfile: { id: organizationProfile?.id } } }); - if (res.locals.organizationAdmin) { - if (res.locals.organizationAdmin.id == admin?.id) { - next(); - } + } else if (res.locals.organizationAdmin) { + if (res.locals.organizationAdmin.id == id) { + next(); } else { - next() + next(createError(401)); } } + } -const checkCreator = () => { - return async ( - req: express.Request, - res: express.Response, - next: express.NextFunction - ) => { - const id = Number(req.params.id); - let voluntaryWork = await VoluntaryWork.findOne({ where: { id } }); +const checkAdmin = async (req: express.Request, res: express.Response, next: express.NextFunction) => { + const id = req.params.id; + const admin = await OrganizationAdmin.findOne({ where: { orgProfile: { id } } }); - if (res.locals.organizationAdmin) { - if (res.locals.organizationAdmin.id == voluntaryWork?.creatorId) { - next(); - } - } else if (res.locals.volunteer) { - if (res.locals.volunteer.id == voluntaryWork?.creatorId) { - next(); - } - } else { - next(createError(401)); + if (res.locals.organizationAdmin) { + if (res.locals.organizationAdmin.id == admin?.id) { + next(); } + } else { + next(createError(401)); } } -const c1heckParticipation = () => { - return async ( - req: express.Request, - res: express.Response, - next: express.NextFunction - ) => { - const id = Number(req.params.id); - let voluntaryWork = await VoluntaryWork.findOne({ where: { id } }); - if(res.locals.volunteer) { - const volunteer:Volunteer=res.locals.volunteer; - }else { - next(createError(401)); + +const checkCreator = async (req: express.Request, res: express.Response, next: express.NextFunction) => { + const id = Number(req.params.id); + let voluntaryWork = await VoluntaryWork.findOne({ where: { id } }); + + if (res.locals.organizationAdmin) { + if (res.locals.organizationAdmin.id == voluntaryWork?.creatorId) { + next(); + } + } else if (res.locals.volunteer) { + if (res.locals.volunteer.id == voluntaryWork?.creatorId) { + next(); } + } else { + next(createError(401)); } } -const checkParticipation = () => { - return async ( - req: express.Request, - res: express.Response, - next: express.NextFunction - ) => { - const id = Number(req.params.id); +const checkParticipation = async ( + req: express.Request, + res: express.Response, + next: express.NextFunction +) => { + const id = Number(req.params.id); - if (res.locals.volunteer) { - const volunteer = res.locals.volunteer; - const volunteerProfile = volunteer.volunteerProfile; + if (res.locals.volunteer) { + const volunteer = res.locals.volunteer; + const volunteerProfile = volunteer.volunteerProfile; - if (volunteerProfile) { - const voluntaryWork = await VoluntaryWork.findOne({ - where: { id }, - relations: ['volunteerProfiles'] - }); + if (volunteerProfile) { + const voluntaryWork = await VoluntaryWork.findOne({ + where: { id }, + relations: ['volunteerProfiles'] + }); - if (voluntaryWork && voluntaryWork.volunteerProfiles.includes(volunteerProfile)) { - next(); - } + if (voluntaryWork && voluntaryWork.volunteerProfiles.includes(volunteerProfile)) { + next(); } - } - next(createError(401)); - }; + } + } + next(createError(401)); }; + export { authorize, checkMe, diff --git a/src/routes/organizationAdmin.ts b/src/routes/organizationAdmin.ts index b215f177..acc5a622 100644 --- a/src/routes/organizationAdmin.ts +++ b/src/routes/organizationAdmin.ts @@ -15,12 +15,12 @@ router.post('/', authorize("POST_organizationAdmin"), validateOrganizationAdmin, }); }); -router.delete('/:id', authorize("DELETE_organizationAdmin"), checkMe, async (req, res, next) => { +router.delete('/:id', authorize("DELETE_organizationAdmin"), async (req, res, next) => { const id = req.params.id?.toString(); deleteOrganizationAdmin(id) .then(data => { - res.send("Deleted"); + res.send(data); }) .catch(err => { // console.error(error); @@ -29,7 +29,7 @@ router.delete('/:id', authorize("DELETE_organizationAdmin"), checkMe, async (req }); }); -router.put("/:id", authorize("PUT_organizationAdmin"), checkMe, validateAdminEdited, async (req, res, next) => { +router.put("/:id", authorize("PUT_organizationAdmin"), validateAdminEdited, async (req, res, next) => { editOrganizationAdmin({ ...req.body, id: req.params.id }).then(() => { res.status(201).send("Organization Admin edited successfully!!") }).catch(err => { diff --git a/src/routes/organizationProfile.ts b/src/routes/organizationProfile.ts index 4d3e070e..2aa3b0f4 100644 --- a/src/routes/organizationProfile.ts +++ b/src/routes/organizationProfile.ts @@ -15,12 +15,12 @@ router.post('/', authorize("POST_organizationProfile"), validateOrganizationProf }); }); -router.delete('/:id', authorize("DELETE_organizationProfile"), checkAdmin, async (req, res, next) => { +router.delete('/:id', authorize("DELETE_organizationProfile"), async (req, res, next) => { const id = Number(req.params.id?.toString()); deleteOrganizationProfile(id) .then(data => { - res.send("Deleted"); + res.send(data); }) .catch(err => { // console.error(error); @@ -29,7 +29,7 @@ router.delete('/:id', authorize("DELETE_organizationProfile"), checkAdmin, async }); }); -router.put("/:id", authorize("PUT_organizationProfile"),checkAdmin,validateOrgId, async (req, res, next) => { +router.put("/:id", authorize("PUT_organizationProfile"), validateOrgId, async (req, res, next) => { editOrganizationProfile(req.body).then(() => { res.status(201).send("Organization Profile edited successfully!!") }).catch(err => { diff --git a/src/routes/permission.ts b/src/routes/permission.ts index b33f9927..765defeb 100644 --- a/src/routes/permission.ts +++ b/src/routes/permission.ts @@ -20,7 +20,7 @@ router.delete('/:id', authorize("DELETE_permission"), async (req, res, next) => deletePermission(id) .then(data => { - res.send("Deleted"); + res.send(data); }) .catch(err => { // console.error(error); diff --git a/src/routes/role.ts b/src/routes/role.ts index 4799b670..d5311ae4 100644 --- a/src/routes/role.ts +++ b/src/routes/role.ts @@ -21,7 +21,7 @@ router.delete('/:id', authorize("DELETE_role"), async (req, res, next) => { deleteRole(id) .then(data => { - res.send("Deleted"); + res.send(data); }) .catch(err => { // console.error(error); diff --git a/src/routes/voluntaryWork.ts b/src/routes/voluntaryWork.ts index b17d4fce..2b91c333 100644 --- a/src/routes/voluntaryWork.ts +++ b/src/routes/voluntaryWork.ts @@ -23,7 +23,7 @@ router.delete('/:id', authorize("DELETE_voluntaryWork"), checkCreator, async (re deleteVoluntaryWork(id) .then(data => { - res.send("Deleted"); + res.send(data); }) .catch(err => { // res.status(500).send('Something went wrong'); diff --git a/src/routes/volunteer.ts b/src/routes/volunteer.ts index 99954c4e..639f90a6 100644 --- a/src/routes/volunteer.ts +++ b/src/routes/volunteer.ts @@ -35,7 +35,7 @@ router.post('/login', (req, res, next) => { }) }); -router.delete('/:id', authenticate, authorize("DELETE_volunteer"), checkMe(), async (req, res, next) => { +router.delete('/:id', authenticate, authorize("DELETE_volunteer"), async (req, res, next) => { const id = req.params.id?.toString(); deleteVolunteer(id) @@ -47,7 +47,7 @@ router.delete('/:id', authenticate, authorize("DELETE_volunteer"), checkMe(), as }); }) -router.put("/:id", authenticate, authorize("PUT_volunteer"), checkMe(), validateEditedVolunteer, async (req, res, next) => { +router.put("/:id", authenticate, authorize("PUT_volunteer"), validateEditedVolunteer, async (req, res, next) => { editVolunteer({ ...req.body, id: req.params.id?.toString() }).then(() => { res.status(201).send("Volunteer edited successfully!!") }).catch(err => { diff --git a/types/organizationProfile.ts b/types/organizationProfile.ts index 08f29839..e53bd549 100644 --- a/types/organizationProfile.ts +++ b/types/organizationProfile.ts @@ -3,7 +3,6 @@ export namespace NSOrganizationProfile { export interface Item { id?: string; name: string; - email: string; description: string; createdAt?: Date; } From 30d5a3c5d0fc212695c59f2d84d973dc03d36b89 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Sun, 8 Oct 2023 12:02:02 +0300 Subject: [PATCH 077/146] edit delete and get orgProfile --- src/controllers/OrganizationProfile .ts | 7 ++++--- src/routes/organizationProfile.ts | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/controllers/OrganizationProfile .ts b/src/controllers/OrganizationProfile .ts index 202ec39a..2a755241 100644 --- a/src/controllers/OrganizationProfile .ts +++ b/src/controllers/OrganizationProfile .ts @@ -4,7 +4,7 @@ import { OrganizationProfile } from "../db/entities/OrganizationProfile.js"; import createError from 'http-errors'; const createOrganizationProfile = async (payload: NSOrganizationProfile.Item) => { - const newOrganizationProfile = OrganizationProfile.create({name:payload.name,description:payload.description }); + const newOrganizationProfile = OrganizationProfile.create({ name: payload.name, description: payload.description }); return newOrganizationProfile.save(); } @@ -20,7 +20,7 @@ const editOrganizationProfile = async (payload: { id: string, name: string, desc } } -const deleteOrganizationProfile = async (profileId: number) => { +const deleteOrganizationProfile = async (profileId: string) => { return OrganizationProfile.delete(profileId); } @@ -58,7 +58,8 @@ const getOrganizationProfile = async (payload: { take: pageSize, order: { createdAt: 'ASC' - } + }, + select: ["name", "description", "createdAt"] }) return { diff --git a/src/routes/organizationProfile.ts b/src/routes/organizationProfile.ts index 2aa3b0f4..6a9088a8 100644 --- a/src/routes/organizationProfile.ts +++ b/src/routes/organizationProfile.ts @@ -16,7 +16,7 @@ router.post('/', authorize("POST_organizationProfile"), validateOrganizationProf }); router.delete('/:id', authorize("DELETE_organizationProfile"), async (req, res, next) => { - const id = Number(req.params.id?.toString()); + const id = (req.params.id?.toString()); deleteOrganizationProfile(id) .then(data => { From 0c202a8bf59a070885556d6bb13f615060dc1ae9 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Sun, 8 Oct 2023 12:21:40 +0300 Subject: [PATCH 078/146] Edit creat admin so when creat it assgin a role to him --- src/controllers/organizationAdmin.ts | 16 +++++++++++----- src/middleware/auth/authorize.ts | 2 +- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/controllers/organizationAdmin.ts b/src/controllers/organizationAdmin.ts index c1823a1f..bb9b246f 100644 --- a/src/controllers/organizationAdmin.ts +++ b/src/controllers/organizationAdmin.ts @@ -3,6 +3,7 @@ import { OrganizationAdmin } from "../db/entities/OrganizationAdmin.js"; import { OrganizationProfile } from "../db/entities/OrganizationProfile.js"; import bcrypt from 'bcrypt'; import createError from 'http-errors'; +import { Role } from "../db/entities/Role.js"; const createOrganizationAdmin = async (payload: NSOrganizationAdmin.Item) => { @@ -12,6 +13,11 @@ const createOrganizationAdmin = async (payload: NSOrganizationAdmin.Item) => { where: { id: payload.organizationId }, }); + const role = await Role.findOne({ where: { name: "admin" } }); + if (role) { + newOrganizationAdmin.roles = role; + } + if (organization) { newOrganizationAdmin.orgProfile = organization; return newOrganizationAdmin.save(); @@ -41,8 +47,8 @@ const getOrganizationAdmins = async (payload: { return OrganizationAdmin.findOne({ where: { email: payload.email } }) } if (payload.organizationName) { - - const organization = await OrganizationProfile.findOne({ where: { name: payload.organizationName} }); + + const organization = await OrganizationProfile.findOne({ where: { name: payload.organizationName } }); if (organization) { return await OrganizationAdmin.findOne({ where: { orgProfile: { id: organization.id } } }); @@ -83,14 +89,14 @@ const editOrganizationAdmin = async (payload: { id: string, name: string, email: admin.email = payload.email; if (payload.newPassword) { - if (!payload.oldPassword){ + if (!payload.oldPassword) { throw "Old password is needed !"; } const passwordMatching = await bcrypt.compare(payload.oldPassword, admin?.password || ''); - if (passwordMatching){ + if (passwordMatching) { admin.password = await bcrypt.hash(payload.newPassword, 10); - }else{ + } else { throw "The old password isn't correct !" } } diff --git a/src/middleware/auth/authorize.ts b/src/middleware/auth/authorize.ts index 19691c12..7dcc71f1 100644 --- a/src/middleware/auth/authorize.ts +++ b/src/middleware/auth/authorize.ts @@ -17,7 +17,7 @@ const authorize = (api: string) => { if (res.locals.organizationAdmin) { const organizationAdmin: OrganizationAdmin = res.locals.organizationAdmin; - permissions.push(...organizationAdmin.roles.permissions); + permissions.push(...(organizationAdmin.roles.permissions)); } else if (res.locals.volunteer) { const volunteer: Volunteer = res.locals.volunteer; From 970865629f78b2253720b497f50685a6fc9e24e7 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Sun, 8 Oct 2023 12:47:48 +0300 Subject: [PATCH 079/146] Edit the get admin so return it without id and password --- src/controllers/organizationAdmin.ts | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/controllers/organizationAdmin.ts b/src/controllers/organizationAdmin.ts index bb9b246f..9786abfa 100644 --- a/src/controllers/organizationAdmin.ts +++ b/src/controllers/organizationAdmin.ts @@ -4,6 +4,7 @@ import { OrganizationProfile } from "../db/entities/OrganizationProfile.js"; import bcrypt from 'bcrypt'; import createError from 'http-errors'; import { Role } from "../db/entities/Role.js"; +import { Not } from "typeorm"; const createOrganizationAdmin = async (payload: NSOrganizationAdmin.Item) => { @@ -37,22 +38,33 @@ const getOrganizationAdmins = async (payload: { const page = parseInt(payload.page); const pageSize = parseInt(payload.pageSize); + if (payload.id) { - return OrganizationAdmin.findOne({ where: { id: payload.id } }) + return OrganizationAdmin.findOne({ + where: { id: payload.id, name: Not("root") }, + select: ["name", "email", "createdAt"] + }) } if (payload.name) { - return OrganizationAdmin.findOne({ where: { name: payload.name } }) + return OrganizationAdmin.findOne({ + where: { name: payload.name === 'root' ? "" : payload.name }, + select: ["name", "email", "createdAt"] + }) } if (payload.email) { - return OrganizationAdmin.findOne({ where: { email: payload.email } }) + return OrganizationAdmin.findOne({ + where: { email: payload.email, name: Not("root") }, + select: ["name", "email", "createdAt"] + }) } if (payload.organizationName) { const organization = await OrganizationProfile.findOne({ where: { name: payload.organizationName } }); if (organization) { - - return await OrganizationAdmin.findOne({ where: { orgProfile: { id: organization.id } } }); + const admin = await OrganizationAdmin.findOne({ where: { orgProfile: { id: organization.id } } }); + return {name:admin?.name, createdAt:admin?.createdAt, email:admin?.email}; } else { + throw createError(404); } } @@ -62,7 +74,11 @@ const getOrganizationAdmins = async (payload: { take: pageSize, order: { createdAt: 'ASC' - } + }, + where: { + name: Not("root") + }, + select: ["name", "email", "createdAt"] }) return { From 149e064f394484d05dbe40507ea9ced0cb60c5b7 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Sun, 8 Oct 2023 13:14:14 +0300 Subject: [PATCH 080/146] Edit the authorization middlewares --- src/controllers/index.ts | 2 +- src/middleware/auth/authorize.ts | 7 +++++-- src/middleware/validation/organizationAdmin.ts | 4 ++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/controllers/index.ts b/src/controllers/index.ts index 7d9ec0d0..21f65b88 100644 --- a/src/controllers/index.ts +++ b/src/controllers/index.ts @@ -5,7 +5,7 @@ const getDate = (date: string): Date => { const isValidPassword = (password: string) => { const validation = []; - if (password.length < 10) { + if (password?.length < 10) { validation.push("The password should be at least 10 characters"); } diff --git a/src/middleware/auth/authorize.ts b/src/middleware/auth/authorize.ts index 7dcc71f1..4d6c7e1d 100644 --- a/src/middleware/auth/authorize.ts +++ b/src/middleware/auth/authorize.ts @@ -59,20 +59,21 @@ const checkMe = (req: express.Request, res: express.Response, next: express.Next } -const checkAdmin = async (req: express.Request, res: express.Response, next: express.NextFunction) => { +const checkAdmin = async (req: express.Request, res: express.Response, next: express.NextFunction) => { const id = req.params.id; const admin = await OrganizationAdmin.findOne({ where: { orgProfile: { id } } }); if (res.locals.organizationAdmin) { if (res.locals.organizationAdmin.id == admin?.id) { next(); + }else{ + next(createError(401)); } } else { next(createError(401)); } } - const checkCreator = async (req: express.Request, res: express.Response, next: express.NextFunction) => { const id = Number(req.params.id); let voluntaryWork = await VoluntaryWork.findOne({ where: { id } }); @@ -84,6 +85,8 @@ const checkCreator = async (req: express.Request, res: express.Response, next: e } else if (res.locals.volunteer) { if (res.locals.volunteer.id == voluntaryWork?.creatorId) { next(); + }else{ + next(createError(401)); } } else { next(createError(401)); diff --git a/src/middleware/validation/organizationAdmin.ts b/src/middleware/validation/organizationAdmin.ts index 1cdf85c1..8756f40e 100644 --- a/src/middleware/validation/organizationAdmin.ts +++ b/src/middleware/validation/organizationAdmin.ts @@ -45,8 +45,8 @@ const validateAdminEdited = async (req: express.Request, errorList.push('Email is not Valid'); } } - - errorList.push(...isValidPassword(organizationAdmin.password )); + if (organizationAdmin.password ) + errorList.push(...isValidPassword(organizationAdmin.password )); if (errorList.length) { res.status(400).send(errorList); From a8a153a66065d17102762dedd4e4eb81fc981203 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Sun, 8 Oct 2023 15:03:13 +0300 Subject: [PATCH 081/146] edit get voluntary works function to make the relation AND and to bring wanted attributes --- src/controllers/voluntaryWork.ts | 90 ++++++++++++---------- src/controllers/volunteer.ts | 7 +- src/db/entities/VoluntaryWork.ts | 2 +- src/middleware/auth/authorize.ts | 12 ++- src/middleware/validation/voluntaryWork.ts | 14 ++-- src/routes/voluntaryWork.ts | 8 +- 6 files changed, 72 insertions(+), 61 deletions(-) diff --git a/src/controllers/voluntaryWork.ts b/src/controllers/voluntaryWork.ts index 277ae6d7..108ff7b4 100644 --- a/src/controllers/voluntaryWork.ts +++ b/src/controllers/voluntaryWork.ts @@ -1,4 +1,4 @@ -import { DeepPartial, FindOperator, FindOptionsWhere, In, LessThan, LessThanOrEqual, MoreThan, MoreThanOrEqual } from "typeorm"; +import { DeepPartial, FindOperator, FindOptionsWhere, In, LessThan, LessThanOrEqual, Like, MoreThan, MoreThanOrEqual } from "typeorm"; import { NSVoluntaryWork } from "../../types/voluntaryWork.js"; import { SkillTag } from "../db/entities/SkillTag.js"; import { VoluntaryWork } from "../db/entities/VoluntaryWork.js"; @@ -67,87 +67,75 @@ const getVoluntaryWork = (payload: { id: number }) => { const getVoluntaryWorks = async (payload: NSVoluntaryWork.GetVoluntaryWorks) => { const page = parseInt(payload.page); const pageSize = parseInt(payload.pageSize); - const conditions = []; - + const conditions: Record = {}; + if (payload.id) { - const voluntaryWork = await VoluntaryWork.findOne({ where: { id: payload.id }, relations: ['skillTags', 'volunteerProfiles'] }) - return { - ...voluntaryWork, - volunteerNumbers: voluntaryWork?.volunteerProfiles.length - } - - + conditions["id"] = payload.id; } if (payload.name) { - const voluntaryWork = await VoluntaryWork.findOne({ where: { name: payload.name }, relations: ['skillTags', 'volunteerProfiles'] }) - return { - ...voluntaryWork, - volunteerNumbers: voluntaryWork?.volunteerProfiles.length - } + conditions["name"] = payload.name; } if (payload.time.length > 0) { - conditions.push({ time: In(payload.time) }); + conditions["time"] = In(payload.time); } if (payload.location) { - conditions.push({ location: payload.location }); + conditions["location"] = payload.location; } if (payload.rating) { - conditions.push({ rating: payload.rating }); + conditions["rating"] = payload.rating; } if (payload.status) { - conditions.push({ status: payload.status }); + conditions["status"] = payload.status; } if (payload.days.length > 0) { - conditions.push({ days: In(payload.days) }); + conditions["days"] = In(payload.days); } if (payload.skills.length > 0) { - conditions.push({ skillTags: { name: In(payload.skills) } }); + conditions["skillTags"] = In(payload.skills); } if (payload.startedDate) { - let startedDate = getDate(payload.startedDate); - conditions.push({ startedDate: startedDate }); + conditions["startedDate"] = payload.startedDate; // Assuming this is a specific date comparison } if (payload.finishedDate) { - let finishedDate = getDate(payload.finishedDate); - conditions.push({ finishedDate: finishedDate }); + conditions["finishedDate"] = payload.finishedDate; // Assuming this is a specific date comparison } if (payload.capacity) { - conditions.push({ capacity: payload.capacity }); + conditions["capacity"] = payload.capacity; } if (payload.creatorId) { - conditions.push({ creatorId: payload.creatorId }); + conditions["creatorId"] = payload.creatorId; } if (payload.startedAfter) { const startedAfterDate = getDate(payload.startedAfter); - conditions.push({ startedDate: MoreThan(startedAfterDate) }); + conditions["startedDate"] = MoreThan(payload.startedAfter); } if (payload.startedBefore) { const startedBeforeDate = getDate(payload.startedBefore); - conditions.push({ startedDate: LessThan(startedBeforeDate) }); + conditions["startedDate"] = LessThan(payload.startedBefore); } if (payload.finishedAfter) { const finishedAfterDate = getDate(payload.finishedAfter); - conditions.push({ finishedDate: MoreThan(finishedAfterDate) }); + conditions["finishedDate"] = MoreThan(payload.finishedAfter); } if (payload.finishedBefore) { const finishedBeforeDate = getDate(payload.finishedBefore); - conditions.push({ finishedDate: LessThan(finishedBeforeDate) }); + conditions["finishedDate"] = LessThan(payload.finishedBefore); } if (payload.ratingMore) { - conditions.push({ rating: MoreThanOrEqual(payload.ratingMore) }); + conditions["rating"] = MoreThanOrEqual(payload.ratingMore); } if (payload.ratingLess) { - conditions.push({ rating: LessThanOrEqual(payload.ratingLess) }); + conditions["rating"] = LessThanOrEqual(payload.ratingLess); } const [voluntaryWorks, total] = await VoluntaryWork.findAndCount({ - where: conditions.length > 0 ? conditions : {}, + where: Object.keys(conditions).length > 0 ? conditions : {}, skip: pageSize * (page - 1), take: pageSize, order: { @@ -156,14 +144,38 @@ const getVoluntaryWorks = async (payload: NSVoluntaryWork.GetVoluntaryWorks) => relations: ['skillTags', 'volunteerProfiles'] }); + const processedVW = voluntaryWorks.map(vw => { + return { + name: vw.name, + description: vw.description, + days: vw.days, + time: vw.time, + location: vw.location, + startedDate: vw.startedDate, + finishedDate: vw.finishedDate, + status: vw.status, + images: vw.images, + rating: vw.rating, + feedback: vw.feedback, + capacity: vw.capacity, + skillTags: vw.skillTags.map(st => { return { name: st.name } }), + volunteers: vw.volunteerProfiles.map(async vp => { + const v = await Volunteer.findOne({ where: { volunteerProfile: { id: vp.id } } }); + return { + name: v?.name + } + }), + volunteerNumbers: vw.volunteerProfiles.length, + createdAt: vw.createdAt + }; + + }); + return { page, pageSize: voluntaryWorks.length, total, - voluntaryWorks: voluntaryWorks.map(voluntaryWork => ({ - ...voluntaryWork, - volunteerNumbers: voluntaryWork.volunteerProfiles.length, - })) + voluntaryWorks: processedVW }; } @@ -210,7 +222,7 @@ const putImages = async (id: number, uploadedFiles: UploadedFile[]) => { voluntaryWork.images.push(...imageUrls); await voluntaryWork.save(); } - catch(err){ + catch (err) { console.log(err); return "Internet Error!"; } diff --git a/src/controllers/volunteer.ts b/src/controllers/volunteer.ts index cff4a322..afa48c38 100644 --- a/src/controllers/volunteer.ts +++ b/src/controllers/volunteer.ts @@ -168,7 +168,7 @@ const getVolunteers = async (payload: NSVolunteer.Item & { page: string; pageSiz const processedVolunteers = volunteers.map((volunteer) => { // Create a new volunteer object with the desired properties - const processedVolunteer = { + return { name: volunteer.name, email: volunteer.email, type: volunteer.type, @@ -184,8 +184,6 @@ const getVolunteers = async (payload: NSVolunteer.Item & { page: string; pageSiz }), }, }; - - return processedVolunteer; }); const filteredVolunteers = processedVolunteers.filter((volunteer) => { @@ -207,9 +205,6 @@ const getVolunteers = async (payload: NSVolunteer.Item & { page: string; pageSiz }; }; -// "availableTime", -// "availableLocation", -// "availableDays", export { getVolunteers, login, createVolunteer, deleteVolunteer, editVolunteer } diff --git a/src/db/entities/VoluntaryWork.ts b/src/db/entities/VoluntaryWork.ts index 4a40343b..9185c81b 100644 --- a/src/db/entities/VoluntaryWork.ts +++ b/src/db/entities/VoluntaryWork.ts @@ -47,7 +47,7 @@ export class VoluntaryWork extends BaseEntity { @Column({ type: 'json', nullable: true }) images: string[]; - @Column({ nullable: true }) + @Column({ nullable: true, default:0 }) rating: number; @Column({ type: 'json', nullable: true }) diff --git a/src/middleware/auth/authorize.ts b/src/middleware/auth/authorize.ts index 4d6c7e1d..7c03bb80 100644 --- a/src/middleware/auth/authorize.ts +++ b/src/middleware/auth/authorize.ts @@ -59,14 +59,14 @@ const checkMe = (req: express.Request, res: express.Response, next: express.Next } -const checkAdmin = async (req: express.Request, res: express.Response, next: express.NextFunction) => { +const checkAdmin = async (req: express.Request, res: express.Response, next: express.NextFunction) => { const id = req.params.id; const admin = await OrganizationAdmin.findOne({ where: { orgProfile: { id } } }); if (res.locals.organizationAdmin) { if (res.locals.organizationAdmin.id == admin?.id) { next(); - }else{ + } else { next(createError(401)); } } else { @@ -76,19 +76,23 @@ const checkAdmin = async (req: express.Request, res: express.Response, next: exp const checkCreator = async (req: express.Request, res: express.Response, next: express.NextFunction) => { const id = Number(req.params.id); + let voluntaryWork = await VoluntaryWork.findOne({ where: { id } }); if (res.locals.organizationAdmin) { if (res.locals.organizationAdmin.id == voluntaryWork?.creatorId) { next(); + } else { + next(createError(401)); } } else if (res.locals.volunteer) { - if (res.locals.volunteer.id == voluntaryWork?.creatorId) { + if (res.locals.volunteer?.id == voluntaryWork?.creatorId) { next(); - }else{ + } else { next(createError(401)); } } else { + next(createError(401)); } } diff --git a/src/middleware/validation/voluntaryWork.ts b/src/middleware/validation/voluntaryWork.ts index d84c80fd..89757a5b 100644 --- a/src/middleware/validation/voluntaryWork.ts +++ b/src/middleware/validation/voluntaryWork.ts @@ -13,7 +13,7 @@ const validateVoluntaryWork = (req: express.Request, const voluntaryWork = req.body; const errorList = values.map(key => !voluntaryWork[key] && `${key} is Required!`).filter(Boolean); - const validStatus = voluntaryWork.status.every((status: string) => Object.values(NSVoluntaryWork.StatusType).includes(status as NSVoluntaryWork.StatusType)); + const validStatus = Object.values(NSVoluntaryWork.StatusType).includes(voluntaryWork.status); if (!validStatus) { errorList.push("Invalid status !"); } @@ -38,7 +38,7 @@ const validateVoluntaryWork = (req: express.Request, errorList.push("The started date should be before the finished date !"); } - if (errorList.length) { + if (errorList.length > 0) { res.status(400).send(errorList); } else { next(); @@ -53,14 +53,14 @@ const validateEditedVoluntaryWork = async (req: express.Request, const errorList = []; const id = Number(req.params.id.toString()); - const vw = await VoluntaryWork.findOne({where:{id}}); - if(!vw){ + const vw = await VoluntaryWork.findOne({ where: { id } }); + if (!vw) { //res.status(400).send("Id not valid"); next(createError(404)); } if (voluntaryWork.status) { - const validStatus = voluntaryWork.status.every((status: string) => Object.values(NSVoluntaryWork.StatusType).includes(status as NSVoluntaryWork.StatusType)); + const validStatus = Object.values(NSVoluntaryWork.StatusType).includes(voluntaryWork.status); if (!validStatus) { errorList.push("Invalid status !"); } @@ -94,11 +94,11 @@ const validateEditedVoluntaryWork = async (req: express.Request, if (getDate(voluntaryWork.startedDate) > getDate(voluntaryWork.finishedDate)) { errorList.push("The started date should be before the finished date !"); } - }else if (voluntaryWork.startedDate && vw){ + } else if (voluntaryWork.startedDate && vw) { if (getDate(voluntaryWork.startedDate) > vw.finishedDate) { errorList.push("The started date should be before the finished date !"); } - }else if (voluntaryWork.finishedDate && vw){ + } else if (voluntaryWork.finishedDate && vw) { if (vw.startedDate > getDate(voluntaryWork.finishedDate)) { errorList.push("The started date should be before the finished date !"); } diff --git a/src/routes/voluntaryWork.ts b/src/routes/voluntaryWork.ts index 2b91c333..07b37ab1 100644 --- a/src/routes/voluntaryWork.ts +++ b/src/routes/voluntaryWork.ts @@ -8,8 +8,8 @@ import { UploadedFile } from 'express-fileupload'; var router = express.Router(); -router.post('/', authorize("POST_voluntaryWork"), validateVoluntaryWork, (req, res, next) => { - createVoluntaryWork({ ...req.body, creatorId: res.locals.volunteer.id || res.locals.organizationAdmin.id }).then(() => { +router.post('/', authorize("POST_voluntaryWork"), validateVoluntaryWork, (req, res, next) => { + createVoluntaryWork({ ...req.body, creatorId: res.locals.volunteer?.id || res.locals.organizationAdmin?.id }).then(() => { res.status(201).send("Voluntary work created successfully!!") }).catch(err => { // console.error(err); @@ -18,7 +18,7 @@ router.post('/', authorize("POST_voluntaryWork"), validateVoluntaryWork, (req, r }); }); -router.delete('/:id', authorize("DELETE_voluntaryWork"), checkCreator, async (req, res, next) => { +router.delete('/:id', authorize("DELETE_voluntaryWork"), async (req, res, next) => { const id = Number(req.params.id?.toString()); deleteVoluntaryWork(id) @@ -31,7 +31,7 @@ router.delete('/:id', authorize("DELETE_voluntaryWork"), checkCreator, async (re }); }) -router.put("/:id", authorize("PUT_voluntaryWork"), checkCreator,validateEditedVoluntaryWork, async (req, res, next) => { +router.put("/:id", authorize("PUT_voluntaryWork"),validateEditedVoluntaryWork, async (req, res, next) => { editVoluntaryWork({ ...req.body, id: req.params.id?.toString() }).then(() => { res.status(201).send("Voluntary Work edited successfully!!") }).catch(err => { From 1a50c882fcbda59abca086b6573b53fa32ff0e9d Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Sun, 8 Oct 2023 16:28:16 +0300 Subject: [PATCH 082/146] Edit get volunteers to need attributes with subrelations --- src/controllers/voluntaryWork.ts | 46 ++++++++++++++++++----------- src/middleware/auth/authenticate.ts | 2 +- src/routes/voluntaryWork.ts | 13 ++++---- 3 files changed, 38 insertions(+), 23 deletions(-) diff --git a/src/controllers/voluntaryWork.ts b/src/controllers/voluntaryWork.ts index 108ff7b4..7865b439 100644 --- a/src/controllers/voluntaryWork.ts +++ b/src/controllers/voluntaryWork.ts @@ -68,7 +68,7 @@ const getVoluntaryWorks = async (payload: NSVoluntaryWork.GetVoluntaryWorks) => const page = parseInt(payload.page); const pageSize = parseInt(payload.pageSize); const conditions: Record = {}; - + if (payload.id) { conditions["id"] = payload.id; } @@ -135,7 +135,7 @@ const getVoluntaryWorks = async (payload: NSVoluntaryWork.GetVoluntaryWorks) => } const [voluntaryWorks, total] = await VoluntaryWork.findAndCount({ - where: Object.keys(conditions).length > 0 ? conditions : {}, + where: conditions, skip: pageSize * (page - 1), take: pageSize, order: { @@ -143,8 +143,14 @@ const getVoluntaryWorks = async (payload: NSVoluntaryWork.GetVoluntaryWorks) => }, relations: ['skillTags', 'volunteerProfiles'] }); - - const processedVW = voluntaryWorks.map(vw => { + const processedVW = await Promise.all(voluntaryWorks.map(async vw => { + const volunteers = []; + for (const vp of vw.volunteerProfiles) { + const v = await Volunteer.findOne({ where: { volunteerProfile: { id: vp.id } } }); + if (v) { + volunteers.push({ name: v.name }); + } + } return { name: vw.name, description: vw.description, @@ -159,17 +165,12 @@ const getVoluntaryWorks = async (payload: NSVoluntaryWork.GetVoluntaryWorks) => feedback: vw.feedback, capacity: vw.capacity, skillTags: vw.skillTags.map(st => { return { name: st.name } }), - volunteers: vw.volunteerProfiles.map(async vp => { - const v = await Volunteer.findOne({ where: { volunteerProfile: { id: vp.id } } }); - return { - name: v?.name - } - }), - volunteerNumbers: vw.volunteerProfiles.length, + volunteers, + volunteerNumbers: volunteers.length, createdAt: vw.createdAt }; + })); - }); return { page, @@ -251,15 +252,22 @@ const registerByVolunteer = async (workId: number, volunteerProfile: Volunteer[" throw new Error("VoluntaryWork is already at full capacity"); } - voluntaryWork.volunteerProfiles.push(volunteerProfile); - await voluntaryWork.save(); + if (voluntaryWork.volunteerProfiles) { + voluntaryWork.volunteerProfiles.push(volunteerProfile); + } else { + voluntaryWork.volunteerProfiles = [volunteerProfile]; + } + await voluntaryWork.save(); return "Registration successful!"; } const registerByOrganizationAdmin = async (workId: number, volunteerId: string) => { const voluntaryWork = await VoluntaryWork.findOne({ where: { id: workId } }); - const volunteer = await Volunteer.findOne({ where: { id: volunteerId } }); + const volunteer = await Volunteer.findOne({ + where: { id: volunteerId }, + relations: ["roles", "roles.permissions", "volunteerProfile"] + }); if (!voluntaryWork) { throw createError(404); @@ -268,9 +276,13 @@ const registerByOrganizationAdmin = async (workId: number, volunteerId: string) throw createError(404); } - voluntaryWork.volunteerProfiles.push(volunteer.volunteerProfile); - await voluntaryWork.save(); + if (voluntaryWork.volunteerProfiles) { + voluntaryWork.volunteerProfiles.push(volunteer.volunteerProfile); + } else { + voluntaryWork.volunteerProfiles = [volunteer.volunteerProfile]; + } + await voluntaryWork.save(); return "Registration successful!"; } diff --git a/src/middleware/auth/authenticate.ts b/src/middleware/auth/authenticate.ts index 32ef8696..60e32be1 100644 --- a/src/middleware/auth/authenticate.ts +++ b/src/middleware/auth/authenticate.ts @@ -27,7 +27,7 @@ const authenticate = async ( }); const volunteer = await Volunteer.findOne({ where: { name: decoded.name, email: decoded.email, id: decoded.id }, - relations: ["roles", "roles.permissions"] + relations: ["roles", "roles.permissions", "volunteerProfile"] }); if (organizationAdmin) { diff --git a/src/routes/voluntaryWork.ts b/src/routes/voluntaryWork.ts index 07b37ab1..9e613d87 100644 --- a/src/routes/voluntaryWork.ts +++ b/src/routes/voluntaryWork.ts @@ -5,6 +5,7 @@ import { NSVoluntaryWork } from '../../types/voluntaryWork.js'; import { authorize, checkCreator, checkParticipation } from '../middleware/auth/authorize.js'; import { validateEditedVoluntaryWork, validateVoluntaryWork } from '../middleware/validation/voluntaryWork.js'; import { UploadedFile } from 'express-fileupload'; +import { Volunteer } from '../db/entities/Volunteer.js'; var router = express.Router(); @@ -156,16 +157,18 @@ router.put("/images/:id", authorize("PUT_images"), async (req, res, next) => { }); }); -router.put("/register/:id", authorize("REGISTER_voluntaryWork"), async (req, res, next) => { - if (res.locals.volunteer) { - registerByVolunteer(Number(req.params.id), res.locals.volunteer["volunteerProfile"]).then(() => { +router.put("/register/:id", authorize("REGISTER_voluntaryWork"), async (req, res, next) => { + if (res.locals.volunteer) { + registerByVolunteer(Number(req.params.id), res.locals.volunteer.volunteerProfile).then(() => { res.status(201).send("Registration done successfully!!") }).catch(err => { - // console.error(err); + console.error(err); // res.status(500).send(err); next(err); }); } else if (res.locals.organizationAdmin) { + + if (!req.body.volunteerId.toString()) { res.status(400).send("volunteer id is required!"); } @@ -173,7 +176,7 @@ router.put("/register/:id", authorize("REGISTER_voluntaryWork"), async (req, res registerByOrganizationAdmin(Number(req.params.id), req.body.volunteerId.toString()).then(() => { res.status(201).send("Registration done successfully!!") }).catch(err => { - // console.error(err); + console.error(err); // res.status(500).send(err); next(err); }); From eb06231cbc79aed5f24ebaf668533b6ee133e825 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Sun, 8 Oct 2023 16:46:36 +0300 Subject: [PATCH 083/146] edit registration in vw --- src/controllers/voluntaryWork.ts | 15 ++++++++------- src/db/entities/VoluntaryWork.ts | 11 +++++------ src/db/entities/VolunteerProfile.ts | 11 +++++------ 3 files changed, 18 insertions(+), 19 deletions(-) diff --git a/src/controllers/voluntaryWork.ts b/src/controllers/voluntaryWork.ts index 7865b439..1d592471 100644 --- a/src/controllers/voluntaryWork.ts +++ b/src/controllers/voluntaryWork.ts @@ -75,7 +75,7 @@ const getVoluntaryWorks = async (payload: NSVoluntaryWork.GetVoluntaryWorks) => if (payload.name) { conditions["name"] = payload.name; } - if (payload.time.length > 0) { + if (payload.time?.length > 0) { conditions["time"] = In(payload.time); } if (payload.location) { @@ -87,10 +87,10 @@ const getVoluntaryWorks = async (payload: NSVoluntaryWork.GetVoluntaryWorks) => if (payload.status) { conditions["status"] = payload.status; } - if (payload.days.length > 0) { + if (payload.days?.length > 0) { conditions["days"] = In(payload.days); } - if (payload.skills.length > 0) { + if (payload.skills?.length > 0) { conditions["skillTags"] = In(payload.skills); } if (payload.startedDate) { @@ -238,17 +238,18 @@ const registerByVolunteer = async (workId: number, volunteerProfile: Volunteer[" if (!voluntaryWork) { throw createError(404); } + console.log(volunteerProfile.availableDays); if ( volunteerProfile.availableLocation !== voluntaryWork.location || - !volunteerProfile.availableDays.every(day => voluntaryWork.days.includes(day)) || - !volunteerProfile.availableTime.every(time => voluntaryWork.time.includes(time)) || - !volunteerProfile.skillTags.every(skillTag => voluntaryWork.skillTags.some(workSkill => workSkill.id === skillTag.id)) + !(volunteerProfile.availableDays?.length > 0 && volunteerProfile.availableDays?.every(day => voluntaryWork.days.includes(day))) || + !(volunteerProfile.availableTime?.length > 0 && volunteerProfile.availableTime?.every(time => voluntaryWork.time.includes(time))) || + !(volunteerProfile.skillTags?.length > 0 && volunteerProfile.skillTags.every(skillTag => voluntaryWork.skillTags.some(workSkill => workSkill.id === skillTag.id))) ) { throw new Error("Volunteer's profile information does not align with the VoluntaryWork information"); } - if (voluntaryWork.volunteerProfiles.length >= voluntaryWork.capacity) { + if (voluntaryWork.volunteerProfiles?.length >= voluntaryWork.capacity) { throw new Error("VoluntaryWork is already at full capacity"); } diff --git a/src/db/entities/VoluntaryWork.ts b/src/db/entities/VoluntaryWork.ts index 9185c81b..e3eee552 100644 --- a/src/db/entities/VoluntaryWork.ts +++ b/src/db/entities/VoluntaryWork.ts @@ -2,6 +2,7 @@ import { BaseEntity, Column, CreateDateColumn, Entity, JoinTable, ManyToMany, Ma import { SkillTag } from "./SkillTag.js"; import { VolunteerProfile } from "./VolunteerProfile.js"; import { OrganizationProfile } from "./OrganizationProfile.js"; +import { NSVolunteer } from "../../../types/volunteer.js"; @Entity() export class VoluntaryWork extends BaseEntity { @@ -15,18 +16,16 @@ export class VoluntaryWork extends BaseEntity { description: string; @Column({ - type: 'enum', - enum: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], + type: 'json', nullable: false }) - days: ('Sunday' | 'Monday' | 'Tuesday' | 'Wednesday' | 'Thursday' | 'Friday' | 'Saturday')[]; + days: NSVolunteer.AvailableDays[]; @Column({ - type: 'enum', - enum: ['Morning', 'Afternoon'], + type: 'json', nullable: false }) - time: ('Morning' | 'Afternoon')[]; + time: NSVolunteer.AvailableTime[]; @Column({ nullable: false }) location: string; diff --git a/src/db/entities/VolunteerProfile.ts b/src/db/entities/VolunteerProfile.ts index 26f2dea8..6b1240bb 100644 --- a/src/db/entities/VolunteerProfile.ts +++ b/src/db/entities/VolunteerProfile.ts @@ -1,6 +1,7 @@ import { BaseEntity, Column, CreateDateColumn, Entity, JoinTable, ManyToMany, PrimaryGeneratedColumn } from "typeorm"; import { SkillTag } from "./SkillTag.js"; import { VoluntaryWork } from "./VoluntaryWork.js"; +import { NSVolunteer } from "../../../types/volunteer.js"; @Entity() export class VolunteerProfile extends BaseEntity { @@ -8,18 +9,16 @@ export class VolunteerProfile extends BaseEntity { id: string; @Column({ - type: 'enum', - enum: ['Morning', 'Afternoon'], + type: 'json', nullable: false }) - availableTime: ('Morning' | 'Afternoon')[]; + availableTime: NSVolunteer.AvailableTime[]; @Column({ - type: 'enum', - enum: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], + type: 'json', nullable: false }) - availableDays: ('Sunday' | 'Monday' | 'Tuesday' | 'Wednesday' | 'Thursday' | 'Friday' | 'Saturday')[]; + availableDays:NSVolunteer.AvailableDays[]; @Column({ nullable: false }) availableLocation: string; From dbaa9d6a48834daed49d65cf396c1c434e133adf Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Sun, 8 Oct 2023 16:58:07 +0300 Subject: [PATCH 084/146] edit the deregistration function --- src/controllers/voluntaryWork.ts | 32 ++++++++++++++++++++++++++++---- src/routes/voluntaryWork.ts | 9 +++++---- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/src/controllers/voluntaryWork.ts b/src/controllers/voluntaryWork.ts index 1d592471..14d8718d 100644 --- a/src/controllers/voluntaryWork.ts +++ b/src/controllers/voluntaryWork.ts @@ -287,9 +287,33 @@ const registerByOrganizationAdmin = async (workId: number, volunteerId: string) return "Registration successful!"; } +// const deregisterVoluntaryWork = async (workId: number, volunteerId: string) => { +// const voluntaryWork = await VoluntaryWork.findOne({ where: { id: workId }, relations: ["volunteerProfiles"] }); +// const volunteer = await Volunteer.findOne({ where: { id: volunteerId } }); + +// if (!voluntaryWork) { +// throw createError(404); +// } + +// if (!volunteer) { +// throw createError(404); +// } +// console.log('voluntaryWork:', voluntaryWork); +// console.log('volunteer:', volunteer); +// const index = voluntaryWork.volunteerProfiles.findIndex(profile => profile.id === volunteer.volunteerProfile.id); + +// if (index !== -1) { +// voluntaryWork.volunteerProfiles.splice(index, 1); +// await voluntaryWork.save(); +// return "Deregistration successful!"; +// } else { +// throw new Error("Volunteer is not registered for this voluntary work"); +// } +// } + const deregisterVoluntaryWork = async (workId: number, volunteerId: string) => { const voluntaryWork = await VoluntaryWork.findOne({ where: { id: workId }, relations: ["volunteerProfiles"] }); - const volunteer = await Volunteer.findOne({ where: { id: volunteerId } }); + const volunteer = await Volunteer.findOne({ where: { id: volunteerId },relations: ["volunteerProfile"] }); if (!voluntaryWork) { throw createError(404); @@ -298,9 +322,10 @@ const deregisterVoluntaryWork = async (workId: number, volunteerId: string) => { if (!volunteer) { throw createError(404); } - + // Check if the volunteer is registered for this voluntary work const index = voluntaryWork.volunteerProfiles.findIndex(profile => profile.id === volunteer.volunteerProfile.id); - + console.log(index); + if (index !== -1) { voluntaryWork.volunteerProfiles.splice(index, 1); await voluntaryWork.save(); @@ -310,7 +335,6 @@ const deregisterVoluntaryWork = async (workId: number, volunteerId: string) => { } } - export { deregisterVoluntaryWork, registerByOrganizationAdmin, registerByVolunteer, putImages, createVoluntaryWork, diff --git a/src/routes/voluntaryWork.ts b/src/routes/voluntaryWork.ts index 9e613d87..9bd9495a 100644 --- a/src/routes/voluntaryWork.ts +++ b/src/routes/voluntaryWork.ts @@ -176,7 +176,7 @@ router.put("/register/:id", authorize("REGISTER_voluntaryWork"), async (req, res registerByOrganizationAdmin(Number(req.params.id), req.body.volunteerId.toString()).then(() => { res.status(201).send("Registration done successfully!!") }).catch(err => { - console.error(err); + // console.error(err); // res.status(500).send(err); next(err); }); @@ -184,15 +184,16 @@ router.put("/register/:id", authorize("REGISTER_voluntaryWork"), async (req, res }); router.put("/deregister/:id", authorize("DEREGISTER_voluntaryWork"), async (req, res, next) => { - if( res.locals.volunteer.id || req.body.volunteerId.toString()){ + + if( !res.locals.volunteer?.id && !req.body.volunteerId?.toString()){ res.status(400).send("Volunteer id is required !"); } deregisterVoluntaryWork(Number(req.params.id), res.locals.volunteer.id || req.body.volunteerId.toString()).then(() => { res.status(201).send("Deregistration done successfully!!") }).catch(err => { // console.error(err); - // res.status(500).send(err); - next(err); + res.status(500).send(err); + //next(err); }); }); From ed9dad0789aa80596bfab1d944977df4824dfc7e Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Sun, 8 Oct 2023 17:15:31 +0300 Subject: [PATCH 085/146] edit put reating fun and validation --- src/controllers/voluntaryWork.ts | 33 ++++++-------------------------- src/middleware/auth/authorize.ts | 30 ++++++++++++++++++----------- src/routes/voluntaryWork.ts | 6 +++--- 3 files changed, 28 insertions(+), 41 deletions(-) diff --git a/src/controllers/voluntaryWork.ts b/src/controllers/voluntaryWork.ts index 14d8718d..c52ddb95 100644 --- a/src/controllers/voluntaryWork.ts +++ b/src/controllers/voluntaryWork.ts @@ -183,8 +183,12 @@ const getVoluntaryWorks = async (payload: NSVoluntaryWork.GetVoluntaryWorks) => const putRating = async (id: number, rating: number) => { let voluntaryWork = await VoluntaryWork.findOne({ where: { id } }); if (voluntaryWork) { - voluntaryWork.rating += rating; - voluntaryWork.rating /= 2; + if (voluntaryWork.rating){ + voluntaryWork.rating += rating; + voluntaryWork.rating /= 2; + }else{ + voluntaryWork.rating=rating; + } return voluntaryWork.save(); } else { throw createError(404); @@ -238,7 +242,6 @@ const registerByVolunteer = async (workId: number, volunteerProfile: Volunteer[" if (!voluntaryWork) { throw createError(404); } - console.log(volunteerProfile.availableDays); if ( volunteerProfile.availableLocation !== voluntaryWork.location || @@ -287,29 +290,6 @@ const registerByOrganizationAdmin = async (workId: number, volunteerId: string) return "Registration successful!"; } -// const deregisterVoluntaryWork = async (workId: number, volunteerId: string) => { -// const voluntaryWork = await VoluntaryWork.findOne({ where: { id: workId }, relations: ["volunteerProfiles"] }); -// const volunteer = await Volunteer.findOne({ where: { id: volunteerId } }); - -// if (!voluntaryWork) { -// throw createError(404); -// } - -// if (!volunteer) { -// throw createError(404); -// } -// console.log('voluntaryWork:', voluntaryWork); -// console.log('volunteer:', volunteer); -// const index = voluntaryWork.volunteerProfiles.findIndex(profile => profile.id === volunteer.volunteerProfile.id); - -// if (index !== -1) { -// voluntaryWork.volunteerProfiles.splice(index, 1); -// await voluntaryWork.save(); -// return "Deregistration successful!"; -// } else { -// throw new Error("Volunteer is not registered for this voluntary work"); -// } -// } const deregisterVoluntaryWork = async (workId: number, volunteerId: string) => { const voluntaryWork = await VoluntaryWork.findOne({ where: { id: workId }, relations: ["volunteerProfiles"] }); @@ -322,7 +302,6 @@ const deregisterVoluntaryWork = async (workId: number, volunteerId: string) => { if (!volunteer) { throw createError(404); } - // Check if the volunteer is registered for this voluntary work const index = voluntaryWork.volunteerProfiles.findIndex(profile => profile.id === volunteer.volunteerProfile.id); console.log(index); diff --git a/src/middleware/auth/authorize.ts b/src/middleware/auth/authorize.ts index 7c03bb80..3621bd12 100644 --- a/src/middleware/auth/authorize.ts +++ b/src/middleware/auth/authorize.ts @@ -97,29 +97,37 @@ const checkCreator = async (req: express.Request, res: express.Response, next: e } } -const checkParticipation = async ( - req: express.Request, - res: express.Response, - next: express.NextFunction -) => { +const checkParticipation = async (req: express.Request, res: express.Response, next: express.NextFunction) => { const id = Number(req.params.id); - + if (res.locals.volunteer) { const volunteer = res.locals.volunteer; const volunteerProfile = volunteer.volunteerProfile; - + if (volunteerProfile) { const voluntaryWork = await VoluntaryWork.findOne({ where: { id }, relations: ['volunteerProfiles'] }); - - if (voluntaryWork && voluntaryWork.volunteerProfiles.includes(volunteerProfile)) { - next(); + + if (voluntaryWork) { + // Check if volunteerProfile.id exists in the array of volunteerProfiles' ids + const isParticipating = voluntaryWork.volunteerProfiles.some(profile => profile.id === volunteerProfile.id); + + if (isParticipating) { + next(); + } else { + next(createError(401)); + } + } else { + next(createError(404)); // Optional: Handle the case when voluntaryWork is not found } + } else { + next(createError(401)); // Handle the case when volunteerProfile is not defined } + } else { + next(createError(401)); // Handle the case when res.locals.volunteer is not defined } - next(createError(401)); }; diff --git a/src/routes/voluntaryWork.ts b/src/routes/voluntaryWork.ts index 9bd9495a..957b3fab 100644 --- a/src/routes/voluntaryWork.ts +++ b/src/routes/voluntaryWork.ts @@ -162,7 +162,7 @@ router.put("/register/:id", authorize("REGISTER_voluntaryWork"), async (req, res registerByVolunteer(Number(req.params.id), res.locals.volunteer.volunteerProfile).then(() => { res.status(201).send("Registration done successfully!!") }).catch(err => { - console.error(err); + // console.error(err); // res.status(500).send(err); next(err); }); @@ -192,8 +192,8 @@ router.put("/deregister/:id", authorize("DEREGISTER_voluntaryWork"), async (req, res.status(201).send("Deregistration done successfully!!") }).catch(err => { // console.error(err); - res.status(500).send(err); - //next(err); + //res.status(500).send(err); + next(err); }); }); From 4e70873d0005c1f40ac14d2e68f74e20a7c43985 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Sun, 8 Oct 2023 17:32:22 +0300 Subject: [PATCH 086/146] edit s3 --- src/controllers/voluntaryWork.ts | 45 +++++++++++++++----------------- src/middleware/auth/authorize.ts | 16 +++++++----- 2 files changed, 31 insertions(+), 30 deletions(-) diff --git a/src/controllers/voluntaryWork.ts b/src/controllers/voluntaryWork.ts index c52ddb95..88037ebd 100644 --- a/src/controllers/voluntaryWork.ts +++ b/src/controllers/voluntaryWork.ts @@ -183,11 +183,11 @@ const getVoluntaryWorks = async (payload: NSVoluntaryWork.GetVoluntaryWorks) => const putRating = async (id: number, rating: number) => { let voluntaryWork = await VoluntaryWork.findOne({ where: { id } }); if (voluntaryWork) { - if (voluntaryWork.rating){ + if (voluntaryWork.rating) { voluntaryWork.rating += rating; voluntaryWork.rating /= 2; - }else{ - voluntaryWork.rating=rating; + } else { + voluntaryWork.rating = rating; } return voluntaryWork.save(); } else { @@ -206,32 +206,29 @@ const putFeedback = async (id: number, feedback: string) => { } const putImages = async (id: number, uploadedFiles: UploadedFile[]) => { + let voluntaryWork = await VoluntaryWork.findOne({ where: { id } }); if (voluntaryWork) { - try { - const S3 = await configureS3Bucket(); - const imageUrls = []; + const S3 = await configureS3Bucket(); + const imageUrls = []; - for (const file of uploadedFiles) { - const uploadParams = { - Bucket: process.env.AWS_BUCKET_NAME || '', - Body: Buffer.from(file.data), - Key: `${Date.now().toString()}.png`, - ACL: 'public-read', - }; + for (const file of uploadedFiles) { + const uploadParams = { + Bucket: process.env.AWS_BUCKET_NAME || '', + Body: Buffer.from(file.data), + Key: `${Date.now().toString()}.png`, + ACL: 'public-read', + }; - const data = await S3.upload(uploadParams).promise(); - imageUrls.push(data.Location); - } - voluntaryWork.images.push(...imageUrls); - await voluntaryWork.save(); - } - catch (err) { - console.log(err); - return "Internet Error!"; + const data = await S3.upload(uploadParams).promise(); + imageUrls.push(data.Location); } + voluntaryWork.images.push(...imageUrls); + await voluntaryWork.save(); + + } else { throw createError(404); } @@ -293,7 +290,7 @@ const registerByOrganizationAdmin = async (workId: number, volunteerId: string) const deregisterVoluntaryWork = async (workId: number, volunteerId: string) => { const voluntaryWork = await VoluntaryWork.findOne({ where: { id: workId }, relations: ["volunteerProfiles"] }); - const volunteer = await Volunteer.findOne({ where: { id: volunteerId },relations: ["volunteerProfile"] }); + const volunteer = await Volunteer.findOne({ where: { id: volunteerId }, relations: ["volunteerProfile"] }); if (!voluntaryWork) { throw createError(404); @@ -304,7 +301,7 @@ const deregisterVoluntaryWork = async (workId: number, volunteerId: string) => { } const index = voluntaryWork.volunteerProfiles.findIndex(profile => profile.id === volunteer.volunteerProfile.id); console.log(index); - + if (index !== -1) { voluntaryWork.volunteerProfiles.splice(index, 1); await voluntaryWork.save(); diff --git a/src/middleware/auth/authorize.ts b/src/middleware/auth/authorize.ts index 3621bd12..84b3e925 100644 --- a/src/middleware/auth/authorize.ts +++ b/src/middleware/auth/authorize.ts @@ -33,10 +33,14 @@ const authorize = (api: string) => { checkAdmin(req, res, next); } else if ((/organizationAdmin$/.test(api)) || (/volunteer$/.test(api))) { checkMe(req, res, next); - } else if ((/voluntaryWork$/.test(api))) { + } else if ((/voluntaryWork$/.test(api)) || ((/images/.test(api)))) { checkCreator(req, res, next); + }else { + res.status(403).send("You don't have the permission to access this resource!"); } } else { + + res.status(403).send("You don't have the permission to access this resource!"); } } @@ -99,24 +103,24 @@ const checkCreator = async (req: express.Request, res: express.Response, next: e const checkParticipation = async (req: express.Request, res: express.Response, next: express.NextFunction) => { const id = Number(req.params.id); - + if (res.locals.volunteer) { const volunteer = res.locals.volunteer; const volunteerProfile = volunteer.volunteerProfile; - + if (volunteerProfile) { const voluntaryWork = await VoluntaryWork.findOne({ where: { id }, relations: ['volunteerProfiles'] }); - + if (voluntaryWork) { // Check if volunteerProfile.id exists in the array of volunteerProfiles' ids const isParticipating = voluntaryWork.volunteerProfiles.some(profile => profile.id === volunteerProfile.id); - + if (isParticipating) { next(); - } else { + } else { next(createError(401)); } } else { From 4367a5dcfbc87e7afb651fef39598895711c11cf Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Sun, 8 Oct 2023 17:41:46 +0300 Subject: [PATCH 087/146] Adding the id validation middleware for all routes --- .../validation/organizationAdmin.ts | 27 +++++++++++---- src/middleware/validation/role.ts | 17 +++++++++- src/middleware/validation/voluntaryWork.ts | 18 +++++++++- src/middleware/validation/volunteer.ts | 17 +++++++++- src/routes/organizationAdmin.ts | 6 ++-- src/routes/organizationProfile.ts | 4 +-- src/routes/permission.ts | 2 +- src/routes/role.ts | 6 ++-- src/routes/voluntaryWork.ts | 33 +++++++++---------- 9 files changed, 95 insertions(+), 35 deletions(-) diff --git a/src/middleware/validation/organizationAdmin.ts b/src/middleware/validation/organizationAdmin.ts index 8756f40e..9de9c7ec 100644 --- a/src/middleware/validation/organizationAdmin.ts +++ b/src/middleware/validation/organizationAdmin.ts @@ -16,8 +16,8 @@ const validateOrganizationAdmin = (req: express.Request, if (!EmailValidator.validate(organizationAdmin.email)) { errorList.push('Email is not Valid'); } - - errorList.push(...isValidPassword(organizationAdmin.password )); + + errorList.push(...isValidPassword(organizationAdmin.password)); if (errorList.length) { res.status(400).send(errorList); @@ -40,13 +40,13 @@ const validateAdminEdited = async (req: express.Request, next(createError(404)); } - if (organizationAdmin.email){ + if (organizationAdmin.email) { if (!EmailValidator.validate(organizationAdmin.email)) { errorList.push('Email is not Valid'); } } - if (organizationAdmin.password ) - errorList.push(...isValidPassword(organizationAdmin.password )); + if (organizationAdmin.password) + errorList.push(...isValidPassword(organizationAdmin.password)); if (errorList.length) { res.status(400).send(errorList); @@ -55,7 +55,22 @@ const validateAdminEdited = async (req: express.Request, } } +const validateAdminId = async (req: express.Request, + res: express.Response, + next: express.NextFunction +) => { + const id = req.params.id.toString(); + const p = await OrganizationAdmin.findOne({ where: { id } }); + if (!p) { + //res.status(400).send("Id not valid"); + next(createError(404)); + } else { + next(); + } +} + export { validateOrganizationAdmin, - validateAdminEdited + validateAdminEdited, + validateAdminId } \ No newline at end of file diff --git a/src/middleware/validation/role.ts b/src/middleware/validation/role.ts index 364dff09..e4355348 100644 --- a/src/middleware/validation/role.ts +++ b/src/middleware/validation/role.ts @@ -47,8 +47,23 @@ const validateEditedRole = async (req: express.Request, next(); } } +const validateRoleId = async (req: express.Request, + res: express.Response, + next: express.NextFunction + ) => { + const id = Number(req.params.id.toString()); + const p = await Role.findOne({ where: { id } }); + if (!p) { + //res.status(400).send("Id not valid"); + next(createError(404)); + }else{ + next(); + } + } + export { validateRole, - validateEditedRole + validateEditedRole, + validateRoleId } \ No newline at end of file diff --git a/src/middleware/validation/voluntaryWork.ts b/src/middleware/validation/voluntaryWork.ts index 89757a5b..02c30b59 100644 --- a/src/middleware/validation/voluntaryWork.ts +++ b/src/middleware/validation/voluntaryWork.ts @@ -110,7 +110,23 @@ const validateEditedVoluntaryWork = async (req: express.Request, next(); } } + +const validateVoluntaryWorkId = async (req: express.Request, + res: express.Response, + next: express.NextFunction +) => { + const id = Number(req.params.id.toString()); + const p = await VoluntaryWork.findOne({ where: { id } }); + if (!p) { + //res.status(400).send("Id not valid"); + next(createError(404)); + } else { + next(); + } +} + export { validateVoluntaryWork, - validateEditedVoluntaryWork + validateEditedVoluntaryWork, + validateVoluntaryWorkId } \ No newline at end of file diff --git a/src/middleware/validation/volunteer.ts b/src/middleware/validation/volunteer.ts index 9a2e4b4b..878c6856 100644 --- a/src/middleware/validation/volunteer.ts +++ b/src/middleware/validation/volunteer.ts @@ -97,7 +97,22 @@ const validateEditedVolunteer = async (req: express.Request, res: express.Respon } }; +const validateVolunteerId = async (req: express.Request, + res: express.Response, + next: express.NextFunction +) => { + const id = (req.params.id.toString()); + const p = await Volunteer.findOne({ where: { id } }); + if (!p) { + //res.status(400).send("Id not valid"); + next(createError(404)); + } else { + next(); + } +} + export { validateVolunteer, - validateEditedVolunteer + validateEditedVolunteer, + validateVolunteerId } \ No newline at end of file diff --git a/src/routes/organizationAdmin.ts b/src/routes/organizationAdmin.ts index acc5a622..d313ecb7 100644 --- a/src/routes/organizationAdmin.ts +++ b/src/routes/organizationAdmin.ts @@ -1,7 +1,7 @@ import express from "express"; import { createOrganizationAdmin, deleteOrganizationAdmin, editOrganizationAdmin, getOrganizationAdmins } from "../controllers/organizationAdmin.js"; import { authorize, checkMe } from "../middleware/auth/authorize.js"; -import { validateAdminEdited, validateOrganizationAdmin } from "../middleware/validation/organizationAdmin.js"; +import { validateAdminEdited, validateAdminId, validateOrganizationAdmin } from "../middleware/validation/organizationAdmin.js"; const router = express.Router(); @@ -15,7 +15,7 @@ router.post('/', authorize("POST_organizationAdmin"), validateOrganizationAdmin, }); }); -router.delete('/:id', authorize("DELETE_organizationAdmin"), async (req, res, next) => { +router.delete('/:id', validateAdminId, authorize("DELETE_organizationAdmin"), async (req, res, next) => { const id = req.params.id?.toString(); deleteOrganizationAdmin(id) @@ -29,7 +29,7 @@ router.delete('/:id', authorize("DELETE_organizationAdmin"), async (req, res, ne }); }); -router.put("/:id", authorize("PUT_organizationAdmin"), validateAdminEdited, async (req, res, next) => { +router.put("/:id", authorize("PUT_organizationAdmin"), validateAdminEdited, async (req, res, next) => { editOrganizationAdmin({ ...req.body, id: req.params.id }).then(() => { res.status(201).send("Organization Admin edited successfully!!") }).catch(err => { diff --git a/src/routes/organizationProfile.ts b/src/routes/organizationProfile.ts index 6a9088a8..d3d3a3ce 100644 --- a/src/routes/organizationProfile.ts +++ b/src/routes/organizationProfile.ts @@ -15,7 +15,7 @@ router.post('/', authorize("POST_organizationProfile"), validateOrganizationProf }); }); -router.delete('/:id', authorize("DELETE_organizationProfile"), async (req, res, next) => { +router.delete('/:id', validateOrgId, authorize("DELETE_organizationProfile"), async (req, res, next) => { const id = (req.params.id?.toString()); deleteOrganizationProfile(id) @@ -29,7 +29,7 @@ router.delete('/:id', authorize("DELETE_organizationProfile"), async (req, res, }); }); -router.put("/:id", authorize("PUT_organizationProfile"), validateOrgId, async (req, res, next) => { +router.put("/:id", validateOrgId, authorize("PUT_organizationProfile"), async (req, res, next) => { editOrganizationProfile(req.body).then(() => { res.status(201).send("Organization Profile edited successfully!!") }).catch(err => { diff --git a/src/routes/permission.ts b/src/routes/permission.ts index 765defeb..7f39711a 100644 --- a/src/routes/permission.ts +++ b/src/routes/permission.ts @@ -15,7 +15,7 @@ router.post('/', authorize("POST_permissions"), validatePermission, (req, res, n }); }); -router.delete('/:id', authorize("DELETE_permission"), async (req, res, next) => { +router.delete('/:id', validatePermissionId, authorize("DELETE_permission"), async (req, res, next) => { const id = Number(req.params.id?.toString()); deletePermission(id) diff --git a/src/routes/role.ts b/src/routes/role.ts index d5311ae4..510b5a18 100644 --- a/src/routes/role.ts +++ b/src/routes/role.ts @@ -2,7 +2,7 @@ import express from 'express'; import { createRole, deleteRole, editRole, getRoles } from '../controllers/role.js'; import { NSRole } from '../../types/role.js'; import { authorize } from '../middleware/auth/authorize.js'; -import { validateEditedRole, validateRole } from '../middleware/validation/role.js'; +import { validateEditedRole, validateRole, validateRoleId } from '../middleware/validation/role.js'; var router = express.Router(); @@ -16,7 +16,7 @@ router.post('/', authorize("POST_role"), validateRole, (req, res, next) => { }); }); -router.delete('/:id', authorize("DELETE_role"), async (req, res, next) => { +router.delete('/:id', validateRoleId, authorize("DELETE_role"), async (req, res, next) => { const id = Number(req.params.id?.toString()); deleteRole(id) @@ -30,7 +30,7 @@ router.delete('/:id', authorize("DELETE_role"), async (req, res, next) => { }); }) -router.put("/:id", authorize("PUT_role"),validateEditedRole, async (req, res, next) => { +router.put("/:id", authorize("PUT_role"), validateEditedRole, async (req, res, next) => { editRole({ ...req.body, id: req.params.id?.toString() }).then(() => { res.status(201).send("Role edited successfully!!") }).catch(err => { diff --git a/src/routes/voluntaryWork.ts b/src/routes/voluntaryWork.ts index 957b3fab..ffbc5fbf 100644 --- a/src/routes/voluntaryWork.ts +++ b/src/routes/voluntaryWork.ts @@ -2,14 +2,13 @@ import express from 'express'; import { createVoluntaryWork, deleteVoluntaryWork, deregisterVoluntaryWork, editVoluntaryWork, getVoluntaryWork, getVoluntaryWorks, putFeedback, putImages, putRating, registerByOrganizationAdmin, registerByVolunteer } from '../controllers/voluntaryWork.js'; import { NSVolunteer } from '../../types/volunteer.js'; import { NSVoluntaryWork } from '../../types/voluntaryWork.js'; -import { authorize, checkCreator, checkParticipation } from '../middleware/auth/authorize.js'; -import { validateEditedVoluntaryWork, validateVoluntaryWork } from '../middleware/validation/voluntaryWork.js'; +import { authorize, checkParticipation } from '../middleware/auth/authorize.js'; +import { validateEditedVoluntaryWork, validateVoluntaryWork, validateVoluntaryWorkId } from '../middleware/validation/voluntaryWork.js'; import { UploadedFile } from 'express-fileupload'; -import { Volunteer } from '../db/entities/Volunteer.js'; var router = express.Router(); -router.post('/', authorize("POST_voluntaryWork"), validateVoluntaryWork, (req, res, next) => { +router.post('/', authorize("POST_voluntaryWork"), validateVoluntaryWork, (req, res, next) => { createVoluntaryWork({ ...req.body, creatorId: res.locals.volunteer?.id || res.locals.organizationAdmin?.id }).then(() => { res.status(201).send("Voluntary work created successfully!!") }).catch(err => { @@ -19,7 +18,7 @@ router.post('/', authorize("POST_voluntaryWork"), validateVoluntaryWork, (req, r }); }); -router.delete('/:id', authorize("DELETE_voluntaryWork"), async (req, res, next) => { +router.delete('/:id', validateVoluntaryWorkId, authorize("DELETE_voluntaryWork"), async (req, res, next) => { const id = Number(req.params.id?.toString()); deleteVoluntaryWork(id) @@ -32,7 +31,7 @@ router.delete('/:id', authorize("DELETE_voluntaryWork"), async (req, res, next) }); }) -router.put("/:id", authorize("PUT_voluntaryWork"),validateEditedVoluntaryWork, async (req, res, next) => { +router.put("/:id", authorize("PUT_voluntaryWork"), validateEditedVoluntaryWork, async (req, res, next) => { editVoluntaryWork({ ...req.body, id: req.params.id?.toString() }).then(() => { res.status(201).send("Voluntary Work edited successfully!!") }).catch(err => { @@ -127,7 +126,7 @@ router.get('/recommendation', authorize("GET_recommendation"), async (req, res, }); }); -router.put("/rating/:id", authorize("PUT_rating"), checkParticipation, async (req, res, next) => { +router.put("/rating/:id", validateVoluntaryWorkId, authorize("PUT_rating"), checkParticipation, async (req, res, next) => { putRating(Number(req.params.id), Number(req.body.rating)).then(() => { res.status(201).send("Rating added successfully!!") }).catch(err => { @@ -137,7 +136,7 @@ router.put("/rating/:id", authorize("PUT_rating"), checkParticipation, async (re }); }); -router.put("/feedback/:id", authorize("PUT_feedback"), checkParticipation, async (req, res, next) => { +router.put("/feedback/:id", validateVoluntaryWorkId, authorize("PUT_feedback"), checkParticipation, async (req, res, next) => { putFeedback(Number(req.params.id), req.body.feedback).then(() => { res.status(201).send("Feedback added successfully!!") }).catch(err => { @@ -147,7 +146,7 @@ router.put("/feedback/:id", authorize("PUT_feedback"), checkParticipation, async }); }); -router.put("/images/:id", authorize("PUT_images"), async (req, res, next) => { +router.put("/images/:id", validateVoluntaryWorkId, authorize("PUT_images"), async (req, res, next) => { putImages(Number(req.params.id), ((Array.isArray(req.files?.image) ? req.files?.image : [req.files?.image]).filter(Boolean)) as UploadedFile[]).then(() => { res.status(201).send("Images added successfully!!") }).catch(err => { @@ -157,8 +156,8 @@ router.put("/images/:id", authorize("PUT_images"), async (req, res, next) => { }); }); -router.put("/register/:id", authorize("REGISTER_voluntaryWork"), async (req, res, next) => { - if (res.locals.volunteer) { +router.put("/register/:id", validateVoluntaryWorkId, authorize("REGISTER_voluntaryWork"), async (req, res, next) => { + if (res.locals.volunteer) { registerByVolunteer(Number(req.params.id), res.locals.volunteer.volunteerProfile).then(() => { res.status(201).send("Registration done successfully!!") }).catch(err => { @@ -167,8 +166,8 @@ router.put("/register/:id", authorize("REGISTER_voluntaryWork"), async (req, res next(err); }); } else if (res.locals.organizationAdmin) { - - + + if (!req.body.volunteerId.toString()) { res.status(400).send("volunteer id is required!"); } @@ -183,16 +182,16 @@ router.put("/register/:id", authorize("REGISTER_voluntaryWork"), async (req, res } }); -router.put("/deregister/:id", authorize("DEREGISTER_voluntaryWork"), async (req, res, next) => { - - if( !res.locals.volunteer?.id && !req.body.volunteerId?.toString()){ +router.put("/deregister/:id", validateVoluntaryWorkId, authorize("DEREGISTER_voluntaryWork"), async (req, res, next) => { + + if (!res.locals.volunteer?.id && !req.body.volunteerId?.toString()) { res.status(400).send("Volunteer id is required !"); } deregisterVoluntaryWork(Number(req.params.id), res.locals.volunteer.id || req.body.volunteerId.toString()).then(() => { res.status(201).send("Deregistration done successfully!!") }).catch(err => { // console.error(err); - //res.status(500).send(err); + //res.status(500).send(err); next(err); }); }); From c63d6a7742fb37dd1b8e3f2489cb40d1a81412de Mon Sep 17 00:00:00 2001 From: TarteelTamimi Date: Sun, 8 Oct 2023 22:56:35 +0300 Subject: [PATCH 088/146] add logs and logger --- .gitignore | 3 +- app.ts | 11 +- logger.ts | 12 +++ package-lock.json | 227 +++++++++++++++++++++++++++++++++++++++- package.json | 3 +- src/controllers/logs.ts | 11 ++ src/db/dataSource.ts | 3 +- src/db/entities/Logs.ts | 41 ++++++++ types/logs.ts | 24 +++++ 9 files changed, 326 insertions(+), 9 deletions(-) create mode 100644 logger.ts create mode 100644 src/controllers/logs.ts create mode 100644 src/db/entities/Logs.ts create mode 100644 types/logs.ts diff --git a/.gitignore b/.gitignore index fb86b3ce..65b65a2a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ node_modules dist .env -.env.test \ No newline at end of file +.env.test +logs \ No newline at end of file diff --git a/app.ts b/app.ts index 740261b3..3bc5a0f5 100644 --- a/app.ts +++ b/app.ts @@ -16,6 +16,7 @@ import organizationAdminRouter from "./src/routes/organizationAdmin.js" import organizationProfileRouter from "./src/routes/organizationProfile.js" import volunteerRouter from "./src/routes/volunteer.js" import { authenticate } from "./src/middleware/auth/authenticate.js" +import baseLogger from "./logger.js" const app = express(); dotenv.config(); @@ -28,9 +29,9 @@ app.use(fileUpload({ limits: { fileSize: 50 * 1024 * 1024 } })) // catch 404 and forward to error handler -app.use(function (req, res, next) { - next(createError(404)); -}); +// app.use(function (req, res, next) { +// next(createError(404)); +// }); const errorHandler = ( error: any, @@ -62,8 +63,8 @@ app.use('/', indexRouter); app.use('/permission', authenticate, permissionRouter); app.use('/role', authenticate, roleRouter); app.use('/voluntaryWork', authenticate, voluntaryWorkRouter); -app.use('/organizationAdmin', authenticate, organizationAdminRouter); -app.use('/organizationProfile', authenticate, organizationProfileRouter); +app.use('/organizationAdmin', /*authenticate,*/ organizationAdminRouter); +app.use('/organizationProfile', /*authenticate,*/ organizationProfileRouter); app.use("/volunteer", volunteerRouter); app.use(errorHandler); diff --git a/logger.ts b/logger.ts new file mode 100644 index 00000000..cf24a7b0 --- /dev/null +++ b/logger.ts @@ -0,0 +1,12 @@ +import winston from "winston"; + +const baseLogger = winston.createLogger({ + format: winston.format.json(), + defaultMeta: { project: 'serve and shine', time: new Date() }, + transports: [ + new winston.transports.File({ filename: 'logs/error.log', level: 'error' }), + new winston.transports.File({ filename: 'logs/all.log' }), + ], +}); + +export default baseLogger; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 45833f2c..f4e40ab8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,7 +24,8 @@ "morgan": "^1.10.0", "mysql": "^2.18.1", "typeorm": "^0.3.17", - "typescript": "^5.2.2" + "typescript": "^5.2.2", + "winston": "^3.11.0" }, "devDependencies": { "@babel/preset-env": "^7.22.20", @@ -1948,6 +1949,24 @@ "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==" }, + "node_modules/@colors/colors": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz", + "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==", + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@dabh/diagnostics": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz", + "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==", + "dependencies": { + "colorspace": "1.1.x", + "enabled": "2.0.x", + "kuler": "^2.0.0" + } + }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -2548,6 +2567,11 @@ "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==" }, + "node_modules/@types/triple-beam": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.3.tgz", + "integrity": "sha512-6tOUG+nVHn0cJbVp25JFayS5UE6+xlbcNF9Lo9mU7U0zk3zeUShZied4YEQZjy1JBF043FSkdXw8YkUJuVtB5g==" + }, "node_modules/@types/yargs": { "version": "17.0.26", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.26.tgz", @@ -2759,6 +2783,11 @@ "resolved": "https://registry.npmjs.org/asap/-/asap-1.0.0.tgz", "integrity": "sha512-Ej9qjcXY+8Tuy1cNqiwNMwFRXOy9UwgTeMA8LxreodygIPV48lx8PU1ecFxb5ZeU1DpMKxiq6vGLTxcitWZPbA==" }, + "node_modules/async": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", + "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" + }, "node_modules/available-typed-arrays": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", @@ -3454,6 +3483,15 @@ "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==" }, + "node_modules/color": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", + "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", + "dependencies": { + "color-convert": "^1.9.3", + "color-string": "^1.6.0" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -3470,6 +3508,15 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, "node_modules/color-support": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", @@ -3478,6 +3525,28 @@ "color-support": "bin.js" } }, + "node_modules/color/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/colorspace": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz", + "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==", + "dependencies": { + "color": "^3.1.3", + "text-hex": "1.0.x" + } + }, "node_modules/commander": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/commander/-/commander-2.6.0.tgz", @@ -3802,6 +3871,11 @@ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, + "node_modules/enabled": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", + "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" + }, "node_modules/encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", @@ -4014,6 +4088,11 @@ "bser": "2.1.1" } }, + "node_modules/fecha": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz", + "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==" + }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -4054,6 +4133,11 @@ "node": ">=8" } }, + "node_modules/fn.name": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", + "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" + }, "node_modules/for-each": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", @@ -5416,6 +5500,11 @@ "node": ">=6" } }, + "node_modules/kuler": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", + "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==" + }, "node_modules/lazy-cache": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", @@ -5495,6 +5584,32 @@ "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" }, + "node_modules/logform": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/logform/-/logform-2.5.1.tgz", + "integrity": "sha512-9FyqAm9o9NKKfiAKfZoYo9bGXXuwMkxQiQttkT4YjjVtQVIQtK6LmVtlxmCaFswo6N4AfEkHqZTV0taDtPotNg==", + "dependencies": { + "@colors/colors": "1.5.0", + "@types/triple-beam": "^1.3.2", + "fecha": "^4.2.0", + "ms": "^2.1.1", + "safe-stable-stringify": "^2.3.1", + "triple-beam": "^1.3.0" + } + }, + "node_modules/logform/node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/logform/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, "node_modules/longest": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", @@ -5939,6 +6054,14 @@ "wrappy": "1" } }, + "node_modules/one-time": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz", + "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", + "dependencies": { + "fn.name": "1.x.x" + } + }, "node_modules/onetime": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", @@ -6495,6 +6618,14 @@ } ] }, + "node_modules/safe-stable-stringify": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz", + "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==", + "engines": { + "node": ">=10" + } + }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -6649,6 +6780,19 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/simple-swizzle/node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + }, "node_modules/simple-update-notifier": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", @@ -6721,6 +6865,14 @@ "node": ">= 0.6" } }, + "node_modules/stack-trace": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", + "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==", + "engines": { + "node": "*" + } + }, "node_modules/stack-utils": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", @@ -6889,6 +7041,11 @@ "node": ">=8" } }, + "node_modules/text-hex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", + "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" + }, "node_modules/thenify": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", @@ -7031,6 +7188,14 @@ "tree-kill": "cli.js" } }, + "node_modules/triple-beam": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz", + "integrity": "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==", + "engines": { + "node": ">= 14.0.0" + } + }, "node_modules/tslib": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", @@ -7545,6 +7710,66 @@ "node": ">= 0.8.0" } }, + "node_modules/winston": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.11.0.tgz", + "integrity": "sha512-L3yR6/MzZAOl0DsysUXHVjOwv8mKZ71TrA/41EIduGpOOV5LQVodqN+QdQ6BS6PJ/RdIshZhq84P/fStEZkk7g==", + "dependencies": { + "@colors/colors": "^1.6.0", + "@dabh/diagnostics": "^2.0.2", + "async": "^3.2.3", + "is-stream": "^2.0.0", + "logform": "^2.4.0", + "one-time": "^1.0.0", + "readable-stream": "^3.4.0", + "safe-stable-stringify": "^2.3.1", + "stack-trace": "0.0.x", + "triple-beam": "^1.3.0", + "winston-transport": "^4.5.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/winston-transport": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.5.0.tgz", + "integrity": "sha512-YpZzcUzBedhlTAfJg6vJDlyEai/IFMIVcaEZZyl3UXIl4gmqRpU7AE89AHLkbzLUsv0NVmw7ts+iztqKxxPW1Q==", + "dependencies": { + "logform": "^2.3.2", + "readable-stream": "^3.6.0", + "triple-beam": "^1.3.0" + }, + "engines": { + "node": ">= 6.4.0" + } + }, + "node_modules/winston-transport/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/winston/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/with": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/with/-/with-4.0.3.tgz", diff --git a/package.json b/package.json index 1dea7d67..d9b3e313 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,8 @@ "morgan": "^1.10.0", "mysql": "^2.18.1", "typeorm": "^0.3.17", - "typescript": "^5.2.2" + "typescript": "^5.2.2", + "winston": "^3.11.0" }, "devDependencies": { "@babel/preset-env": "^7.22.20", diff --git a/src/controllers/logs.ts b/src/controllers/logs.ts new file mode 100644 index 00000000..df0e3d24 --- /dev/null +++ b/src/controllers/logs.ts @@ -0,0 +1,11 @@ +import { NSLogs } from "../../types/logs.js"; +import { Logs } from "../db/entities/Logs.js"; + +const log = async (payload: any) => { + + const newLog = Logs.create(payload); + return newLog.save(); + +} + +export { log } \ No newline at end of file diff --git a/src/db/dataSource.ts b/src/db/dataSource.ts index f49020e8..215aec0d 100644 --- a/src/db/dataSource.ts +++ b/src/db/dataSource.ts @@ -7,6 +7,7 @@ import { SkillTag } from "./entities/SkillTag.js"; import { VoluntaryWork } from "./entities/VoluntaryWork.js"; import { Volunteer } from "./entities/Volunteer.js"; import { VolunteerProfile } from "./entities/VolunteerProfile.js"; +import { Logs } from "./entities/Logs.js"; const dataSource = new DataSource({ type: 'mysql', @@ -16,7 +17,7 @@ const dataSource = new DataSource({ password: process.env.DB_PASSWORD, database: process.env.DB_NAME, entities: [OrganizationAdmin, OrganizationProfile, Permission, - Role, SkillTag, VoluntaryWork, Volunteer, VolunteerProfile], + Role, SkillTag, VoluntaryWork, Volunteer, VolunteerProfile, Logs], migrations: ['./**/migration/*.ts'], synchronize: true, logging: false diff --git a/src/db/entities/Logs.ts b/src/db/entities/Logs.ts new file mode 100644 index 00000000..d70220a1 --- /dev/null +++ b/src/db/entities/Logs.ts @@ -0,0 +1,41 @@ +import { BaseEntity, Column, CreateDateColumn, Entity, PrimaryGeneratedColumn } from "typeorm"; + +@Entity() +export class Logs extends BaseEntity { + @PrimaryGeneratedColumn('increment') + id: number; + + @Column({ + nullable:false, + unique:true + }) + userId: string; + + @Column({ + nullable:false + }) + userName: string; + + @Column({ + nullable:false + }) + userType: string; + + @Column({ + type: 'enum', + enum: ['success', 'failed'], + nullable: false + }) + type: 'success' | 'failed'; + + @Column({ + nullable:false + }) + request: string + + @CreateDateColumn({ + type: 'timestamp', + default: () => "CURRENT_TIMESTAMP(6)" + }) + createdAt: Date; +} \ No newline at end of file diff --git a/types/logs.ts b/types/logs.ts new file mode 100644 index 00000000..5d16c565 --- /dev/null +++ b/types/logs.ts @@ -0,0 +1,24 @@ +export namespace NSLogs { + + export enum userType { + root = 'root', + admin = 'admin', + volunteer = 'volunteer', + premium = 'premium' + } + + export enum Type { + success = 'success', + failed = 'failed' + } + + export interface Item { + id?: number; + userId: string; + userName: string; + userType: userType; + type:Type; + request: string; + createdAt?: Date; + } +} From 5601e934437b7fa023cbc3192b7de97bea7890c2 Mon Sep 17 00:00:00 2001 From: TarteelTamimi Date: Mon, 9 Oct 2023 00:46:13 +0300 Subject: [PATCH 089/146] complete logs & logger --- app.ts | 32 ++-- logger.ts | 2 +- src/db/entities/Logs.ts | 1 - src/routes/organizationAdmin.ts | 100 +++++++++-- src/routes/organizationProfile.ts | 99 +++++++++-- src/routes/permission.ts | 97 ++++++++++- src/routes/role.ts | 89 +++++++++- src/routes/voluntaryWork.ts | 264 +++++++++++++++++++++++++++--- src/routes/volunteer.ts | 107 +++++++++++- 9 files changed, 708 insertions(+), 83 deletions(-) diff --git a/app.ts b/app.ts index 672dca18..d9f401f9 100644 --- a/app.ts +++ b/app.ts @@ -2,7 +2,7 @@ import "./config.js" import express from 'express' import dotenv from 'dotenv' import createError from 'http-errors' -import dataSource, { initDB } from './src/db/dataSource.js' +import { initDB } from './src/db/dataSource.js' import logger from 'morgan' import cookieParser from 'cookie-parser' import fileUpload from 'express-fileupload'; @@ -33,21 +33,21 @@ app.use(fileUpload({ limits: { fileSize: 50 * 1024 * 1024 } })) // next(createError(404)); // }); -const errorHandler = ( - error: any, - req: express.Request, - res: express.Response, - next: express.NextFunction) => { - if (error.status == 404) { - res.status(404).send("Something is not found"); - } else if (error.status == 401) { - res.status(401).send("You are unautharized"); - } else if (error.status == 403) { - res.status(401).send("You don't have the permission"); - } else { - res.status(500).send('Something went wrong'); - } -} +// const errorHandler = ( +// error: any, +// req: express.Request, +// res: express.Response, +// next: express.NextFunction) => { +// if (error.status == 404) { +// res.status(404).send("Something is not found"); +// } else if (error.status == 401) { +// res.status(401).send("You are unautharized"); +// } else if (error.status == 403) { +// res.status(401).send("You don't have the permission"); +// } else { +// res.status(500).send('Something went wrong'); +// } +// } // error handler // app.use(function (err: any, req: any, res: any, next: any) { diff --git a/logger.ts b/logger.ts index cf24a7b0..cada788c 100644 --- a/logger.ts +++ b/logger.ts @@ -5,7 +5,7 @@ const baseLogger = winston.createLogger({ defaultMeta: { project: 'serve and shine', time: new Date() }, transports: [ new winston.transports.File({ filename: 'logs/error.log', level: 'error' }), - new winston.transports.File({ filename: 'logs/all.log' }), + //new winston.transports.File({ filename: 'logs/all.log' }), ], }); diff --git a/src/db/entities/Logs.ts b/src/db/entities/Logs.ts index d70220a1..f4130c1d 100644 --- a/src/db/entities/Logs.ts +++ b/src/db/entities/Logs.ts @@ -7,7 +7,6 @@ export class Logs extends BaseEntity { @Column({ nullable:false, - unique:true }) userId: string; diff --git a/src/routes/organizationAdmin.ts b/src/routes/organizationAdmin.ts index d313ecb7..02e8b0f3 100644 --- a/src/routes/organizationAdmin.ts +++ b/src/routes/organizationAdmin.ts @@ -2,15 +2,37 @@ import express from "express"; import { createOrganizationAdmin, deleteOrganizationAdmin, editOrganizationAdmin, getOrganizationAdmins } from "../controllers/organizationAdmin.js"; import { authorize, checkMe } from "../middleware/auth/authorize.js"; import { validateAdminEdited, validateAdminId, validateOrganizationAdmin } from "../middleware/validation/organizationAdmin.js"; +import { log } from "../controllers/logs.js"; const router = express.Router(); router.post('/', authorize("POST_organizationAdmin"), validateOrganizationAdmin, (req, res, next) => { createOrganizationAdmin(req.body).then(() => { + log({ + userId: res.locals.organizationAdmin.id, + userName: res.locals.organizationAdmin.name, + userType: 'admin', + type: 'success', + request: 'Create Organization Admin' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) + res.status(201).send("Organization Admin created successfully!!") }).catch(err => { - // console.error(err); - // res.status(500).send(err); + log({ + userId: res.locals.organizationAdmin.id, + userName: res.locals.organizationAdmin.name, + userType: 'admin', + type: 'failed', + request: 'Create Organization Admin' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(err); }); }); @@ -20,21 +42,61 @@ router.delete('/:id', validateAdminId, authorize("DELETE_organizationAdmin"), as deleteOrganizationAdmin(id) .then(data => { + log({ + userId: res.locals.organizationAdmin.id, + userName: res.locals.organizationAdmin.name, + userType: 'admin', + type: 'success', + request: 'Delete Organization Admin' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.send(data); }) .catch(err => { - // console.error(error); - // res.status(500).send('Something went wrong'); + log({ + userId: res.locals.organizationAdmin.id, + userName: res.locals.organizationAdmin.name, + userType: 'admin', + type: 'failed', + request: 'Delete Organization Admin' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(err); }); }); router.put("/:id", authorize("PUT_organizationAdmin"), validateAdminEdited, async (req, res, next) => { editOrganizationAdmin({ ...req.body, id: req.params.id }).then(() => { + log({ + userId: res.locals.organizationAdmin.id, + userName: res.locals.organizationAdmin.name, + userType: 'admin', + type: 'success', + request: 'Edit Organization Admin' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.status(201).send("Organization Admin edited successfully!!") }).catch(err => { - // console.error(err); - // res.status(500).send(err); + log({ + userId: res.locals.organizationAdmin.id, + userName: res.locals.organizationAdmin.name, + userType: 'admin', + type: 'failed', + request: 'Edit Organization Admin' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(err); }); }); @@ -51,15 +113,33 @@ router.get('/', authorize("GET_organizationAdmins"), async (req, res, next) => { getOrganizationAdmins(payload) .then(data => { + log({ + userId: res.locals.organizationAdmin.id, + userName: res.locals.organizationAdmin.name, + userType: 'admin', + type: 'success', + request: 'Get all Organization Admins' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.send(data); }) .catch(err => { - // console.error(error); - // res.status(500).send(error); + log({ + userId: res.locals.organizationAdmin.id, + userName: res.locals.organizationAdmin.name, + userType: 'admin', + type: 'failed', + request: 'Get all Organization Admins' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(err); }); }); - - export default router; \ No newline at end of file diff --git a/src/routes/organizationProfile.ts b/src/routes/organizationProfile.ts index d3d3a3ce..8315cd7f 100644 --- a/src/routes/organizationProfile.ts +++ b/src/routes/organizationProfile.ts @@ -2,15 +2,36 @@ import express from "express"; import { createOrganizationProfile, deleteOrganizationProfile, editOrganizationProfile, getOrganizationProfile } from "../controllers/OrganizationProfile .js"; import { authorize, checkAdmin } from "../middleware/auth/authorize.js"; import { validateOrgId, validateOrganizationProfile } from "../middleware/validation/organizationProfile.js"; +import { log } from "../controllers/logs.js"; const router = express.Router(); router.post('/', authorize("POST_organizationProfile"), validateOrganizationProfile, (req, res, next) => { createOrganizationProfile(req.body).then(() => { + log({ + userId: res.locals.organizationAdmin.id, + userName: res.locals.organizationAdmin.name, + userType: 'admin', + type: 'success', + request: 'Create Organization Profile' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.status(201).send("Organization Profile created successfully!!") }).catch(err => { - // console.error(err); - // res.status(500).send(err); + log({ + userId: res.locals.organizationAdmin.id, + userName: res.locals.organizationAdmin.name, + userType: 'admin', + type: 'failed', + request: 'Create Organization Profile' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(err); }); }); @@ -20,21 +41,61 @@ router.delete('/:id', validateOrgId, authorize("DELETE_organizationProfile"), as deleteOrganizationProfile(id) .then(data => { + log({ + userId: res.locals.organizationAdmin.id, + userName: res.locals.organizationAdmin.name, + userType: 'admin', + type: 'success', + request: 'Delete Organization Profile' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.send(data); }) .catch(err => { - // console.error(error); - // res.status(500).send('Something went wrong'); + log({ + userId: res.locals.organizationAdmin.id, + userName: res.locals.organizationAdmin.name, + userType: 'admin', + type: 'failed', + request: 'Delete Organization Profile' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(err); }); }); router.put("/:id", validateOrgId, authorize("PUT_organizationProfile"), async (req, res, next) => { editOrganizationProfile(req.body).then(() => { + log({ + userId: res.locals.organizationAdmin.id, + userName: res.locals.organizationAdmin.name, + userType: 'admin', + type: 'success', + request: 'Edit Organization Profile' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.status(201).send("Organization Profile edited successfully!!") }).catch(err => { - // console.error(err); - // res.status(500).send(err); + log({ + userId: res.locals.organizationAdmin.id, + userName: res.locals.organizationAdmin.name, + userType: 'admin', + type: 'failed', + request: 'Edit Organization Profile' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(err); }); }); @@ -50,15 +111,33 @@ router.get('/', authorize("GET_organizationProfiles"), async (req, res, next) => getOrganizationProfile(payload) .then(data => { + log({ + userId: res.locals.organizationAdmin.id, + userName: res.locals.organizationAdmin.name, + userType: 'admin', + type: 'success', + request: 'Get Organization Profiles' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.send(data); }) .catch(err => { - // console.error(error); - // res.status(500).send(error); + log({ + userId: res.locals.organizationAdmin.id, + userName: res.locals.organizationAdmin.name, + userType: 'admin', + type: 'failed', + request: 'Get Organization Profiles' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(err); }); }); - - export default router; \ No newline at end of file diff --git a/src/routes/permission.ts b/src/routes/permission.ts index 7f39711a..f8b6a9e6 100644 --- a/src/routes/permission.ts +++ b/src/routes/permission.ts @@ -2,15 +2,36 @@ import express from 'express'; import { createPermission, deletePermission, editPermission, getPermissions } from '../controllers/permission.js'; import { authorize } from '../middleware/auth/authorize.js'; import { validatePermission, validatePermissionId } from '../middleware/validation/permission.js'; +import { log } from '../controllers/logs.js'; var router = express.Router(); router.post('/', authorize("POST_permissions"), validatePermission, (req, res, next) => { createPermission(req.body).then(() => { + log({ + userId: res.locals.organizationAdmin.id, + userName: res.locals.organizationAdmin.name, + userType: 'admin', + type: 'success', + request: 'Create Permission' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.status(201).send("Permission created successfully!!") }).catch(err => { - // console.error(err); - // res.status(500).send(err); + log({ + userId: res.locals.organizationAdmin.id, + userName: res.locals.organizationAdmin.name, + userType: 'admin', + type: 'failed', + request: 'Create Permission' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(err); }); }); @@ -20,21 +41,61 @@ router.delete('/:id', validatePermissionId, authorize("DELETE_permission"), asyn deletePermission(id) .then(data => { + log({ + userId: res.locals.organizationAdmin.id, + userName: res.locals.organizationAdmin.name, + userType: 'admin', + type: 'success', + request: 'Delete Permission' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.send(data); }) .catch(err => { - // console.error(error); - // res.status(500).send('Something went wrong'); + log({ + userId: res.locals.organizationAdmin.id, + userName: res.locals.organizationAdmin.name, + userType: 'admin', + type: 'failed', + request: 'Delete Permission' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(err); }); }) router.put("/:id", authorize("PUT_permission"), validatePermissionId, async (req, res, next) => { editPermission({ ...req.body, id: req.params.id?.toString() }).then(() => { + log({ + userId: res.locals.organizationAdmin.id, + userName: res.locals.organizationAdmin.name, + userType: 'admin', + type: 'success', + request: 'Edit Permission' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.status(201).send("Permission edited successfully!!") }).catch(err => { - // console.error(err); - // res.status(500).send(err); + log({ + userId: res.locals.organizationAdmin.id, + userName: res.locals.organizationAdmin.name, + userType: 'admin', + type: 'failed', + request: 'Edit Permission' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(err); }); }); @@ -49,11 +110,31 @@ router.get('/', authorize("GET_permissions"), async (req, res, next) => { getPermissions(payload) .then(data => { + log({ + userId: res.locals.organizationAdmin.id, + userName: res.locals.organizationAdmin.name, + userType: 'admin', + type: 'success', + request: 'Get Permissions' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.send(data); }) .catch(err => { - // console.error(error); - // res.status(500).send('Something went wrong'); + log({ + userId: res.locals.organizationAdmin.id, + userName: res.locals.organizationAdmin.name, + userType: 'admin', + type: 'failed', + request: 'Get Permissions' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(err); }); }); diff --git a/src/routes/role.ts b/src/routes/role.ts index 510b5a18..5c62555a 100644 --- a/src/routes/role.ts +++ b/src/routes/role.ts @@ -3,15 +3,34 @@ import { createRole, deleteRole, editRole, getRoles } from '../controllers/role. import { NSRole } from '../../types/role.js'; import { authorize } from '../middleware/auth/authorize.js'; import { validateEditedRole, validateRole, validateRoleId } from '../middleware/validation/role.js'; +import { log } from '../controllers/logs.js'; var router = express.Router(); router.post('/', authorize("POST_role"), validateRole, (req, res, next) => { createRole(req.body).then(() => { + log ({ + userId: res.locals.organizationAdmin.id, + userName: res.locals.organizationAdmin.name, + userType: 'admin', + type: 'success', + request: 'Create Role'}).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.status(201).send("Role created successfully!!") }).catch(err => { - // console.error(err); - // res.status(500).send(err); + log ({ + userId: res.locals.organizationAdmin.id, + userName: res.locals.organizationAdmin.name, + userType: 'admin', + type: 'failed', + request: 'Create Role'}).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(err); }); }); @@ -21,21 +40,57 @@ router.delete('/:id', validateRoleId, authorize("DELETE_role"), async (req, res, deleteRole(id) .then(data => { + log ({ + userId: res.locals.organizationAdmin.id, + userName: res.locals.organizationAdmin.name, + userType: 'admin', + type: 'success', + request: 'Delete Role'}).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.send(data); }) .catch(err => { - // console.error(error); - // res.status(500).send('Something went wrong'); + log ({ + userId: res.locals.organizationAdmin.id, + userName: res.locals.organizationAdmin.name, + userType: 'admin', + type: 'failed', + request: 'Delete Role'}).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(err); }); }) router.put("/:id", authorize("PUT_role"), validateEditedRole, async (req, res, next) => { editRole({ ...req.body, id: req.params.id?.toString() }).then(() => { + log ({ + userId: res.locals.organizationAdmin.id, + userName: res.locals.organizationAdmin.name, + userType: 'admin', + type: 'success', + request: 'Edit Role'}).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.status(201).send("Role edited successfully!!") }).catch(err => { - // console.error(err); - // res.status(500).send(err); + log ({ + userId: res.locals.organizationAdmin.id, + userName: res.locals.organizationAdmin.name, + userType: 'admin', + type: 'failed', + request: 'Edit Role'}).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(err); }); }); @@ -50,11 +105,29 @@ router.get('/', authorize("GET_roles"), async (req, res, next) => { getRoles(payload) .then(data => { + log ({ + userId: res.locals.organizationAdmin.id, + userName: res.locals.organizationAdmin.name, + userType: 'admin', + type: 'success', + request: 'Get Roles'}).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.send(data); }) .catch(err => { - // console.error(error); - // res.status(500).send('Something went wrong'); + log ({ + userId: res.locals.organizationAdmin.id, + userName: res.locals.organizationAdmin.name, + userType: 'admin', + type: 'failed', + request: 'Get Roles'}).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(err); }); }); diff --git a/src/routes/voluntaryWork.ts b/src/routes/voluntaryWork.ts index ffbc5fbf..4f8f2738 100644 --- a/src/routes/voluntaryWork.ts +++ b/src/routes/voluntaryWork.ts @@ -5,15 +5,34 @@ import { NSVoluntaryWork } from '../../types/voluntaryWork.js'; import { authorize, checkParticipation } from '../middleware/auth/authorize.js'; import { validateEditedVoluntaryWork, validateVoluntaryWork, validateVoluntaryWorkId } from '../middleware/validation/voluntaryWork.js'; import { UploadedFile } from 'express-fileupload'; +import { log } from '../controllers/logs.js'; var router = express.Router(); router.post('/', authorize("POST_voluntaryWork"), validateVoluntaryWork, (req, res, next) => { createVoluntaryWork({ ...req.body, creatorId: res.locals.volunteer?.id || res.locals.organizationAdmin?.id }).then(() => { res.status(201).send("Voluntary work created successfully!!") + log ({ + userId: res.locals.organizationAdmin.id, + userName: res.locals.organizationAdmin.name, + userType: 'admin', + type: 'success', + request: 'Create VoluntaryWork'}).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) }).catch(err => { - // console.error(err); - // res.status(500).send(err); + log ({ + userId: res.locals.organizationAdmin.id, + userName: res.locals.organizationAdmin.name, + userType: 'admin', + type: 'failed', + request: 'Create VoluntaryWork'}).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(err); }); }); @@ -23,20 +42,57 @@ router.delete('/:id', validateVoluntaryWorkId, authorize("DELETE_voluntaryWork") deleteVoluntaryWork(id) .then(data => { + log ({ + userId: res.locals.organizationAdmin.id, + userName: res.locals.organizationAdmin.name, + userType: 'admin', + type: 'success', + request: 'Delete VoluntaryWork'}).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.send(data); }) .catch(err => { - // res.status(500).send('Something went wrong'); + log ({ + userId: res.locals.organizationAdmin.id, + userName: res.locals.organizationAdmin.name, + userType: 'admin', + type: 'failed', + request: 'Delete VoluntaryWork'}).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(err); }); }) router.put("/:id", authorize("PUT_voluntaryWork"), validateEditedVoluntaryWork, async (req, res, next) => { editVoluntaryWork({ ...req.body, id: req.params.id?.toString() }).then(() => { + log ({ + userId: res.locals.organizationAdmin.id, + userName: res.locals.organizationAdmin.name, + userType: 'admin', + type: 'success', + request: 'Edit VoluntaryWork'}).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.status(201).send("Voluntary Work edited successfully!!") }).catch(err => { - // console.error(err); - // res.status(500).send(err); + log ({ + userId: res.locals.organizationAdmin.id, + userName: res.locals.organizationAdmin.name, + userType: 'admin', + type: 'failed', + request: 'Edit VoluntaryWork'}).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(err); }); }); @@ -68,11 +124,29 @@ router.get('/', authorize("GET_voluntaryWorks"), async (req, res, next) => { getVoluntaryWorks(payload) .then(data => { + log ({ + userId: res.locals.organizationAdmin.id, + userName: res.locals.organizationAdmin.name, + userType: 'admin', + type: 'success', + request: 'Get VoluntaryWork/s'}).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.send(data); }) .catch(err => { - // console.error(error); - // res.status(500).send('Something went wrong'); + log ({ + userId: res.locals.organizationAdmin.id, + userName: res.locals.organizationAdmin.name, + userType: 'admin', + type: 'failed', + request: 'Get VoluntaryWork/s'}).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(err); }); }); @@ -104,11 +178,29 @@ router.get('/analysis', authorize("GET_analysis"), async (req, res, next) => { getVoluntaryWorks(payload) .then(data => { + log ({ + userId: res.locals.organizationAdmin.id, + userName: res.locals.organizationAdmin.name, + userType: 'admin', + type: 'success', + request: 'Analysis VoluntaryWorks'}).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.send(data); }) .catch(err => { - // console.error(error); - // res.status(500).send('Something went wrong'); + log ({ + userId: res.locals.organizationAdmin.id, + userName: res.locals.organizationAdmin.name, + userType: 'admin', + type: 'failed', + request: 'Analysis VoluntaryWorks'}).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(err); }); }); @@ -117,41 +209,113 @@ router.get('/recommendation', authorize("GET_recommendation"), async (req, res, const payload = { ...res.locals.volunteer }; getVoluntaryWorks(payload) .then(data => { + log ({ + userId: res.locals.organizationAdmin.id, + userName: res.locals.organizationAdmin.name, + userType: 'admin', + type: 'success', + request: 'Recommendation'}).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.send(data); }) .catch(err => { - // console.error(error); - // res.status(500).send('Something went wrong'); + log ({ + userId: res.locals.organizationAdmin.id, + userName: res.locals.organizationAdmin.name, + userType: 'admin', + type: 'failed', + request: 'Recommendation'}).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(err); }); }); router.put("/rating/:id", validateVoluntaryWorkId, authorize("PUT_rating"), checkParticipation, async (req, res, next) => { putRating(Number(req.params.id), Number(req.body.rating)).then(() => { + log ({ + userId: res.locals.organizationAdmin.id, + userName: res.locals.organizationAdmin.name, + userType: 'admin', + type: 'success', + request: 'Rating'}).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.status(201).send("Rating added successfully!!") }).catch(err => { - // console.error(err); - // res.status(500).send(err); + log ({ + userId: res.locals.organizationAdmin.id, + userName: res.locals.organizationAdmin.name, + userType: 'admin', + type: 'failed', + request: 'Rating'}).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(err); }); }); router.put("/feedback/:id", validateVoluntaryWorkId, authorize("PUT_feedback"), checkParticipation, async (req, res, next) => { putFeedback(Number(req.params.id), req.body.feedback).then(() => { + log ({ + userId: res.locals.organizationAdmin.id, + userName: res.locals.organizationAdmin.name, + userType: 'admin', + type: 'success', + request: 'Feedback'}).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.status(201).send("Feedback added successfully!!") }).catch(err => { - // console.error(err); - // res.status(500).send(err); + log ({ + userId: res.locals.organizationAdmin.id, + userName: res.locals.organizationAdmin.name, + userType: 'admin', + type: 'failed', + request: 'Feedback'}).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(err); }); }); router.put("/images/:id", validateVoluntaryWorkId, authorize("PUT_images"), async (req, res, next) => { putImages(Number(req.params.id), ((Array.isArray(req.files?.image) ? req.files?.image : [req.files?.image]).filter(Boolean)) as UploadedFile[]).then(() => { + log ({ + userId: res.locals.organizationAdmin.id, + userName: res.locals.organizationAdmin.name, + userType: 'admin', + type: 'success', + request: 'Add images'}).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.status(201).send("Images added successfully!!") }).catch(err => { - // console.error(err); - // res.status(500).send(err); + log ({ + userId: res.locals.organizationAdmin.id, + userName: res.locals.organizationAdmin.name, + userType: 'admin', + type: 'failed', + request: 'Add images'}).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(err); }); }); @@ -159,10 +323,28 @@ router.put("/images/:id", validateVoluntaryWorkId, authorize("PUT_images"), asyn router.put("/register/:id", validateVoluntaryWorkId, authorize("REGISTER_voluntaryWork"), async (req, res, next) => { if (res.locals.volunteer) { registerByVolunteer(Number(req.params.id), res.locals.volunteer.volunteerProfile).then(() => { + log ({ + userId: res.locals.organizationAdmin.id, + userName: res.locals.organizationAdmin.name, + userType: 'admin', + type: 'success', + request: 'Register VoluntaryWorks'}).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.status(201).send("Registration done successfully!!") }).catch(err => { - // console.error(err); - // res.status(500).send(err); + log ({ + userId: res.locals.organizationAdmin.id, + userName: res.locals.organizationAdmin.name, + userType: 'admin', + type: 'failed', + request: 'Register VoluntaryWorks'}).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(err); }); } else if (res.locals.organizationAdmin) { @@ -173,10 +355,28 @@ router.put("/register/:id", validateVoluntaryWorkId, authorize("REGISTER_volunta } registerByOrganizationAdmin(Number(req.params.id), req.body.volunteerId.toString()).then(() => { + log ({ + userId: res.locals.organizationAdmin.id, + userName: res.locals.organizationAdmin.name, + userType: 'admin', + type: 'success', + request: 'Register By Organization Admin'}).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.status(201).send("Registration done successfully!!") }).catch(err => { - // console.error(err); - // res.status(500).send(err); + log ({ + userId: res.locals.organizationAdmin.id, + userName: res.locals.organizationAdmin.name, + userType: 'admin', + type: 'failed', + request: 'Register By Organization Admin'}).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(err); }); } @@ -188,10 +388,28 @@ router.put("/deregister/:id", validateVoluntaryWorkId, authorize("DEREGISTER_vol res.status(400).send("Volunteer id is required !"); } deregisterVoluntaryWork(Number(req.params.id), res.locals.volunteer.id || req.body.volunteerId.toString()).then(() => { + log ({ + userId: res.locals.organizationAdmin.id, + userName: res.locals.organizationAdmin.name, + userType: 'admin', + type: 'success', + request: 'Deregister'}).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.status(201).send("Deregistration done successfully!!") }).catch(err => { - // console.error(err); - //res.status(500).send(err); + log ({ + userId: res.locals.organizationAdmin.id, + userName: res.locals.organizationAdmin.name, + userType: 'admin', + type: 'failed', + request: 'Deregister'}).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(err); }); }); diff --git a/src/routes/volunteer.ts b/src/routes/volunteer.ts index 639f90a6..498186ce 100644 --- a/src/routes/volunteer.ts +++ b/src/routes/volunteer.ts @@ -4,15 +4,34 @@ import { authenticate } from '../middleware/auth/authenticate.js'; import { validateEditedVolunteer, validateVolunteer } from '../middleware/validation/volunteer.js'; import { createVolunteer, deleteVolunteer, editVolunteer, getVolunteers, login } from '../controllers/volunteer.js'; import { NSVolunteer } from '../../types/volunteer.js'; +import { log } from '../controllers/logs.js'; var router = express.Router(); router.post('/register', validateVolunteer, (req, res, next) => { createVolunteer({...req.body,type:"volunteer" }).then(() => { + log ({ + userId: res.locals.organizationAdmin.id || res.locals.volunteer.id, + userName: res.locals.organizationAdmin.name || res.locals.volunteer.name, + userType: 'admin', + type: 'success', + request: 'Register volunteer'}).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.status(201).send("Volunteer created successfully!!") }).catch(err => { - // console.error(err); - // res.status(500).send(err); + log ({ + userId: res.locals.organizationAdmin.id || res.locals.volunteer.id, + userName: res.locals.organizationAdmin.name || res.locals.volunteer.name, + userType: 'admin', + type: 'failed', + request: 'Register volunteer'}).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(err); }); }); @@ -28,9 +47,29 @@ router.post('/login', (req, res, next) => { maxAge: 60 *24 * 60 * 1000, sameSite: "lax" // Protect against CSRF attacks }); + log ({ + userId: res.locals.organizationAdmin.id || res.locals.volunteer.id, + userName: res.locals.organizationAdmin.name || res.locals.volunteer.name, + userType: 'admin', + type: 'success', + request: 'Login'}).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.status(201).send("You logged in successfully !"); }) .catch(err => { + log ({ + userId: res.locals.organizationAdmin.id || res.locals.volunteer.id, + userName: res.locals.organizationAdmin.name || res.locals.volunteer.name, + userType: 'admin', + type: 'failed', + request: 'Login'}).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.status(401).send(err); }) }); @@ -40,19 +79,57 @@ router.delete('/:id', authenticate, authorize("DELETE_volunteer"), async (req, r deleteVolunteer(id) .then(data => { + log ({ + userId: res.locals.organizationAdmin.id || res.locals.volunteer.id, + userName: res.locals.organizationAdmin.name || res.locals.volunteer.name, + userType: 'admin', + type: 'success', + request: 'Delete Volunteer'}).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.send(data); }) .catch(error => { + log ({ + userId: res.locals.organizationAdmin.id || res.locals.volunteer.id, + userName: res.locals.organizationAdmin.name || res.locals.volunteer.name, + userType: 'admin', + type: 'failed', + request: 'Delete Volunteer'}).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(error); }); }) router.put("/:id", authenticate, authorize("PUT_volunteer"), validateEditedVolunteer, async (req, res, next) => { editVolunteer({ ...req.body, id: req.params.id?.toString() }).then(() => { + log ({ + userId: res.locals.organizationAdmin.id || res.locals.volunteer.id, + userName: res.locals.organizationAdmin.name || res.locals.volunteer.name, + userType: 'admin', + type: 'success', + request: 'Edit Volunteer'}).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.status(201).send("Volunteer edited successfully!!") }).catch(err => { - // console.error(err); - // res.status(500).send(err); + log ({ + userId: res.locals.organizationAdmin.id || res.locals.volunteer.id, + userName: res.locals.organizationAdmin.name || res.locals.volunteer.name, + userType: 'admin', + type: 'failed', + request: 'Edit Volunteer'}).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(err); }); }); @@ -74,11 +151,29 @@ router.get('/', authenticate, authorize("GET_volunteers"), async (req, res, next getVolunteers(payload) .then(data => { + log ({ + userId: res.locals.organizationAdmin.id || res.locals.volunteer.id, + userName: res.locals.organizationAdmin.name || res.locals.volunteer.name, + userType: 'admin', + type: 'success', + request: 'get Volunteer/s'}).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.send(data); }) .catch(err => { - // console.error(error); - // res.status(500).send('Something went wrong'); + log ({ + userId: res.locals.organizationAdmin.id || res.locals.volunteer.id, + userName: res.locals.organizationAdmin.name || res.locals.volunteer.name, + userType: 'admin', + type: 'failed', + request: 'Get Volunteer/s'}).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(err); }); }); From ffa8a5c0d13e42cbb3b8faa6fd8795e8d0924b58 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Mon, 9 Oct 2023 07:42:59 +0300 Subject: [PATCH 090/146] Use the Log nameSpace, and edit the logger data in orgAdmin to be sure hwo requsted the server --- app.ts | 35 ------------------ src/controllers/logs.ts | 2 +- src/routes/organizationAdmin.ts | 65 +++++++++++++++++---------------- 3 files changed, 34 insertions(+), 68 deletions(-) diff --git a/app.ts b/app.ts index d9f401f9..219697cc 100644 --- a/app.ts +++ b/app.ts @@ -15,7 +15,6 @@ import organizationAdminRouter from "./src/routes/organizationAdmin.js" import organizationProfileRouter from "./src/routes/organizationProfile.js" import volunteerRouter from "./src/routes/volunteer.js" import { authenticate } from "./src/middleware/auth/authenticate.js" -import baseLogger from "./logger.js" import { errorHandler } from "./src/middleware/errorHandler/errorHandler.js" const app = express(); @@ -27,40 +26,6 @@ app.use(express.urlencoded({ extended: false })); app.use(cookieParser()); app.use(fileUpload({ limits: { fileSize: 50 * 1024 * 1024 } })) - -// catch 404 and forward to error handler -// app.use(function (req, res, next) { -// next(createError(404)); -// }); - -// const errorHandler = ( -// error: any, -// req: express.Request, -// res: express.Response, -// next: express.NextFunction) => { -// if (error.status == 404) { -// res.status(404).send("Something is not found"); -// } else if (error.status == 401) { -// res.status(401).send("You are unautharized"); -// } else if (error.status == 403) { -// res.status(401).send("You don't have the permission"); -// } else { -// res.status(500).send('Something went wrong'); -// } -// } - -// error handler -// app.use(function (err: any, req: any, res: any, next: any) { -// // set locals, only providing error in development -// res.locals.message = err.message; -// res.locals.error = req.app.get('env') === 'development' ? err : {}; - -// // render the error page -// res.status(err.status || 500).send({ error: err.message }); -// }); - -app.use(fileUpload({ limits: { fileSize: 50 * 1024 * 1024 } })); - app.use('/', indexRouter); app.use('/permission', authenticate, permissionRouter); app.use('/role', authenticate, roleRouter); diff --git a/src/controllers/logs.ts b/src/controllers/logs.ts index df0e3d24..4fcc9ad8 100644 --- a/src/controllers/logs.ts +++ b/src/controllers/logs.ts @@ -1,7 +1,7 @@ import { NSLogs } from "../../types/logs.js"; import { Logs } from "../db/entities/Logs.js"; -const log = async (payload: any) => { +const log = async (payload: NSLogs.Item) => { const newLog = Logs.create(payload); return newLog.save(); diff --git a/src/routes/organizationAdmin.ts b/src/routes/organizationAdmin.ts index 02e8b0f3..20767ca4 100644 --- a/src/routes/organizationAdmin.ts +++ b/src/routes/organizationAdmin.ts @@ -3,16 +3,17 @@ import { createOrganizationAdmin, deleteOrganizationAdmin, editOrganizationAdmin import { authorize, checkMe } from "../middleware/auth/authorize.js"; import { validateAdminEdited, validateAdminId, validateOrganizationAdmin } from "../middleware/validation/organizationAdmin.js"; import { log } from "../controllers/logs.js"; +import { NSLogs } from "../../types/logs.js"; const router = express.Router(); router.post('/', authorize("POST_organizationAdmin"), validateOrganizationAdmin, (req, res, next) => { createOrganizationAdmin(req.body).then(() => { log({ - userId: res.locals.organizationAdmin.id, - userName: res.locals.organizationAdmin.name, - userType: 'admin', - type: 'success', + userId: res.locals.organizationAdmin?.id, + userName: res.locals.organizationAdmin?.name, + userType: 'root' as NSLogs.userType, + type: 'success' as NSLogs.Type, request: 'Create Organization Admin' }).then(() => { console.log('logged'); @@ -23,10 +24,10 @@ router.post('/', authorize("POST_organizationAdmin"), validateOrganizationAdmin, res.status(201).send("Organization Admin created successfully!!") }).catch(err => { log({ - userId: res.locals.organizationAdmin.id, - userName: res.locals.organizationAdmin.name, - userType: 'admin', - type: 'failed', + userId: res.locals.organizationAdmin?.id, + userName: res.locals.organizationAdmin?.name, + userType: 'root' as NSLogs.userType, + type: 'failed' as NSLogs.Type, request: 'Create Organization Admin' }).then(() => { console.log('logged'); @@ -43,10 +44,10 @@ router.delete('/:id', validateAdminId, authorize("DELETE_organizationAdmin"), as deleteOrganizationAdmin(id) .then(data => { log({ - userId: res.locals.organizationAdmin.id, - userName: res.locals.organizationAdmin.name, - userType: 'admin', - type: 'success', + userId: res.locals.organizationAdmin?.id, + userName: res.locals.organizationAdmin?.name, + userType: (res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'success' as NSLogs.Type, request: 'Delete Organization Admin' }).then(() => { console.log('logged'); @@ -57,10 +58,10 @@ router.delete('/:id', validateAdminId, authorize("DELETE_organizationAdmin"), as }) .catch(err => { log({ - userId: res.locals.organizationAdmin.id, - userName: res.locals.organizationAdmin.name, - userType: 'admin', - type: 'failed', + userId: res.locals.organizationAdmin?.id, + userName: res.locals.organizationAdmin?.name, + userType: (res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'failed' as NSLogs.Type, request: 'Delete Organization Admin' }).then(() => { console.log('logged'); @@ -74,10 +75,10 @@ router.delete('/:id', validateAdminId, authorize("DELETE_organizationAdmin"), as router.put("/:id", authorize("PUT_organizationAdmin"), validateAdminEdited, async (req, res, next) => { editOrganizationAdmin({ ...req.body, id: req.params.id }).then(() => { log({ - userId: res.locals.organizationAdmin.id, - userName: res.locals.organizationAdmin.name, - userType: 'admin', - type: 'success', + userId: res.locals.organizationAdmin?.id, + userName: res.locals.organizationAdmin?.name, + userType: (res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'success' as NSLogs.Type, request: 'Edit Organization Admin' }).then(() => { console.log('logged'); @@ -87,10 +88,10 @@ router.put("/:id", authorize("PUT_organizationAdmin"), validateAdminEdited, asyn res.status(201).send("Organization Admin edited successfully!!") }).catch(err => { log({ - userId: res.locals.organizationAdmin.id, - userName: res.locals.organizationAdmin.name, - userType: 'admin', - type: 'failed', + userId: res.locals.organizationAdmin?.id, + userName: res.locals.organizationAdmin?.name, + userType: (res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'failed' as NSLogs.Type, request: 'Edit Organization Admin' }).then(() => { console.log('logged'); @@ -114,10 +115,10 @@ router.get('/', authorize("GET_organizationAdmins"), async (req, res, next) => { getOrganizationAdmins(payload) .then(data => { log({ - userId: res.locals.organizationAdmin.id, - userName: res.locals.organizationAdmin.name, - userType: 'admin', - type: 'success', + userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + userName: res.locals.organizationAdmin.name || res.locals.volunteer?.name, + userType: (res.locals.volunteer ? "volunteer" : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'success' as NSLogs.Type, request: 'Get all Organization Admins' }).then(() => { console.log('logged'); @@ -128,10 +129,10 @@ router.get('/', authorize("GET_organizationAdmins"), async (req, res, next) => { }) .catch(err => { log({ - userId: res.locals.organizationAdmin.id, - userName: res.locals.organizationAdmin.name, - userType: 'admin', - type: 'failed', + userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + userName: res.locals.organizationAdmin.name || res.locals.volunteer?.name, + userType: (res.locals.volunteer ? "volunteer" : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'failed' as NSLogs.Type, request: 'Get all Organization Admins' }).then(() => { console.log('logged'); From 9ee37c02fc8561d2b6aec848e7c04c5b95d00af1 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Mon, 9 Oct 2023 07:52:53 +0300 Subject: [PATCH 091/146] Edit the logger call in orgProfile --- src/routes/organizationProfile.ts | 53 ++++++++++++++++--------------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/src/routes/organizationProfile.ts b/src/routes/organizationProfile.ts index 8315cd7f..c4c5888a 100644 --- a/src/routes/organizationProfile.ts +++ b/src/routes/organizationProfile.ts @@ -3,16 +3,17 @@ import { createOrganizationProfile, deleteOrganizationProfile, editOrganizationP import { authorize, checkAdmin } from "../middleware/auth/authorize.js"; import { validateOrgId, validateOrganizationProfile } from "../middleware/validation/organizationProfile.js"; import { log } from "../controllers/logs.js"; +import { NSLogs } from "../../types/logs.js"; const router = express.Router(); router.post('/', authorize("POST_organizationProfile"), validateOrganizationProfile, (req, res, next) => { createOrganizationProfile(req.body).then(() => { log({ - userId: res.locals.organizationAdmin.id, - userName: res.locals.organizationAdmin.name, - userType: 'admin', - type: 'success', + userId: res.locals.organizationAdmin?.id, + userName: res.locals.organizationAdmin?.name, + userType: 'root' as NSLogs.userType, + type: 'success' as NSLogs.Type, request: 'Create Organization Profile' }).then(() => { console.log('logged'); @@ -24,8 +25,8 @@ router.post('/', authorize("POST_organizationProfile"), validateOrganizationProf log({ userId: res.locals.organizationAdmin.id, userName: res.locals.organizationAdmin.name, - userType: 'admin', - type: 'failed', + userType: 'admin' as NSLogs.userType, + type: 'failed' as NSLogs.Type, request: 'Create Organization Profile' }).then(() => { console.log('logged'); @@ -42,10 +43,10 @@ router.delete('/:id', validateOrgId, authorize("DELETE_organizationProfile"), as deleteOrganizationProfile(id) .then(data => { log({ - userId: res.locals.organizationAdmin.id, - userName: res.locals.organizationAdmin.name, - userType: 'admin', - type: 'success', + userId: res.locals.organizationAdmin?.id, + userName: res.locals.organizationAdmin?.name, + userType: (res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'success' as NSLogs.Type, request: 'Delete Organization Profile' }).then(() => { console.log('logged'); @@ -56,10 +57,10 @@ router.delete('/:id', validateOrgId, authorize("DELETE_organizationProfile"), as }) .catch(err => { log({ - userId: res.locals.organizationAdmin.id, - userName: res.locals.organizationAdmin.name, - userType: 'admin', - type: 'failed', + userId: res.locals.organizationAdmin?.id, + userName: res.locals.organizationAdmin?.name, + userType: (res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'failed' as NSLogs.Type, request: 'Delete Organization Profile' }).then(() => { console.log('logged'); @@ -75,8 +76,8 @@ router.put("/:id", validateOrgId, authorize("PUT_organizationProfile"), async (r log({ userId: res.locals.organizationAdmin.id, userName: res.locals.organizationAdmin.name, - userType: 'admin', - type: 'success', + userType: (res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'success' as NSLogs.Type, request: 'Edit Organization Profile' }).then(() => { console.log('logged'); @@ -88,8 +89,8 @@ router.put("/:id", validateOrgId, authorize("PUT_organizationProfile"), async (r log({ userId: res.locals.organizationAdmin.id, userName: res.locals.organizationAdmin.name, - userType: 'admin', - type: 'failed', + userType: (res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'failed' as NSLogs.Type, request: 'Edit Organization Profile' }).then(() => { console.log('logged'); @@ -112,10 +113,10 @@ router.get('/', authorize("GET_organizationProfiles"), async (req, res, next) => getOrganizationProfile(payload) .then(data => { log({ - userId: res.locals.organizationAdmin.id, - userName: res.locals.organizationAdmin.name, - userType: 'admin', - type: 'success', + userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + userName: res.locals.organizationAdmin.name || res.locals.volunteer?.name, + userType: (res.locals.volunteer ? "volunteer" : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'success' as NSLogs.Type, request: 'Get Organization Profiles' }).then(() => { console.log('logged'); @@ -126,10 +127,10 @@ router.get('/', authorize("GET_organizationProfiles"), async (req, res, next) => }) .catch(err => { log({ - userId: res.locals.organizationAdmin.id, - userName: res.locals.organizationAdmin.name, - userType: 'admin', - type: 'failed', + userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + userName: res.locals.organizationAdmin.name || res.locals.volunteer?.name, + userType: (res.locals.volunteer ? "volunteer" : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'failed' as NSLogs.Type, request: 'Get Organization Profiles' }).then(() => { console.log('logged'); From b27bcee67459883a3ce5a4c1ba0828f8216c1bda Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Mon, 9 Oct 2023 07:54:52 +0300 Subject: [PATCH 092/146] Edit to add premium to logger type --- src/routes/organizationAdmin.ts | 4 ++-- src/routes/organizationProfile.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/routes/organizationAdmin.ts b/src/routes/organizationAdmin.ts index 20767ca4..95248569 100644 --- a/src/routes/organizationAdmin.ts +++ b/src/routes/organizationAdmin.ts @@ -117,7 +117,7 @@ router.get('/', authorize("GET_organizationAdmins"), async (req, res, next) => { log({ userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, userName: res.locals.organizationAdmin.name || res.locals.volunteer?.name, - userType: (res.locals.volunteer ? "volunteer" : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + userType: (res.locals.volunteer?.type ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'success' as NSLogs.Type, request: 'Get all Organization Admins' }).then(() => { @@ -131,7 +131,7 @@ router.get('/', authorize("GET_organizationAdmins"), async (req, res, next) => { log({ userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, userName: res.locals.organizationAdmin.name || res.locals.volunteer?.name, - userType: (res.locals.volunteer ? "volunteer" : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + userType: (res.locals.volunteer?.type ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'failed' as NSLogs.Type, request: 'Get all Organization Admins' }).then(() => { diff --git a/src/routes/organizationProfile.ts b/src/routes/organizationProfile.ts index c4c5888a..54897f9d 100644 --- a/src/routes/organizationProfile.ts +++ b/src/routes/organizationProfile.ts @@ -115,7 +115,7 @@ router.get('/', authorize("GET_organizationProfiles"), async (req, res, next) => log({ userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, userName: res.locals.organizationAdmin.name || res.locals.volunteer?.name, - userType: (res.locals.volunteer ? "volunteer" : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'success' as NSLogs.Type, request: 'Get Organization Profiles' }).then(() => { @@ -129,7 +129,7 @@ router.get('/', authorize("GET_organizationProfiles"), async (req, res, next) => log({ userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, userName: res.locals.organizationAdmin.name || res.locals.volunteer?.name, - userType: (res.locals.volunteer ? "volunteer" : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + userType: (res.locals.volunteer?.type ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'failed' as NSLogs.Type, request: 'Get Organization Profiles' }).then(() => { From b0ecd1ef8982b539ab48bd683e2f89cedfd0fdaa Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Mon, 9 Oct 2023 07:59:09 +0300 Subject: [PATCH 093/146] Edit permission logger call --- src/routes/permission.ts | 61 ++++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/src/routes/permission.ts b/src/routes/permission.ts index f8b6a9e6..c3bc037f 100644 --- a/src/routes/permission.ts +++ b/src/routes/permission.ts @@ -3,16 +3,17 @@ import { createPermission, deletePermission, editPermission, getPermissions } fr import { authorize } from '../middleware/auth/authorize.js'; import { validatePermission, validatePermissionId } from '../middleware/validation/permission.js'; import { log } from '../controllers/logs.js'; +import { NSLogs } from '../../types/logs.js'; var router = express.Router(); router.post('/', authorize("POST_permissions"), validatePermission, (req, res, next) => { createPermission(req.body).then(() => { log({ - userId: res.locals.organizationAdmin.id, - userName: res.locals.organizationAdmin.name, - userType: 'admin', - type: 'success', + userId: res.locals.organizationAdmin?.id, + userName: res.locals.organizationAdmin?.name, + userType: 'root' as NSLogs.userType, + type: 'success' as NSLogs.Type, request: 'Create Permission' }).then(() => { console.log('logged'); @@ -24,8 +25,8 @@ router.post('/', authorize("POST_permissions"), validatePermission, (req, res, n log({ userId: res.locals.organizationAdmin.id, userName: res.locals.organizationAdmin.name, - userType: 'admin', - type: 'failed', + userType: 'root' as NSLogs.userType, + type: 'failed' as NSLogs.Type, request: 'Create Permission' }).then(() => { console.log('logged'); @@ -42,10 +43,10 @@ router.delete('/:id', validatePermissionId, authorize("DELETE_permission"), asyn deletePermission(id) .then(data => { log({ - userId: res.locals.organizationAdmin.id, - userName: res.locals.organizationAdmin.name, - userType: 'admin', - type: 'success', + userId: res.locals.organizationAdmin?.id, + userName: res.locals.organizationAdmin?.name, + userType: 'root' as NSLogs.userType, + type: 'success' as NSLogs.Type, request: 'Delete Permission' }).then(() => { console.log('logged'); @@ -56,10 +57,10 @@ router.delete('/:id', validatePermissionId, authorize("DELETE_permission"), asyn }) .catch(err => { log({ - userId: res.locals.organizationAdmin.id, - userName: res.locals.organizationAdmin.name, - userType: 'admin', - type: 'failed', + userId: res.locals.organizationAdmin?.id, + userName: res.locals.organizationAdmin?.name, + userType: 'root' as NSLogs.userType, + type: 'failed' as NSLogs.Type, request: 'Delete Permission' }).then(() => { console.log('logged'); @@ -73,10 +74,10 @@ router.delete('/:id', validatePermissionId, authorize("DELETE_permission"), asyn router.put("/:id", authorize("PUT_permission"), validatePermissionId, async (req, res, next) => { editPermission({ ...req.body, id: req.params.id?.toString() }).then(() => { log({ - userId: res.locals.organizationAdmin.id, - userName: res.locals.organizationAdmin.name, - userType: 'admin', - type: 'success', + userId: res.locals.organizationAdmin?.id, + userName: res.locals.organizationAdmin?.name, + userType: 'root' as NSLogs.userType, + type: 'success' as NSLogs.Type, request: 'Edit Permission' }).then(() => { console.log('logged'); @@ -86,10 +87,10 @@ router.put("/:id", authorize("PUT_permission"), validatePermissionId, async (req res.status(201).send("Permission edited successfully!!") }).catch(err => { log({ - userId: res.locals.organizationAdmin.id, - userName: res.locals.organizationAdmin.name, - userType: 'admin', - type: 'failed', + userId: res.locals.organizationAdmin?.id, + userName: res.locals.organizationAdmin?.name, + userType: 'root' as NSLogs.userType, + type: 'failed' as NSLogs.Type, request: 'Edit Permission' }).then(() => { console.log('logged'); @@ -111,10 +112,10 @@ router.get('/', authorize("GET_permissions"), async (req, res, next) => { getPermissions(payload) .then(data => { log({ - userId: res.locals.organizationAdmin.id, - userName: res.locals.organizationAdmin.name, - userType: 'admin', - type: 'success', + userId: res.locals.organizationAdmin?.id, + userName: res.locals.organizationAdmin?.name, + userType: 'root' as NSLogs.userType, + type: 'success' as NSLogs.Type, request: 'Get Permissions' }).then(() => { console.log('logged'); @@ -125,10 +126,10 @@ router.get('/', authorize("GET_permissions"), async (req, res, next) => { }) .catch(err => { log({ - userId: res.locals.organizationAdmin.id, - userName: res.locals.organizationAdmin.name, - userType: 'admin', - type: 'failed', + userId: res.locals.organizationAdmin?.id, + userName: res.locals.organizationAdmin?.name, + userType: 'root' as NSLogs.userType, + type: 'failed' as NSLogs.Type, request: 'Get Permissions' }).then(() => { console.log('logged'); From d9dc5f77e3312973f20daa22db578f2de87e5b79 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Mon, 9 Oct 2023 08:01:18 +0300 Subject: [PATCH 094/146] Edit role logger call --- src/routes/role.ts | 137 ++++++++++++++++++++++++--------------------- 1 file changed, 73 insertions(+), 64 deletions(-) diff --git a/src/routes/role.ts b/src/routes/role.ts index 5c62555a..6e695e17 100644 --- a/src/routes/role.ts +++ b/src/routes/role.ts @@ -4,33 +4,36 @@ import { NSRole } from '../../types/role.js'; import { authorize } from '../middleware/auth/authorize.js'; import { validateEditedRole, validateRole, validateRoleId } from '../middleware/validation/role.js'; import { log } from '../controllers/logs.js'; +import { NSLogs } from '../../types/logs.js'; var router = express.Router(); router.post('/', authorize("POST_role"), validateRole, (req, res, next) => { createRole(req.body).then(() => { - log ({ + log({ userId: res.locals.organizationAdmin.id, userName: res.locals.organizationAdmin.name, - userType: 'admin', - type: 'success', - request: 'Create Role'}).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + userType: 'root' as NSLogs.userType, + type: 'success' as NSLogs.Type, + request: 'Create Role' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.status(201).send("Role created successfully!!") }).catch(err => { - log ({ + log({ userId: res.locals.organizationAdmin.id, userName: res.locals.organizationAdmin.name, - userType: 'admin', - type: 'failed', - request: 'Create Role'}).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + userType: 'root' as NSLogs.userType, + type: 'failed' as NSLogs.Type, + request: 'Create Role' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(err); }); }); @@ -40,57 +43,61 @@ router.delete('/:id', validateRoleId, authorize("DELETE_role"), async (req, res, deleteRole(id) .then(data => { - log ({ + log({ userId: res.locals.organizationAdmin.id, userName: res.locals.organizationAdmin.name, - userType: 'admin', - type: 'success', - request: 'Delete Role'}).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + userType: 'root' as NSLogs.userType, + type: 'success' as NSLogs.Type, + request: 'Delete Role' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.send(data); }) .catch(err => { - log ({ + log({ userId: res.locals.organizationAdmin.id, userName: res.locals.organizationAdmin.name, - userType: 'admin', - type: 'failed', - request: 'Delete Role'}).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + userType: 'root' as NSLogs.userType, + type: 'failed' as NSLogs.Type, + request: 'Delete Role' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(err); }); }) router.put("/:id", authorize("PUT_role"), validateEditedRole, async (req, res, next) => { editRole({ ...req.body, id: req.params.id?.toString() }).then(() => { - log ({ + log({ userId: res.locals.organizationAdmin.id, userName: res.locals.organizationAdmin.name, - userType: 'admin', - type: 'success', - request: 'Edit Role'}).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + userType: 'root' as NSLogs.userType, + type: 'success' as NSLogs.Type, + request: 'Edit Role' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.status(201).send("Role edited successfully!!") }).catch(err => { - log ({ + log({ userId: res.locals.organizationAdmin.id, userName: res.locals.organizationAdmin.name, - userType: 'admin', - type: 'failed', - request: 'Edit Role'}).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + userType: 'root' as NSLogs.userType, + type: 'failed' as NSLogs.Type, + request: 'Edit Role' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(err); }); }); @@ -105,29 +112,31 @@ router.get('/', authorize("GET_roles"), async (req, res, next) => { getRoles(payload) .then(data => { - log ({ + log({ userId: res.locals.organizationAdmin.id, userName: res.locals.organizationAdmin.name, - userType: 'admin', - type: 'success', - request: 'Get Roles'}).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + userType: 'root' as NSLogs.userType, + type: 'success' as NSLogs.Type, + request: 'Get Roles' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.send(data); }) .catch(err => { - log ({ + log({ userId: res.locals.organizationAdmin.id, userName: res.locals.organizationAdmin.name, - userType: 'admin', - type: 'failed', - request: 'Get Roles'}).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + userType: 'root' as NSLogs.userType, + type: 'failed' as NSLogs.Type, + request: 'Get Roles' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(err); }); }); From 97108abb295013b0f652f94ad6a0a8d7abc0c55f Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Mon, 9 Oct 2023 09:45:39 +0300 Subject: [PATCH 095/146] Edit voluntary work logger calls --- src/middleware/auth/authorize.ts | 2 - src/routes/voluntaryWork.ts | 510 ++++++++++++++++--------------- 2 files changed, 264 insertions(+), 248 deletions(-) diff --git a/src/middleware/auth/authorize.ts b/src/middleware/auth/authorize.ts index 84b3e925..e25cf5c9 100644 --- a/src/middleware/auth/authorize.ts +++ b/src/middleware/auth/authorize.ts @@ -2,9 +2,7 @@ import express from 'express'; import { NSPermission } from '../../../types/permission.js'; import { OrganizationAdmin } from '../../db/entities/OrganizationAdmin.js'; import { Volunteer } from '../../db/entities/Volunteer.js'; -import { OrganizationProfile } from '../../db/entities/OrganizationProfile.js'; import { VoluntaryWork } from '../../db/entities/VoluntaryWork.js'; -import { VolunteerProfile } from '../../db/entities/VolunteerProfile.js'; import createError from 'http-errors'; const authorize = (api: string) => { diff --git a/src/routes/voluntaryWork.ts b/src/routes/voluntaryWork.ts index 4f8f2738..7c49d61f 100644 --- a/src/routes/voluntaryWork.ts +++ b/src/routes/voluntaryWork.ts @@ -6,33 +6,36 @@ import { authorize, checkParticipation } from '../middleware/auth/authorize.js'; import { validateEditedVoluntaryWork, validateVoluntaryWork, validateVoluntaryWorkId } from '../middleware/validation/voluntaryWork.js'; import { UploadedFile } from 'express-fileupload'; import { log } from '../controllers/logs.js'; +import { NSLogs } from '../../types/logs.js'; var router = express.Router(); router.post('/', authorize("POST_voluntaryWork"), validateVoluntaryWork, (req, res, next) => { createVoluntaryWork({ ...req.body, creatorId: res.locals.volunteer?.id || res.locals.organizationAdmin?.id }).then(() => { res.status(201).send("Voluntary work created successfully!!") - log ({ - userId: res.locals.organizationAdmin.id, - userName: res.locals.organizationAdmin.name, - userType: 'admin', - type: 'success', - request: 'Create VoluntaryWork'}).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + log({ + userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, + userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'success' as NSLogs.Type, + request: 'Create Voluntary Work' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) }).catch(err => { - log ({ - userId: res.locals.organizationAdmin.id, - userName: res.locals.organizationAdmin.name, - userType: 'admin', - type: 'failed', - request: 'Create VoluntaryWork'}).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + log({ + userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, + userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'failed' as NSLogs.Type, + request: 'Create Voluntary Work' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(err); }); }); @@ -42,57 +45,61 @@ router.delete('/:id', validateVoluntaryWorkId, authorize("DELETE_voluntaryWork") deleteVoluntaryWork(id) .then(data => { - log ({ - userId: res.locals.organizationAdmin.id, - userName: res.locals.organizationAdmin.name, - userType: 'admin', - type: 'success', - request: 'Delete VoluntaryWork'}).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + log({ + userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, + userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'success' as NSLogs.Type, + request: 'Delete Voluntary Work' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.send(data); }) .catch(err => { - log ({ - userId: res.locals.organizationAdmin.id, - userName: res.locals.organizationAdmin.name, - userType: 'admin', - type: 'failed', - request: 'Delete VoluntaryWork'}).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + log({ + userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, + userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'failed' as NSLogs.Type, + request: 'Delete Voluntary Work' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(err); }); }) router.put("/:id", authorize("PUT_voluntaryWork"), validateEditedVoluntaryWork, async (req, res, next) => { editVoluntaryWork({ ...req.body, id: req.params.id?.toString() }).then(() => { - log ({ - userId: res.locals.organizationAdmin.id, - userName: res.locals.organizationAdmin.name, - userType: 'admin', - type: 'success', - request: 'Edit VoluntaryWork'}).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + log({ + userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, + userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'success' as NSLogs.Type, + request: 'Edit Voluntary Work' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.status(201).send("Voluntary Work edited successfully!!") }).catch(err => { - log ({ - userId: res.locals.organizationAdmin.id, - userName: res.locals.organizationAdmin.name, - userType: 'admin', - type: 'failed', - request: 'Edit VoluntaryWork'}).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + log({ + userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, + userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'failed' as NSLogs.Type, + request: 'Edit Voluntary Work' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(err); }); }); @@ -124,29 +131,31 @@ router.get('/', authorize("GET_voluntaryWorks"), async (req, res, next) => { getVoluntaryWorks(payload) .then(data => { - log ({ - userId: res.locals.organizationAdmin.id, - userName: res.locals.organizationAdmin.name, - userType: 'admin', - type: 'success', - request: 'Get VoluntaryWork/s'}).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + log({ + userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, + userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'success' as NSLogs.Type, + request: 'Get Voluntary Work/s' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.send(data); }) .catch(err => { - log ({ - userId: res.locals.organizationAdmin.id, + log({ + userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, userName: res.locals.organizationAdmin.name, - userType: 'admin', - type: 'failed', - request: 'Get VoluntaryWork/s'}).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'failed' as NSLogs.Type, + request: 'Get Voluntary Work/s' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(err); }); }); @@ -178,29 +187,31 @@ router.get('/analysis', authorize("GET_analysis"), async (req, res, next) => { getVoluntaryWorks(payload) .then(data => { - log ({ - userId: res.locals.organizationAdmin.id, - userName: res.locals.organizationAdmin.name, - userType: 'admin', - type: 'success', - request: 'Analysis VoluntaryWorks'}).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + log({ + userId: res.locals.organizationAdmin?.id, + userName: res.locals.organizationAdmin?.name, + userType: 'root' as NSLogs.userType, + type: 'success' as NSLogs.Type, + request: 'Analysis Voluntary Works' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.send(data); }) .catch(err => { - log ({ - userId: res.locals.organizationAdmin.id, - userName: res.locals.organizationAdmin.name, - userType: 'admin', - type: 'failed', - request: 'Analysis VoluntaryWorks'}).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + log({ + userId: res.locals.organizationAdmin?.id, + userName: res.locals.organizationAdmin?.name, + userType: "root" as NSLogs.userType, + type: 'failed' as NSLogs.Type, + request: 'Analysis Voluntary Works' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(err); }); }); @@ -209,113 +220,121 @@ router.get('/recommendation', authorize("GET_recommendation"), async (req, res, const payload = { ...res.locals.volunteer }; getVoluntaryWorks(payload) .then(data => { - log ({ - userId: res.locals.organizationAdmin.id, - userName: res.locals.organizationAdmin.name, - userType: 'admin', - type: 'success', - request: 'Recommendation'}).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + log({ + userId: res.locals.volunteer?.id, + userName: res.locals.volunteer?.name, + userType: res.locals.volunteer?.type as NSLogs.userType, + type: 'success' as NSLogs.Type, + request: 'Get recommendation' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.send(data); }) .catch(err => { - log ({ - userId: res.locals.organizationAdmin.id, - userName: res.locals.organizationAdmin.name, - userType: 'admin', - type: 'failed', - request: 'Recommendation'}).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + log({ + userId: res.locals.volunteer?.id, + userName: res.locals.volunteer?.name, + userType: res.locals.volunteer?.type as NSLogs.userType, + type: 'failed' as NSLogs.Type, + request: 'Get recommendation' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(err); }); }); router.put("/rating/:id", validateVoluntaryWorkId, authorize("PUT_rating"), checkParticipation, async (req, res, next) => { putRating(Number(req.params.id), Number(req.body.rating)).then(() => { - log ({ - userId: res.locals.organizationAdmin.id, - userName: res.locals.organizationAdmin.name, - userType: 'admin', - type: 'success', - request: 'Rating'}).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + log({ + userId: res.locals.volunteer?.id, + userName: res.locals.volunteer?.name, + userType: res.locals.volunteer?.type as NSLogs.userType, + type: 'success' as NSLogs.Type, + request: 'Add Rating' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.status(201).send("Rating added successfully!!") }).catch(err => { - log ({ - userId: res.locals.organizationAdmin.id, - userName: res.locals.organizationAdmin.name, - userType: 'admin', - type: 'failed', - request: 'Rating'}).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + log({ + userId: res.locals.volunteer?.id, + userName: res.locals.volunteer?.name, + userType: res.locals.volunteer?.type as NSLogs.userType, + type: 'failed' as NSLogs.Type, + request: 'Add Rating' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(err); }); }); router.put("/feedback/:id", validateVoluntaryWorkId, authorize("PUT_feedback"), checkParticipation, async (req, res, next) => { putFeedback(Number(req.params.id), req.body.feedback).then(() => { - log ({ - userId: res.locals.organizationAdmin.id, - userName: res.locals.organizationAdmin.name, - userType: 'admin', - type: 'success', - request: 'Feedback'}).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + log({ + userId: res.locals.volunteer?.id, + userName: res.locals.volunteer?.name, + userType: res.locals.volunteer?.type as NSLogs.userType, + type: 'success' as NSLogs.Type, + request: 'Add feedback' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.status(201).send("Feedback added successfully!!") }).catch(err => { - log ({ - userId: res.locals.organizationAdmin.id, - userName: res.locals.organizationAdmin.name, - userType: 'admin', - type: 'failed', - request: 'Feedback'}).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + log({ + userId: res.locals.volunteer?.id, + userName: res.locals.organizationAdmin?.name, + userType: res.locals.volunteer?.type as NSLogs.userType, + type: 'failed' as NSLogs.Type, + request: 'Add feedback' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(err); }); }); router.put("/images/:id", validateVoluntaryWorkId, authorize("PUT_images"), async (req, res, next) => { putImages(Number(req.params.id), ((Array.isArray(req.files?.image) ? req.files?.image : [req.files?.image]).filter(Boolean)) as UploadedFile[]).then(() => { - log ({ - userId: res.locals.organizationAdmin.id, - userName: res.locals.organizationAdmin.name, - userType: 'admin', - type: 'success', - request: 'Add images'}).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + log({ + userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, + userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'success' as NSLogs.Type, + request: 'Add images' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.status(201).send("Images added successfully!!") }).catch(err => { - log ({ - userId: res.locals.organizationAdmin.id, - userName: res.locals.organizationAdmin.name, - userType: 'admin', - type: 'failed', - request: 'Add images'}).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + log({ + userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, + userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'failed' as NSLogs.Type, + request: 'Add images' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(err); }); }); @@ -323,93 +342,92 @@ router.put("/images/:id", validateVoluntaryWorkId, authorize("PUT_images"), asyn router.put("/register/:id", validateVoluntaryWorkId, authorize("REGISTER_voluntaryWork"), async (req, res, next) => { if (res.locals.volunteer) { registerByVolunteer(Number(req.params.id), res.locals.volunteer.volunteerProfile).then(() => { - log ({ - userId: res.locals.organizationAdmin.id, - userName: res.locals.organizationAdmin.name, - userType: 'admin', - type: 'success', - request: 'Register VoluntaryWorks'}).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + log({ + userId: res.locals.volunteer?.id, + userName: res.locals.volunteer?.name, + userType: res.locals.volunteer?.type as NSLogs.userType, + type: 'success' as NSLogs.Type, + request: 'Register voluntary work' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.status(201).send("Registration done successfully!!") }).catch(err => { - log ({ - userId: res.locals.organizationAdmin.id, - userName: res.locals.organizationAdmin.name, - userType: 'admin', - type: 'failed', - request: 'Register VoluntaryWorks'}).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + log({ + userId: res.locals.volunteer?.id, + userName: res.locals.volunteer?.name, + userType: res.locals.volunteer?.type as NSLogs.userType, + type: 'failed' as NSLogs.Type, + request: 'Register voluntary work' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(err); }); } else if (res.locals.organizationAdmin) { - - if (!req.body.volunteerId.toString()) { res.status(400).send("volunteer id is required!"); } - registerByOrganizationAdmin(Number(req.params.id), req.body.volunteerId.toString()).then(() => { - log ({ - userId: res.locals.organizationAdmin.id, - userName: res.locals.organizationAdmin.name, - userType: 'admin', - type: 'success', - request: 'Register By Organization Admin'}).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + log({ + userId: res.locals.organizationAdmin?.id, + userName: res.locals.organizationAdmin?.name, + userType: (res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'success' as NSLogs.Type, + request: 'Register By Organization Admin' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.status(201).send("Registration done successfully!!") }).catch(err => { - log ({ - userId: res.locals.organizationAdmin.id, - userName: res.locals.organizationAdmin.name, - userType: 'admin', - type: 'failed', - request: 'Register By Organization Admin'}).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + log({ + userId: res.locals.organizationAdmin?.id, + userName: res.locals.organizationAdmin?.name, + userType: (res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'failed' as NSLogs.Type, + request: 'Register By Organization Admin' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(err); }); } }); router.put("/deregister/:id", validateVoluntaryWorkId, authorize("DEREGISTER_voluntaryWork"), async (req, res, next) => { - - if (!res.locals.volunteer?.id && !req.body.volunteerId?.toString()) { - res.status(400).send("Volunteer id is required !"); - } deregisterVoluntaryWork(Number(req.params.id), res.locals.volunteer.id || req.body.volunteerId.toString()).then(() => { - log ({ - userId: res.locals.organizationAdmin.id, - userName: res.locals.organizationAdmin.name, - userType: 'admin', - type: 'success', - request: 'Deregister'}).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + log({ + userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, + userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'success' as NSLogs.Type, + request: 'Deregister voluntary work' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.status(201).send("Deregistration done successfully!!") }).catch(err => { - log ({ - userId: res.locals.organizationAdmin.id, - userName: res.locals.organizationAdmin.name, - userType: 'admin', - type: 'failed', - request: 'Deregister'}).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + log({ + userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + userName: res.locals.organizationAdmin.name || res.locals.volunteer?.name, + userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'failed' as NSLogs.Type, + request: 'Deregister voluntary work' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(err); }); }); From c899921a7833697aca38f5105752b5cf03e65fa8 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Mon, 9 Oct 2023 10:39:36 +0300 Subject: [PATCH 096/146] Edit volunteer logger calls --- src/controllers/volunteer.ts | 1 + src/routes/permission.ts | 7 +- src/routes/volunteer.ts | 249 ++++++++++++++++++++--------------- 3 files changed, 151 insertions(+), 106 deletions(-) diff --git a/src/controllers/volunteer.ts b/src/controllers/volunteer.ts index afa48c38..87c66706 100644 --- a/src/controllers/volunteer.ts +++ b/src/controllers/volunteer.ts @@ -43,6 +43,7 @@ const createVolunteer = async (payload: NSVolunteer.Item) => { } await transaction.save(newVolunteer); + return newVolunteer }); }; diff --git a/src/routes/permission.ts b/src/routes/permission.ts index c3bc037f..0dbb440b 100644 --- a/src/routes/permission.ts +++ b/src/routes/permission.ts @@ -7,8 +7,9 @@ import { NSLogs } from '../../types/logs.js'; var router = express.Router(); -router.post('/', authorize("POST_permissions"), validatePermission, (req, res, next) => { - createPermission(req.body).then(() => { +router.post('/', authorize("POST_permission"), validatePermission, (req, res, next) => { + createPermission(req.body).then((data) => { + log({ userId: res.locals.organizationAdmin?.id, userName: res.locals.organizationAdmin?.name, @@ -19,7 +20,7 @@ router.post('/', authorize("POST_permissions"), validatePermission, (req, res, n console.log('logged'); }).catch(err => { console.log('NOT logged'); - }) + }) res.status(201).send("Permission created successfully!!") }).catch(err => { log({ diff --git a/src/routes/volunteer.ts b/src/routes/volunteer.ts index 498186ce..37a3561f 100644 --- a/src/routes/volunteer.ts +++ b/src/routes/volunteer.ts @@ -5,33 +5,36 @@ import { validateEditedVolunteer, validateVolunteer } from '../middleware/valida import { createVolunteer, deleteVolunteer, editVolunteer, getVolunteers, login } from '../controllers/volunteer.js'; import { NSVolunteer } from '../../types/volunteer.js'; import { log } from '../controllers/logs.js'; +import { NSLogs } from '../../types/logs.js'; var router = express.Router(); router.post('/register', validateVolunteer, (req, res, next) => { - createVolunteer({...req.body,type:"volunteer" }).then(() => { - log ({ - userId: res.locals.organizationAdmin.id || res.locals.volunteer.id, - userName: res.locals.organizationAdmin.name || res.locals.volunteer.name, - userType: 'admin', - type: 'success', - request: 'Register volunteer'}).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + createVolunteer({ ...req.body, type: "volunteer" }).then((data) => { + log({ + userId: req.body.id, + userName: req.body.name, + userType: req.body.type as NSLogs.userType, + type: 'success' as NSLogs.Type, + request: 'Register volunteer' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.status(201).send("Volunteer created successfully!!") }).catch(err => { - log ({ - userId: res.locals.organizationAdmin.id || res.locals.volunteer.id, - userName: res.locals.organizationAdmin.name || res.locals.volunteer.name, - userType: 'admin', - type: 'failed', - request: 'Register volunteer'}).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + log({ + userId: req.body.id, + userName: req.body.name, + userType: req.body.type as NSLogs.userType, + type: 'failed' as NSLogs.Type, + request: 'Register volunteer' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(err); }); }); @@ -44,32 +47,34 @@ router.post('/login', (req, res, next) => { .then(data => { res.cookie('myApp', data, { httpOnly: true, - maxAge: 60 *24 * 60 * 1000, + maxAge: 60 * 24 * 60 * 1000, sameSite: "lax" // Protect against CSRF attacks }); - log ({ - userId: res.locals.organizationAdmin.id || res.locals.volunteer.id, - userName: res.locals.organizationAdmin.name || res.locals.volunteer.name, - userType: 'admin', - type: 'success', - request: 'Login'}).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + log({ + userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, + userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'success' as NSLogs.Type, + request: 'Login' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.status(201).send("You logged in successfully !"); }) .catch(err => { - log ({ - userId: res.locals.organizationAdmin.id || res.locals.volunteer.id, - userName: res.locals.organizationAdmin.name || res.locals.volunteer.name, - userType: 'admin', - type: 'failed', - request: 'Login'}).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + log({ + userId: req.body.id, + userName: req.body.name, + userType: 'volunteer' as NSLogs.userType, + type: 'failed' as NSLogs.Type, + request: 'Login' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.status(401).send(err); }) }); @@ -79,57 +84,61 @@ router.delete('/:id', authenticate, authorize("DELETE_volunteer"), async (req, r deleteVolunteer(id) .then(data => { - log ({ - userId: res.locals.organizationAdmin.id || res.locals.volunteer.id, - userName: res.locals.organizationAdmin.name || res.locals.volunteer.name, - userType: 'admin', - type: 'success', - request: 'Delete Volunteer'}).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + log({ + userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, + userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'success' as NSLogs.Type, + request: 'Delete Volunteer' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.send(data); }) .catch(error => { - log ({ - userId: res.locals.organizationAdmin.id || res.locals.volunteer.id, - userName: res.locals.organizationAdmin.name || res.locals.volunteer.name, - userType: 'admin', - type: 'failed', - request: 'Delete Volunteer'}).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + log({ + userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, + userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'failed' as NSLogs.Type, + request: 'Delete Volunteer' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(error); }); }) router.put("/:id", authenticate, authorize("PUT_volunteer"), validateEditedVolunteer, async (req, res, next) => { editVolunteer({ ...req.body, id: req.params.id?.toString() }).then(() => { - log ({ - userId: res.locals.organizationAdmin.id || res.locals.volunteer.id, - userName: res.locals.organizationAdmin.name || res.locals.volunteer.name, - userType: 'admin', - type: 'success', - request: 'Edit Volunteer'}).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + log({ + userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, + userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'success' as NSLogs.Type, + request: 'Edit Volunteer' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.status(201).send("Volunteer edited successfully!!") }).catch(err => { - log ({ - userId: res.locals.organizationAdmin.id || res.locals.volunteer.id, - userName: res.locals.organizationAdmin.name || res.locals.volunteer.name, - userType: 'admin', - type: 'failed', - request: 'Edit Volunteer'}).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + log({ + userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, + userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'failed' as NSLogs.Type, + request: 'Edit Volunteer' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(err); }); }); @@ -151,29 +160,31 @@ router.get('/', authenticate, authorize("GET_volunteers"), async (req, res, next getVolunteers(payload) .then(data => { - log ({ - userId: res.locals.organizationAdmin.id || res.locals.volunteer.id, - userName: res.locals.organizationAdmin.name || res.locals.volunteer.name, - userType: 'admin', - type: 'success', - request: 'get Volunteer/s'}).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + log({ + userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, + userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'success' as NSLogs.Type, + request: 'get Volunteer/s' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.send(data); }) .catch(err => { - log ({ - userId: res.locals.organizationAdmin.id || res.locals.volunteer.id, - userName: res.locals.organizationAdmin.name || res.locals.volunteer.name, - userType: 'admin', - type: 'failed', - request: 'Get Volunteer/s'}).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + log({ + userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, + userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'failed' as NSLogs.Type, + request: 'Get Volunteer/s' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(err); }); }); @@ -185,14 +196,46 @@ router.get("/logout", authenticate, (req, res, next) => { res.cookie("myApp", '', { maxAge: -1 }) - + log({ + userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, + userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'success' as NSLogs.Type, + request: 'Logout' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.send("You logged out successfully !"); }) router.get('/me', authenticate, authorize("GET_me"), async (req, res, next) => { if (res.locals.volunteer) { + log({ + userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, + userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'success' as NSLogs.Type, + request: 'Get my information' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.send(res.locals.volunteer); } else if (res.locals.organizationAdmin) { + log({ + userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, + userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'failed' as NSLogs.Type, + request: 'Get my information' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.send(res.locals.organizationAdmin); } }); From b057e8a6d786bd96b6e2d423966fe32a028b8f2c Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Mon, 9 Oct 2023 11:07:52 +0300 Subject: [PATCH 097/146] Adding extra information with specific details about the loging process --- src/routes/organizationAdmin.ts | 22 ++++++------ src/routes/organizationProfile.ts | 36 +++++++++---------- src/routes/permission.ts | 24 ++++++------- src/routes/role.ts | 44 +++++++++++------------ src/routes/voluntaryWork.ts | 60 +++++++++++++++---------------- src/routes/volunteer.ts | 18 +++++----- 6 files changed, 102 insertions(+), 102 deletions(-) diff --git a/src/routes/organizationAdmin.ts b/src/routes/organizationAdmin.ts index 95248569..153112c4 100644 --- a/src/routes/organizationAdmin.ts +++ b/src/routes/organizationAdmin.ts @@ -8,13 +8,13 @@ import { NSLogs } from "../../types/logs.js"; const router = express.Router(); router.post('/', authorize("POST_organizationAdmin"), validateOrganizationAdmin, (req, res, next) => { - createOrganizationAdmin(req.body).then(() => { + createOrganizationAdmin(req.body).then((data) => { log({ userId: res.locals.organizationAdmin?.id, userName: res.locals.organizationAdmin?.name, userType: 'root' as NSLogs.userType, type: 'success' as NSLogs.Type, - request: 'Create Organization Admin' + request: 'Create Organization Admin '+ data.name }).then(() => { console.log('logged'); }).catch(err => { @@ -28,7 +28,7 @@ router.post('/', authorize("POST_organizationAdmin"), validateOrganizationAdmin, userName: res.locals.organizationAdmin?.name, userType: 'root' as NSLogs.userType, type: 'failed' as NSLogs.Type, - request: 'Create Organization Admin' + request: 'Create Organization Admin ' + req.body.name }).then(() => { console.log('logged'); }).catch(err => { @@ -48,7 +48,7 @@ router.delete('/:id', validateAdminId, authorize("DELETE_organizationAdmin"), as userName: res.locals.organizationAdmin?.name, userType: (res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'success' as NSLogs.Type, - request: 'Delete Organization Admin' + request: 'Delete Organization Admin with id: '+ id }).then(() => { console.log('logged'); }).catch(err => { @@ -62,7 +62,7 @@ router.delete('/:id', validateAdminId, authorize("DELETE_organizationAdmin"), as userName: res.locals.organizationAdmin?.name, userType: (res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'failed' as NSLogs.Type, - request: 'Delete Organization Admin' + request: 'Delete Organization Admin with id: '+ id }).then(() => { console.log('logged'); }).catch(err => { @@ -79,7 +79,7 @@ router.put("/:id", authorize("PUT_organizationAdmin"), validateAdminEdited, asyn userName: res.locals.organizationAdmin?.name, userType: (res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'success' as NSLogs.Type, - request: 'Edit Organization Admin' + request: 'Edit Organization Admin with id: '+ req.params.id }).then(() => { console.log('logged'); }).catch(err => { @@ -92,7 +92,7 @@ router.put("/:id", authorize("PUT_organizationAdmin"), validateAdminEdited, asyn userName: res.locals.organizationAdmin?.name, userType: (res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'failed' as NSLogs.Type, - request: 'Edit Organization Admin' + request: 'Edit Organization Admin with id: '+ req.params.id }).then(() => { console.log('logged'); }).catch(err => { @@ -116,10 +116,10 @@ router.get('/', authorize("GET_organizationAdmins"), async (req, res, next) => { .then(data => { log({ userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, - userName: res.locals.organizationAdmin.name || res.locals.volunteer?.name, + userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, userType: (res.locals.volunteer?.type ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'success' as NSLogs.Type, - request: 'Get all Organization Admins' + request: 'Get Organization Admin/s' }).then(() => { console.log('logged'); }).catch(err => { @@ -130,10 +130,10 @@ router.get('/', authorize("GET_organizationAdmins"), async (req, res, next) => { .catch(err => { log({ userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, - userName: res.locals.organizationAdmin.name || res.locals.volunteer?.name, + userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, userType: (res.locals.volunteer?.type ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'failed' as NSLogs.Type, - request: 'Get all Organization Admins' + request: 'Get Organization Admin/s' }).then(() => { console.log('logged'); }).catch(err => { diff --git a/src/routes/organizationProfile.ts b/src/routes/organizationProfile.ts index 54897f9d..eec51e2e 100644 --- a/src/routes/organizationProfile.ts +++ b/src/routes/organizationProfile.ts @@ -8,13 +8,13 @@ import { NSLogs } from "../../types/logs.js"; const router = express.Router(); router.post('/', authorize("POST_organizationProfile"), validateOrganizationProfile, (req, res, next) => { - createOrganizationProfile(req.body).then(() => { + createOrganizationProfile(req.body).then((data) => { log({ userId: res.locals.organizationAdmin?.id, userName: res.locals.organizationAdmin?.name, userType: 'root' as NSLogs.userType, type: 'success' as NSLogs.Type, - request: 'Create Organization Profile' + request: 'Create Organization Profile ' + data.name }).then(() => { console.log('logged'); }).catch(err => { @@ -23,11 +23,11 @@ router.post('/', authorize("POST_organizationProfile"), validateOrganizationProf res.status(201).send("Organization Profile created successfully!!") }).catch(err => { log({ - userId: res.locals.organizationAdmin.id, - userName: res.locals.organizationAdmin.name, - userType: 'admin' as NSLogs.userType, + userId: res.locals.organizationAdmin?.id, + userName: res.locals.organizationAdmin?.name, + userType: 'root' as NSLogs.userType, type: 'failed' as NSLogs.Type, - request: 'Create Organization Profile' + request: 'Create Organization Profile ' + req.body.name }).then(() => { console.log('logged'); }).catch(err => { @@ -47,7 +47,7 @@ router.delete('/:id', validateOrgId, authorize("DELETE_organizationProfile"), as userName: res.locals.organizationAdmin?.name, userType: (res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'success' as NSLogs.Type, - request: 'Delete Organization Profile' + request: 'Delete Organization Profile with id: ' + id }).then(() => { console.log('logged'); }).catch(err => { @@ -61,7 +61,7 @@ router.delete('/:id', validateOrgId, authorize("DELETE_organizationProfile"), as userName: res.locals.organizationAdmin?.name, userType: (res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'failed' as NSLogs.Type, - request: 'Delete Organization Profile' + request: 'Delete Organization Profile with id: ' + id }).then(() => { console.log('logged'); }).catch(err => { @@ -74,11 +74,11 @@ router.delete('/:id', validateOrgId, authorize("DELETE_organizationProfile"), as router.put("/:id", validateOrgId, authorize("PUT_organizationProfile"), async (req, res, next) => { editOrganizationProfile(req.body).then(() => { log({ - userId: res.locals.organizationAdmin.id, - userName: res.locals.organizationAdmin.name, + userId: res.locals.organizationAdmin?.id, + userName: res.locals.organizationAdmin?.name, userType: (res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'success' as NSLogs.Type, - request: 'Edit Organization Profile' + request: 'Edit Organization Profile with id: ' + req.params.id }).then(() => { console.log('logged'); }).catch(err => { @@ -87,11 +87,11 @@ router.put("/:id", validateOrgId, authorize("PUT_organizationProfile"), async (r res.status(201).send("Organization Profile edited successfully!!") }).catch(err => { log({ - userId: res.locals.organizationAdmin.id, - userName: res.locals.organizationAdmin.name, + userId: res.locals.organizationAdmin?.id, + userName: res.locals.organizationAdmin?.name, userType: (res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'failed' as NSLogs.Type, - request: 'Edit Organization Profile' + request: 'Edit Organization Profile with id: ' + req.params.id }).then(() => { console.log('logged'); }).catch(err => { @@ -114,8 +114,8 @@ router.get('/', authorize("GET_organizationProfiles"), async (req, res, next) => .then(data => { log({ userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, - userName: res.locals.organizationAdmin.name || res.locals.volunteer?.name, - userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, + userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'success' as NSLogs.Type, request: 'Get Organization Profiles' }).then(() => { @@ -128,8 +128,8 @@ router.get('/', authorize("GET_organizationProfiles"), async (req, res, next) => .catch(err => { log({ userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, - userName: res.locals.organizationAdmin.name || res.locals.volunteer?.name, - userType: (res.locals.volunteer?.type ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, + userType: (res.locals.volunteer?.type ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'failed' as NSLogs.Type, request: 'Get Organization Profiles' }).then(() => { diff --git a/src/routes/permission.ts b/src/routes/permission.ts index 0dbb440b..665c508b 100644 --- a/src/routes/permission.ts +++ b/src/routes/permission.ts @@ -9,26 +9,26 @@ var router = express.Router(); router.post('/', authorize("POST_permission"), validatePermission, (req, res, next) => { createPermission(req.body).then((data) => { - + log({ userId: res.locals.organizationAdmin?.id, userName: res.locals.organizationAdmin?.name, userType: 'root' as NSLogs.userType, type: 'success' as NSLogs.Type, - request: 'Create Permission' + request: 'Create Permission ' + req.body.name }).then(() => { console.log('logged'); }).catch(err => { console.log('NOT logged'); - }) + }) res.status(201).send("Permission created successfully!!") }).catch(err => { log({ - userId: res.locals.organizationAdmin.id, - userName: res.locals.organizationAdmin.name, + userId: res.locals.organizationAdmin?.id, + userName: res.locals.organizationAdmin?.name, userType: 'root' as NSLogs.userType, type: 'failed' as NSLogs.Type, - request: 'Create Permission' + request: 'Create Permission ' + req.body.name }).then(() => { console.log('logged'); }).catch(err => { @@ -48,7 +48,7 @@ router.delete('/:id', validatePermissionId, authorize("DELETE_permission"), asyn userName: res.locals.organizationAdmin?.name, userType: 'root' as NSLogs.userType, type: 'success' as NSLogs.Type, - request: 'Delete Permission' + request: 'Delete Permission with id: ' + id }).then(() => { console.log('logged'); }).catch(err => { @@ -62,7 +62,7 @@ router.delete('/:id', validatePermissionId, authorize("DELETE_permission"), asyn userName: res.locals.organizationAdmin?.name, userType: 'root' as NSLogs.userType, type: 'failed' as NSLogs.Type, - request: 'Delete Permission' + request: 'Delete Permission with id: ' + id }).then(() => { console.log('logged'); }).catch(err => { @@ -79,7 +79,7 @@ router.put("/:id", authorize("PUT_permission"), validatePermissionId, async (req userName: res.locals.organizationAdmin?.name, userType: 'root' as NSLogs.userType, type: 'success' as NSLogs.Type, - request: 'Edit Permission' + request: 'Edit Permission with id: ' + req.params.id }).then(() => { console.log('logged'); }).catch(err => { @@ -92,7 +92,7 @@ router.put("/:id", authorize("PUT_permission"), validatePermissionId, async (req userName: res.locals.organizationAdmin?.name, userType: 'root' as NSLogs.userType, type: 'failed' as NSLogs.Type, - request: 'Edit Permission' + request: 'Edit Permission with id: ' + req.params.id }).then(() => { console.log('logged'); }).catch(err => { @@ -117,7 +117,7 @@ router.get('/', authorize("GET_permissions"), async (req, res, next) => { userName: res.locals.organizationAdmin?.name, userType: 'root' as NSLogs.userType, type: 'success' as NSLogs.Type, - request: 'Get Permissions' + request: 'Get Permission/s' }).then(() => { console.log('logged'); }).catch(err => { @@ -131,7 +131,7 @@ router.get('/', authorize("GET_permissions"), async (req, res, next) => { userName: res.locals.organizationAdmin?.name, userType: 'root' as NSLogs.userType, type: 'failed' as NSLogs.Type, - request: 'Get Permissions' + request: 'Get Permission/s' }).then(() => { console.log('logged'); }).catch(err => { diff --git a/src/routes/role.ts b/src/routes/role.ts index 6e695e17..9c375e7e 100644 --- a/src/routes/role.ts +++ b/src/routes/role.ts @@ -11,11 +11,11 @@ var router = express.Router(); router.post('/', authorize("POST_role"), validateRole, (req, res, next) => { createRole(req.body).then(() => { log({ - userId: res.locals.organizationAdmin.id, - userName: res.locals.organizationAdmin.name, + userId: res.locals.organizationAdmin?.id, + userName: res.locals.organizationAdmin?.name, userType: 'root' as NSLogs.userType, type: 'success' as NSLogs.Type, - request: 'Create Role' + request: 'Create Role ' + req.body.name }).then(() => { console.log('logged'); }).catch(err => { @@ -24,11 +24,11 @@ router.post('/', authorize("POST_role"), validateRole, (req, res, next) => { res.status(201).send("Role created successfully!!") }).catch(err => { log({ - userId: res.locals.organizationAdmin.id, - userName: res.locals.organizationAdmin.name, + userId: res.locals.organizationAdmin?.id, + userName: res.locals.organizationAdmin?.name, userType: 'root' as NSLogs.userType, type: 'failed' as NSLogs.Type, - request: 'Create Role' + request: 'Create Role ' + req.body.name }).then(() => { console.log('logged'); }).catch(err => { @@ -44,11 +44,11 @@ router.delete('/:id', validateRoleId, authorize("DELETE_role"), async (req, res, deleteRole(id) .then(data => { log({ - userId: res.locals.organizationAdmin.id, - userName: res.locals.organizationAdmin.name, + userId: res.locals.organizationAdmin?.id, + userName: res.locals.organizationAdmin?.name, userType: 'root' as NSLogs.userType, type: 'success' as NSLogs.Type, - request: 'Delete Role' + request: 'Delete Role with id: ' + id }).then(() => { console.log('logged'); }).catch(err => { @@ -58,11 +58,11 @@ router.delete('/:id', validateRoleId, authorize("DELETE_role"), async (req, res, }) .catch(err => { log({ - userId: res.locals.organizationAdmin.id, - userName: res.locals.organizationAdmin.name, + userId: res.locals.organizationAdmin?.id, + userName: res.locals.organizationAdmin?.name, userType: 'root' as NSLogs.userType, type: 'failed' as NSLogs.Type, - request: 'Delete Role' + request: 'Delete Role with id: ' + id }).then(() => { console.log('logged'); }).catch(err => { @@ -75,11 +75,11 @@ router.delete('/:id', validateRoleId, authorize("DELETE_role"), async (req, res, router.put("/:id", authorize("PUT_role"), validateEditedRole, async (req, res, next) => { editRole({ ...req.body, id: req.params.id?.toString() }).then(() => { log({ - userId: res.locals.organizationAdmin.id, - userName: res.locals.organizationAdmin.name, + userId: res.locals.organizationAdmin?.id, + userName: res.locals.organizationAdmin?.name, userType: 'root' as NSLogs.userType, type: 'success' as NSLogs.Type, - request: 'Edit Role' + request: 'Edit Role with id: ' + req.params.id }).then(() => { console.log('logged'); }).catch(err => { @@ -88,11 +88,11 @@ router.put("/:id", authorize("PUT_role"), validateEditedRole, async (req, res, n res.status(201).send("Role edited successfully!!") }).catch(err => { log({ - userId: res.locals.organizationAdmin.id, - userName: res.locals.organizationAdmin.name, + userId: res.locals.organizationAdmin?.id, + userName: res.locals.organizationAdmin?.name, userType: 'root' as NSLogs.userType, type: 'failed' as NSLogs.Type, - request: 'Edit Role' + request: 'Edit Role with id: ' + req.params.id }).then(() => { console.log('logged'); }).catch(err => { @@ -113,11 +113,11 @@ router.get('/', authorize("GET_roles"), async (req, res, next) => { getRoles(payload) .then(data => { log({ - userId: res.locals.organizationAdmin.id, - userName: res.locals.organizationAdmin.name, + userId: res.locals.organizationAdmin?.id, + userName: res.locals.organizationAdmin?.name, userType: 'root' as NSLogs.userType, type: 'success' as NSLogs.Type, - request: 'Get Roles' + request: 'Get Role/s' }).then(() => { console.log('logged'); }).catch(err => { @@ -131,7 +131,7 @@ router.get('/', authorize("GET_roles"), async (req, res, next) => { userName: res.locals.organizationAdmin.name, userType: 'root' as NSLogs.userType, type: 'failed' as NSLogs.Type, - request: 'Get Roles' + request: 'Get Role/s' }).then(() => { console.log('logged'); }).catch(err => { diff --git a/src/routes/voluntaryWork.ts b/src/routes/voluntaryWork.ts index 7c49d61f..f8efd87e 100644 --- a/src/routes/voluntaryWork.ts +++ b/src/routes/voluntaryWork.ts @@ -18,7 +18,7 @@ router.post('/', authorize("POST_voluntaryWork"), validateVoluntaryWork, (req, r userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'success' as NSLogs.Type, - request: 'Create Voluntary Work' + request: 'Create Voluntary Work ' + req.body.name }).then(() => { console.log('logged'); }).catch(err => { @@ -30,7 +30,7 @@ router.post('/', authorize("POST_voluntaryWork"), validateVoluntaryWork, (req, r userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'failed' as NSLogs.Type, - request: 'Create Voluntary Work' + request: 'Create Voluntary Work ' + req.body.name }).then(() => { console.log('logged'); }).catch(err => { @@ -50,7 +50,7 @@ router.delete('/:id', validateVoluntaryWorkId, authorize("DELETE_voluntaryWork") userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'success' as NSLogs.Type, - request: 'Delete Voluntary Work' + request: 'Delete Voluntary Work with id: ' + id }).then(() => { console.log('logged'); }).catch(err => { @@ -64,7 +64,7 @@ router.delete('/:id', validateVoluntaryWorkId, authorize("DELETE_voluntaryWork") userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'failed' as NSLogs.Type, - request: 'Delete Voluntary Work' + request: 'Delete Voluntary Work with id: ' + id }).then(() => { console.log('logged'); }).catch(err => { @@ -81,7 +81,7 @@ router.put("/:id", authorize("PUT_voluntaryWork"), validateEditedVoluntaryWork, userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'success' as NSLogs.Type, - request: 'Edit Voluntary Work' + request: 'Edit Voluntary Work with id: ' + req.params.id }).then(() => { console.log('logged'); }).catch(err => { @@ -94,7 +94,7 @@ router.put("/:id", authorize("PUT_voluntaryWork"), validateEditedVoluntaryWork, userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'failed' as NSLogs.Type, - request: 'Edit Voluntary Work' + request: 'Edit Voluntary Work with id: ' + req.params.id }).then(() => { console.log('logged'); }).catch(err => { @@ -147,7 +147,7 @@ router.get('/', authorize("GET_voluntaryWorks"), async (req, res, next) => { .catch(err => { log({ userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, - userName: res.locals.organizationAdmin.name, + userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'failed' as NSLogs.Type, request: 'Get Voluntary Work/s' @@ -192,7 +192,7 @@ router.get('/analysis', authorize("GET_analysis"), async (req, res, next) => { userName: res.locals.organizationAdmin?.name, userType: 'root' as NSLogs.userType, type: 'success' as NSLogs.Type, - request: 'Analysis Voluntary Works' + request: 'Analysis Voluntary Work/s' }).then(() => { console.log('logged'); }).catch(err => { @@ -206,7 +206,7 @@ router.get('/analysis', authorize("GET_analysis"), async (req, res, next) => { userName: res.locals.organizationAdmin?.name, userType: "root" as NSLogs.userType, type: 'failed' as NSLogs.Type, - request: 'Analysis Voluntary Works' + request: 'Analysis Voluntary Work/s' }).then(() => { console.log('logged'); }).catch(err => { @@ -237,7 +237,7 @@ router.get('/recommendation', authorize("GET_recommendation"), async (req, res, log({ userId: res.locals.volunteer?.id, userName: res.locals.volunteer?.name, - userType: res.locals.volunteer?.type as NSLogs.userType, + userType: res.locals.volunteer?.type as NSLogs.userType, type: 'failed' as NSLogs.Type, request: 'Get recommendation' }).then(() => { @@ -256,7 +256,7 @@ router.put("/rating/:id", validateVoluntaryWorkId, authorize("PUT_rating"), chec userName: res.locals.volunteer?.name, userType: res.locals.volunteer?.type as NSLogs.userType, type: 'success' as NSLogs.Type, - request: 'Add Rating' + request: 'Add Rating to voluntary work with id' + req.params.id }).then(() => { console.log('logged'); }).catch(err => { @@ -269,7 +269,7 @@ router.put("/rating/:id", validateVoluntaryWorkId, authorize("PUT_rating"), chec userName: res.locals.volunteer?.name, userType: res.locals.volunteer?.type as NSLogs.userType, type: 'failed' as NSLogs.Type, - request: 'Add Rating' + request: 'Add Rating to voluntary work with id' + req.params.id }).then(() => { console.log('logged'); }).catch(err => { @@ -286,7 +286,7 @@ router.put("/feedback/:id", validateVoluntaryWorkId, authorize("PUT_feedback"), userName: res.locals.volunteer?.name, userType: res.locals.volunteer?.type as NSLogs.userType, type: 'success' as NSLogs.Type, - request: 'Add feedback' + request: 'Add feedback to voluntary work with id' + req.params.id }).then(() => { console.log('logged'); }).catch(err => { @@ -299,7 +299,7 @@ router.put("/feedback/:id", validateVoluntaryWorkId, authorize("PUT_feedback"), userName: res.locals.organizationAdmin?.name, userType: res.locals.volunteer?.type as NSLogs.userType, type: 'failed' as NSLogs.Type, - request: 'Add feedback' + request: 'Add feedback to voluntary work with id' + req.params.id }).then(() => { console.log('logged'); }).catch(err => { @@ -314,9 +314,9 @@ router.put("/images/:id", validateVoluntaryWorkId, authorize("PUT_images"), asyn log({ userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, - userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'success' as NSLogs.Type, - request: 'Add images' + request: 'Add images to voluntary work with id' + req.params.id }).then(() => { console.log('logged'); }).catch(err => { @@ -327,9 +327,9 @@ router.put("/images/:id", validateVoluntaryWorkId, authorize("PUT_images"), asyn log({ userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, - userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'failed' as NSLogs.Type, - request: 'Add images' + request: 'Add images to voluntary work with id' + req.params.id }).then(() => { console.log('logged'); }).catch(err => { @@ -341,13 +341,13 @@ router.put("/images/:id", validateVoluntaryWorkId, authorize("PUT_images"), asyn router.put("/register/:id", validateVoluntaryWorkId, authorize("REGISTER_voluntaryWork"), async (req, res, next) => { if (res.locals.volunteer) { - registerByVolunteer(Number(req.params.id), res.locals.volunteer.volunteerProfile).then(() => { + registerByVolunteer(Number(req.params.id), res.locals.volunteer?.volunteerProfile).then(() => { log({ userId: res.locals.volunteer?.id, userName: res.locals.volunteer?.name, - userType: res.locals.volunteer?.type as NSLogs.userType, + userType: res.locals.volunteer?.type as NSLogs.userType, type: 'success' as NSLogs.Type, - request: 'Register voluntary work' + request: 'Register to voluntary work with id' + req.params.id }).then(() => { console.log('logged'); }).catch(err => { @@ -358,9 +358,9 @@ router.put("/register/:id", validateVoluntaryWorkId, authorize("REGISTER_volunta log({ userId: res.locals.volunteer?.id, userName: res.locals.volunteer?.name, - userType: res.locals.volunteer?.type as NSLogs.userType, + userType: res.locals.volunteer?.type as NSLogs.userType, type: 'failed' as NSLogs.Type, - request: 'Register voluntary work' + request: 'Register to voluntary work with id' + req.params.id }).then(() => { console.log('logged'); }).catch(err => { @@ -378,7 +378,7 @@ router.put("/register/:id", validateVoluntaryWorkId, authorize("REGISTER_volunta userName: res.locals.organizationAdmin?.name, userType: (res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'success' as NSLogs.Type, - request: 'Register By Organization Admin' + request: 'Register By Organization Admin to voluntary work with id' + req.params.id + " volunteer id: " + req.body.volunteerId.toString() }).then(() => { console.log('logged'); }).catch(err => { @@ -391,7 +391,7 @@ router.put("/register/:id", validateVoluntaryWorkId, authorize("REGISTER_volunta userName: res.locals.organizationAdmin?.name, userType: (res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'failed' as NSLogs.Type, - request: 'Register By Organization Admin' + request: 'Register By Organization Admin to voluntary work with id' + req.params.id + " volunteer id: " + req.body.volunteerId.toString() }).then(() => { console.log('logged'); }).catch(err => { @@ -407,9 +407,9 @@ router.put("/deregister/:id", validateVoluntaryWorkId, authorize("DEREGISTER_vol log({ userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, - userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'success' as NSLogs.Type, - request: 'Deregister voluntary work' + request: 'Deregister to voluntary work with id' + req.params.id + " volunteer id: " + res.locals.volunteer?.id || req.body.volunteerId.toString() }).then(() => { console.log('logged'); }).catch(err => { @@ -419,10 +419,10 @@ router.put("/deregister/:id", validateVoluntaryWorkId, authorize("DEREGISTER_vol }).catch(err => { log({ userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, - userName: res.locals.organizationAdmin.name || res.locals.volunteer?.name, - userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, + userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'failed' as NSLogs.Type, - request: 'Deregister voluntary work' + request: 'Deregister to voluntary work with id' + req.params.id + " volunteer id: " + res.locals.volunteer?.id || req.body.volunteerId.toString() }).then(() => { console.log('logged'); }).catch(err => { diff --git a/src/routes/volunteer.ts b/src/routes/volunteer.ts index 37a3561f..ba3a1213 100644 --- a/src/routes/volunteer.ts +++ b/src/routes/volunteer.ts @@ -16,7 +16,7 @@ router.post('/register', validateVolunteer, (req, res, next) => { userName: req.body.name, userType: req.body.type as NSLogs.userType, type: 'success' as NSLogs.Type, - request: 'Register volunteer' + request: 'Register volunteer ' + req.body.name }).then(() => { console.log('logged'); }).catch(err => { @@ -29,7 +29,7 @@ router.post('/register', validateVolunteer, (req, res, next) => { userName: req.body.name, userType: req.body.type as NSLogs.userType, type: 'failed' as NSLogs.Type, - request: 'Register volunteer' + request: 'Register volunteer' + req.body.name }).then(() => { console.log('logged'); }).catch(err => { @@ -55,7 +55,7 @@ router.post('/login', (req, res, next) => { userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'success' as NSLogs.Type, - request: 'Login' + request: 'Login ' + res.locals.organizationAdmin?.name || res.locals.volunteer?.name }).then(() => { console.log('logged'); }).catch(err => { @@ -69,7 +69,7 @@ router.post('/login', (req, res, next) => { userName: req.body.name, userType: 'volunteer' as NSLogs.userType, type: 'failed' as NSLogs.Type, - request: 'Login' + request: 'Login' + res.locals.organizationAdmin?.name || res.locals.volunteer?.name }).then(() => { console.log('logged'); }).catch(err => { @@ -89,7 +89,7 @@ router.delete('/:id', authenticate, authorize("DELETE_volunteer"), async (req, r userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'success' as NSLogs.Type, - request: 'Delete Volunteer' + request: 'Delete Volunteer with id: ' + id }).then(() => { console.log('logged'); }).catch(err => { @@ -103,7 +103,7 @@ router.delete('/:id', authenticate, authorize("DELETE_volunteer"), async (req, r userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'failed' as NSLogs.Type, - request: 'Delete Volunteer' + request: 'Delete Volunteer with id: ' + id }).then(() => { console.log('logged'); }).catch(err => { @@ -120,7 +120,7 @@ router.put("/:id", authenticate, authorize("PUT_volunteer"), validateEditedVolun userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'success' as NSLogs.Type, - request: 'Edit Volunteer' + request: 'Edit Volunteer with id: ' + req.params.id?.toString() }).then(() => { console.log('logged'); }).catch(err => { @@ -133,7 +133,7 @@ router.put("/:id", authenticate, authorize("PUT_volunteer"), validateEditedVolun userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'failed' as NSLogs.Type, - request: 'Edit Volunteer' + request: 'Edit Volunteer with id: ' + req.params.id?.toString() }).then(() => { console.log('logged'); }).catch(err => { @@ -201,7 +201,7 @@ router.get("/logout", authenticate, (req, res, next) => { userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'success' as NSLogs.Type, - request: 'Logout' + request: 'Logout ' + res.locals.organizationAdmin?.name || res.locals.volunteer?.name }).then(() => { console.log('logged'); }).catch(err => { From 1e63faaf14c7061868c6572e4fc535f5f8639f89 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Mon, 9 Oct 2023 12:04:14 +0300 Subject: [PATCH 098/146] Adding loging to failed authurization --- src/middleware/auth/authorize.ts | 123 +++++++++++++++++++++++++++++-- 1 file changed, 117 insertions(+), 6 deletions(-) diff --git a/src/middleware/auth/authorize.ts b/src/middleware/auth/authorize.ts index e25cf5c9..b63de56d 100644 --- a/src/middleware/auth/authorize.ts +++ b/src/middleware/auth/authorize.ts @@ -4,6 +4,8 @@ import { OrganizationAdmin } from '../../db/entities/OrganizationAdmin.js'; import { Volunteer } from '../../db/entities/Volunteer.js'; import { VoluntaryWork } from '../../db/entities/VoluntaryWork.js'; import createError from 'http-errors'; +import { log } from '../../controllers/logs.js'; +import { NSLogs } from '../../../types/logs.js'; const authorize = (api: string) => { return async ( @@ -33,13 +35,33 @@ const authorize = (api: string) => { checkMe(req, res, next); } else if ((/voluntaryWork$/.test(api)) || ((/images/.test(api)))) { checkCreator(req, res, next); - }else { - res.status(403).send("You don't have the permission to access this resource!"); + } else { + log({ + userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, + userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'failed' as NSLogs.Type, + request: 'Authorization failed to ' + api + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) + next(createError(401)); } } else { - - - res.status(403).send("You don't have the permission to access this resource!"); + log({ + userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, + userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'failed' as NSLogs.Type, + request: 'Authorization failed to ' + api + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) + next(createError(401)); } } } @@ -50,11 +72,35 @@ const checkMe = (req: express.Request, res: express.Response, next: express.Next if (res.locals.volunteer) { if (res.locals.volunteer.id == id) { next(); + } else { + log({ + userId: res.locals.volunteer?.id, + userName: res.locals.volunteer?.name, + userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'failed' as NSLogs.Type, + request: 'Authorization failed' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) + next(createError(401)); } } else if (res.locals.organizationAdmin) { if (res.locals.organizationAdmin.id == id) { next(); } else { + log({ + userId: res.locals.volunteer?.id, + userName: res.locals.volunteer?.name, + userType: (res.locals.volunteer?.type) as NSLogs.userType, + type: 'failed' as NSLogs.Type, + request: 'Authorization failed' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(createError(401)); } } @@ -69,9 +115,31 @@ const checkAdmin = async (req: express.Request, res: express.Response, next: exp if (res.locals.organizationAdmin.id == admin?.id) { next(); } else { + log({ + userId: res.locals.organizationAdmin?.id, + userName: res.locals.organizationAdmin?.name, + userType: (res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'failed' as NSLogs.Type, + request: 'Authorization failed' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(createError(401)); } } else { + log({ + userId: res.locals.organizationAdmin?.id, + userName: res.locals.organizationAdmin?.name, + userType: (res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'failed' as NSLogs.Type, + request: 'Authorization failed' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(createError(401)); } } @@ -85,16 +153,37 @@ const checkCreator = async (req: express.Request, res: express.Response, next: e if (res.locals.organizationAdmin.id == voluntaryWork?.creatorId) { next(); } else { + log({ + userId: res.locals.organizationAdmin?.id, + userName: res.locals.organizationAdmin?.name, + userType: (res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'failed' as NSLogs.Type, + request: 'Authorization failed' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(createError(401)); } } else if (res.locals.volunteer) { if (res.locals.volunteer?.id == voluntaryWork?.creatorId) { next(); } else { + log({ + userId: res.locals.volunteer?.id, + userName: res.locals.volunteer?.name, + userType: (res.locals.volunteer?.type) as NSLogs.userType, + type: 'failed' as NSLogs.Type, + request: 'Authorization failed' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(createError(401)); } } else { - next(createError(401)); } } @@ -119,6 +208,17 @@ const checkParticipation = async (req: express.Request, res: express.Response, n if (isParticipating) { next(); } else { + log({ + userId: res.locals.volunteer?.id, + userName: res.locals.volunteer?.name, + userType: (res.locals.volunteer?.type) as NSLogs.userType, + type: 'failed' as NSLogs.Type, + request: 'Authorization failed' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(createError(401)); } } else { @@ -128,6 +228,17 @@ const checkParticipation = async (req: express.Request, res: express.Response, n next(createError(401)); // Handle the case when volunteerProfile is not defined } } else { + log({ + userId: res.locals.organizationAdmin?.id ||res.locals.volunteer?.id, + userName:res.locals.organizationAdmin?.name || res.locals.volunteer?.name, + userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'failed' as NSLogs.Type, + request: 'Authorization failed' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(createError(401)); // Handle the case when res.locals.volunteer is not defined } }; From e20df5dd3dd2b33537cf9f6891577086915886c7 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Mon, 9 Oct 2023 12:11:02 +0300 Subject: [PATCH 099/146] Adding logging for failed authunication --- src/middleware/auth/authenticate.ts | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/src/middleware/auth/authenticate.ts b/src/middleware/auth/authenticate.ts index 60e32be1..b66375bd 100644 --- a/src/middleware/auth/authenticate.ts +++ b/src/middleware/auth/authenticate.ts @@ -3,6 +3,8 @@ import jwt, { JwtPayload } from 'jsonwebtoken'; import { OrganizationAdmin } from '../../db/entities/OrganizationAdmin.js'; import { Volunteer } from '../../db/entities/Volunteer.js'; import createError from 'http-errors'; +import { NSLogs } from '../../../types/logs.js'; +import { log } from '../../controllers/logs.js'; const authenticate = async ( req: express.Request, @@ -42,16 +44,36 @@ const authenticate = async ( res.locals.volunteer = volunteer; res.cookie('name', res.locals.volunteer.name, { httpOnly: true, - maxAge: 60 * 24* 60 * 1000, + maxAge: 60 * 24 * 60 * 1000, sameSite: "lax" // Protect against CSRF attacks }); next(); } else { - //res.status(401).send("You are Unauthorized!"); + log({ + userId: "", + userName: "", + userType: "" as NSLogs.userType, + type: 'failed' as NSLogs.Type, + request: 'Authorization failed' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(createError(401)); } } else { - //res.status(401).send("You are Unauthorized!"); + log({ + userId: "", + userName: "", + userType: "" as NSLogs.userType, + type: 'failed' as NSLogs.Type, + request: 'Authorization failed' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(createError(401)); } } From 701df439abc4c74abfa509bd858994cc4cc4b18a Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Mon, 9 Oct 2023 12:52:24 +0300 Subject: [PATCH 100/146] Creat logger for failed validation --- .../validation/organizationAdmin.ts | 48 ++++++++++++++- .../validation/organizationProfile.ts | 29 +++++++++- src/middleware/validation/permission.ts | 35 +++++++++-- src/middleware/validation/role.ts | 58 ++++++++++++++++--- src/middleware/validation/voluntaryWork.ts | 48 ++++++++++++++- src/middleware/validation/volunteer.ts | 49 +++++++++++++++- 6 files changed, 245 insertions(+), 22 deletions(-) diff --git a/src/middleware/validation/organizationAdmin.ts b/src/middleware/validation/organizationAdmin.ts index 9de9c7ec..2964926a 100644 --- a/src/middleware/validation/organizationAdmin.ts +++ b/src/middleware/validation/organizationAdmin.ts @@ -3,6 +3,8 @@ import * as EmailValidator from 'email-validator'; import { isValidPassword } from '../../controllers/index.js'; import { OrganizationAdmin } from '../../db/entities/OrganizationAdmin.js'; import createError from 'http-errors'; +import { NSLogs } from '../../../types/logs.js'; +import { log } from '../../controllers/logs.js'; const validateOrganizationAdmin = (req: express.Request, @@ -20,6 +22,17 @@ const validateOrganizationAdmin = (req: express.Request, errorList.push(...isValidPassword(organizationAdmin.password)); if (errorList.length) { + log({ + userId: res.locals.organizationAdmin?.id, + userName: res.locals.organizationAdmin?.name, + userType: (res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'failed' as NSLogs.Type, + request: 'Bad Organization Admin Request' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.status(400).send(errorList); } else { next(); @@ -36,7 +49,17 @@ const validateAdminEdited = async (req: express.Request, const id = req.params.id.toString(); const v = await OrganizationAdmin.findOne({ where: { id } }); if (!v) { - //res.status(400).send("Id not valid"); + log({ + userId: res.locals.organizationAdmin?.id, + userName: res.locals.organizationAdmin?.name, + userType: (res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'failed' as NSLogs.Type, + request: 'Bad Organization Admin Request' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(createError(404)); } @@ -49,6 +72,17 @@ const validateAdminEdited = async (req: express.Request, errorList.push(...isValidPassword(organizationAdmin.password)); if (errorList.length) { + log({ + userId: res.locals.organizationAdmin?.id, + userName: res.locals.organizationAdmin?.name, + userType: (res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'failed' as NSLogs.Type, + request: 'Bad Organization Admin Request' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.status(400).send(errorList); } else { next(); @@ -62,7 +96,17 @@ const validateAdminId = async (req: express.Request, const id = req.params.id.toString(); const p = await OrganizationAdmin.findOne({ where: { id } }); if (!p) { - //res.status(400).send("Id not valid"); + log({ + userId: res.locals.organizationAdmin?.id, + userName: res.locals.organizationAdmin?.name, + userType: (res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'failed' as NSLogs.Type, + request: 'Bad Organization Admin Request' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(createError(404)); } else { next(); diff --git a/src/middleware/validation/organizationProfile.ts b/src/middleware/validation/organizationProfile.ts index 7e227350..2af1d717 100644 --- a/src/middleware/validation/organizationProfile.ts +++ b/src/middleware/validation/organizationProfile.ts @@ -1,6 +1,8 @@ import express from 'express'; import { OrganizationProfile } from '../../db/entities/OrganizationProfile.js'; import createError from 'http-errors'; +import { NSLogs } from '../../../types/logs.js'; +import { log } from '../../controllers/logs.js'; const validateOrganizationProfile = (req: express.Request, res: express.Response, @@ -9,8 +11,19 @@ const validateOrganizationProfile = (req: express.Request, const values = ["name", "description"]; const organizationProfile = req.body; const errorList = values.map(key => !organizationProfile[key] && `${key} is Required!`).filter(Boolean); - + if (errorList.length) { + log({ + userId: res.locals.organizationAdmin?.id, + userName: res.locals.organizationAdmin?.name, + userType: (res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'failed' as NSLogs.Type, + request: 'Bad Organization Profile Request' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.status(400).send(errorList); } else { next(); @@ -24,9 +37,19 @@ const validateOrgId = async (req: express.Request, const id = req.params.id.toString(); const v = await OrganizationProfile.findOne({ where: { id } }); if (!v) { - //res.status(400).send("Id not valid"); + log({ + userId: res.locals.organizationAdmin?.id, + userName: res.locals.organizationAdmin?.name, + userType: (res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'failed' as NSLogs.Type, + request: 'Bad Organization Profile Request' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(createError(404)); - }else{ + } else { next(); } } diff --git a/src/middleware/validation/permission.ts b/src/middleware/validation/permission.ts index ca9b07f9..ae426885 100644 --- a/src/middleware/validation/permission.ts +++ b/src/middleware/validation/permission.ts @@ -1,6 +1,8 @@ import express from 'express'; import { Permission } from '../../db/entities/Permission.js'; import createError from 'http-errors'; +import { NSLogs } from '../../../types/logs.js'; +import { log } from '../../controllers/logs.js'; const validatePermission = (req: express.Request, res: express.Response, @@ -11,6 +13,17 @@ const validatePermission = (req: express.Request, const errorList = values.map(key => !permission[key] && `${key} is Required!`).filter(Boolean); if (errorList.length) { + log({ + userId: res.locals.organizationAdmin?.id, + userName: res.locals.organizationAdmin?.name, + userType: (res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'failed' as NSLogs.Type, + request: 'Bad Permission Request' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.status(400).send(errorList); } else { next(); @@ -24,14 +37,24 @@ const validatePermissionId = async (req: express.Request, const id = Number(req.params.id.toString()); const p = await Permission.findOne({ where: { id } }); if (!p) { - //res.status(400).send("Id not valid"); - next(createError(404)); - }else{ - next(); + log({ + userId: res.locals.organizationAdmin?.id, + userName: res.locals.organizationAdmin?.name, + userType: (res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'failed' as NSLogs.Type, + request: 'Invalid Permission id' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) + next(createError(404)); + } else { + next(); } } export { - validatePermission, - validatePermissionId + validatePermission, + validatePermissionId } \ No newline at end of file diff --git a/src/middleware/validation/role.ts b/src/middleware/validation/role.ts index e4355348..fdadd622 100644 --- a/src/middleware/validation/role.ts +++ b/src/middleware/validation/role.ts @@ -1,6 +1,8 @@ import express from 'express'; import { Role } from '../../db/entities/Role.js'; import createError from 'http-errors'; +import { NSLogs } from '../../../types/logs.js'; +import { log } from '../../controllers/logs.js'; const validateRole = (req: express.Request, res: express.Response, @@ -15,6 +17,17 @@ const validateRole = (req: express.Request, } if (errorList.length) { + log({ + userId: res.locals.organizationAdmin?.id, + userName: res.locals.organizationAdmin?.name, + userType: (res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'failed' as NSLogs.Type, + request: 'Bad Role Request' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.status(400).send(errorList); } else { next(); @@ -31,17 +44,38 @@ const validateEditedRole = async (req: express.Request, const id = Number(req.params.id.toString()); const r = await Role.findOne({ where: { id } }); if (!r) { - //res.status(400).send("Id not valid"); + log({ + userId: res.locals.organizationAdmin?.id, + userName: res.locals.organizationAdmin?.name, + userType: (res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'failed' as NSLogs.Type, + request: 'Invalid Role id' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(createError(404)); } - if (role.name){ + if (role.name) { if (!['root', 'admin', 'volunteer', 'premium'].includes(role.name)) { errorList.push('role name unknown!'); } } if (errorList.length) { + log({ + userId: res.locals.organizationAdmin?.id, + userName: res.locals.organizationAdmin?.name, + userType: (res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'failed' as NSLogs.Type, + request: 'Bad Role Request' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.status(400).send(errorList); } else { next(); @@ -50,17 +84,27 @@ const validateEditedRole = async (req: express.Request, const validateRoleId = async (req: express.Request, res: express.Response, next: express.NextFunction - ) => { +) => { const id = Number(req.params.id.toString()); const p = await Role.findOne({ where: { id } }); if (!p) { - //res.status(400).send("Id not valid"); + log({ + userId: res.locals.organizationAdmin?.id, + userName: res.locals.organizationAdmin?.name, + userType: (res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'failed' as NSLogs.Type, + request: 'Invalid Role id' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(createError(404)); - }else{ + } else { next(); } - } - +} + export { validateRole, diff --git a/src/middleware/validation/voluntaryWork.ts b/src/middleware/validation/voluntaryWork.ts index 02c30b59..214595a9 100644 --- a/src/middleware/validation/voluntaryWork.ts +++ b/src/middleware/validation/voluntaryWork.ts @@ -4,6 +4,8 @@ import { NSVolunteer } from '../../../types/volunteer.js'; import { getDate, isValidDate } from '../../controllers/index.js'; import { VoluntaryWork } from '../../db/entities/VoluntaryWork.js'; import createError from 'http-errors'; +import { NSLogs } from '../../../types/logs.js'; +import { log } from '../../controllers/logs.js'; const validateVoluntaryWork = (req: express.Request, res: express.Response, @@ -39,6 +41,17 @@ const validateVoluntaryWork = (req: express.Request, } if (errorList.length > 0) { + log({ + userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, + userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'failed' as NSLogs.Type, + request: 'Bad Voluntary Work Request' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.status(400).send(errorList); } else { next(); @@ -55,7 +68,17 @@ const validateEditedVoluntaryWork = async (req: express.Request, const id = Number(req.params.id.toString()); const vw = await VoluntaryWork.findOne({ where: { id } }); if (!vw) { - //res.status(400).send("Id not valid"); + log({ + userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, + userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'failed' as NSLogs.Type, + request: 'Invalid Voluntary Work id' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(createError(404)); } @@ -105,6 +128,17 @@ const validateEditedVoluntaryWork = async (req: express.Request, } if (errorList.length) { + log({ + userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, + userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'failed' as NSLogs.Type, + request: 'Bad Voluntary Work Request' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.status(400).send(errorList); } else { next(); @@ -118,7 +152,17 @@ const validateVoluntaryWorkId = async (req: express.Request, const id = Number(req.params.id.toString()); const p = await VoluntaryWork.findOne({ where: { id } }); if (!p) { - //res.status(400).send("Id not valid"); + log({ + userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, + userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'failed' as NSLogs.Type, + request: 'Invalid Voluntary Work id' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(createError(404)); } else { next(); diff --git a/src/middleware/validation/volunteer.ts b/src/middleware/validation/volunteer.ts index 878c6856..0bc7ab0b 100644 --- a/src/middleware/validation/volunteer.ts +++ b/src/middleware/validation/volunteer.ts @@ -4,6 +4,8 @@ import { isValidPassword } from '../../controllers/index.js'; import { NSVolunteer } from '../../../types/volunteer.js'; import { Volunteer } from '../../db/entities/Volunteer.js'; import createError from 'http-errors' +import { NSLogs } from '../../../types/logs.js'; +import { log } from '../../controllers/logs.js'; const validateVolunteer = (req: express.Request, res: express.Response, next: express.NextFunction) => { @@ -42,6 +44,18 @@ const validateVolunteer = (req: express.Request, res: express.Response, next: ex errorList.push(...isValidPassword(volunteer.password)); if (errorList.length) { + log({ + userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, + userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'failed' as NSLogs.Type, + request: 'Bad Volunteer Request' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) + next(createError(400)); res.status(400).send({ errors: errorList }); } else { next(); @@ -55,7 +69,17 @@ const validateEditedVolunteer = async (req: express.Request, res: express.Respon const id = req.params.id.toString(); const v = await Volunteer.findOne({ where: { id } }); if (!v) { - //res.status(400).send("Id not valid"); + log({ + userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, + userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'failed' as NSLogs.Type, + request: 'Invalid Volunteer id' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(createError(404)); } @@ -91,6 +115,17 @@ const validateEditedVolunteer = async (req: express.Request, res: express.Respon } if (errorList.length) { + log({ + userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, + userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'failed' as NSLogs.Type, + request: 'Bad Volunteer Request' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) res.status(400).send({ errors: errorList }); } else { next(); @@ -104,7 +139,17 @@ const validateVolunteerId = async (req: express.Request, const id = (req.params.id.toString()); const p = await Volunteer.findOne({ where: { id } }); if (!p) { - //res.status(400).send("Id not valid"); + log({ + userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, + userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'failed' as NSLogs.Type, + request: 'Invalid Volunteer id' + }).then(() => { + console.log('logged'); + }).catch(err => { + console.log('NOT logged'); + }) next(createError(404)); } else { next(); From bec7ae542274cb4f68c4e90799df5c43eab54033 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Mon, 9 Oct 2023 12:57:57 +0300 Subject: [PATCH 101/146] auth edit --- src/middleware/auth/authenticate.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/middleware/auth/authenticate.ts b/src/middleware/auth/authenticate.ts index b66375bd..1064c3bc 100644 --- a/src/middleware/auth/authenticate.ts +++ b/src/middleware/auth/authenticate.ts @@ -54,7 +54,7 @@ const authenticate = async ( userName: "", userType: "" as NSLogs.userType, type: 'failed' as NSLogs.Type, - request: 'Authorization failed' + request: 'Authentication failed' }).then(() => { console.log('logged'); }).catch(err => { @@ -68,7 +68,7 @@ const authenticate = async ( userName: "", userType: "" as NSLogs.userType, type: 'failed' as NSLogs.Type, - request: 'Authorization failed' + request: 'Authentication failed' }).then(() => { console.log('logged'); }).catch(err => { From 6182bcffd8d262c185380c825e99b4d9202f6db1 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Mon, 9 Oct 2023 15:17:28 +0300 Subject: [PATCH 102/146] Adding the system error logger --- .gitignore | 2 +- logger.ts | 4 +- src/controllers/OrganizationProfile .ts | 96 +++-- src/controllers/organizationAdmin.ts | 191 +++++---- src/controllers/permission.ts | 72 ++-- src/controllers/role.ts | 73 ++-- src/controllers/voluntaryWork.ts | 522 +++++++++++++----------- src/controllers/volunteer.ts | 348 ++++++++-------- 8 files changed, 716 insertions(+), 592 deletions(-) diff --git a/.gitignore b/.gitignore index 65b65a2a..2aacd589 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,4 @@ node_modules dist .env .env.test -logs \ No newline at end of file +logger \ No newline at end of file diff --git a/logger.ts b/logger.ts index cada788c..998bdf21 100644 --- a/logger.ts +++ b/logger.ts @@ -4,8 +4,8 @@ const baseLogger = winston.createLogger({ format: winston.format.json(), defaultMeta: { project: 'serve and shine', time: new Date() }, transports: [ - new winston.transports.File({ filename: 'logs/error.log', level: 'error' }), - //new winston.transports.File({ filename: 'logs/all.log' }), + new winston.transports.File({ filename: 'logger/error.log', level: 'error' }), + //new winston.transports.File({ filename: 'logger/all.log' }), ], }); diff --git a/src/controllers/OrganizationProfile .ts b/src/controllers/OrganizationProfile .ts index 2a755241..21c9ae37 100644 --- a/src/controllers/OrganizationProfile .ts +++ b/src/controllers/OrganizationProfile .ts @@ -1,27 +1,41 @@ +import baseLogger from "../../logger.js"; import { NSOrganizationProfile } from "../../types/organizationProfile.js"; import { OrganizationAdmin } from "../db/entities/OrganizationAdmin.js"; import { OrganizationProfile } from "../db/entities/OrganizationProfile.js"; import createError from 'http-errors'; const createOrganizationProfile = async (payload: NSOrganizationProfile.Item) => { - const newOrganizationProfile = OrganizationProfile.create({ name: payload.name, description: payload.description }); - return newOrganizationProfile.save(); + try { + const newOrganizationProfile = OrganizationProfile.create({ name: payload.name, description: payload.description }); + return newOrganizationProfile.save(); + } catch (err) { + baseLogger.error(err); + throw createError(404,); + } } const editOrganizationProfile = async (payload: { id: string, name: string, description: string }) => { - let profile = await OrganizationProfile.findOne({ where: { id: payload.id } }); + try { + let profile = await OrganizationProfile.findOne({ where: { id: payload.id } }); - if (profile) { + if (profile) { - profile = Object.assign(profile, payload); - return profile.save(); - } else { + profile = Object.assign(profile, payload); + return profile.save(); + } + } catch (err) { + baseLogger.error(err); throw createError(404); } } -const deleteOrganizationProfile = async (profileId: string) => { - return OrganizationProfile.delete(profileId); +const deleteOrganizationProfile = async (profileId: string) => { + try { + return OrganizationProfile.delete(profileId); + } catch (err) { + baseLogger.error(err); + throw createError(404); + } } const getOrganizationProfile = async (payload: { @@ -31,43 +45,47 @@ const getOrganizationProfile = async (payload: { name: string, adminName: string }) => { + try { + const page = parseInt(payload.page); + const pageSize = parseInt(payload.pageSize); - const page = parseInt(payload.page); - const pageSize = parseInt(payload.pageSize); - - if (payload.id) { - return OrganizationProfile.findOne({ where: { id: payload.id } }) - } + if (payload.id) { + return OrganizationProfile.findOne({ where: { id: payload.id } }) + } - if (payload.name) { - return OrganizationProfile.findOne({ where: { name: payload.name } }) - } + if (payload.name) { + return OrganizationProfile.findOne({ where: { name: payload.name } }) + } - if (payload.adminName) { - const admin = await OrganizationAdmin.findOne({ where: { name: payload.adminName } }); + if (payload.adminName) { + const admin = await OrganizationAdmin.findOne({ where: { name: payload.adminName } }); - if (admin) { - return admin; - } else { - throw createError(404); + if (admin) { + return admin; + } else { + throw "Admin not found" + } } - } - const [orgs, total] = await OrganizationProfile.findAndCount({ - skip: pageSize * (page - 1), - take: pageSize, - order: { - createdAt: 'ASC' - }, - select: ["name", "description", "createdAt"] - }) + const [orgs, total] = await OrganizationProfile.findAndCount({ + skip: pageSize * (page - 1), + take: pageSize, + order: { + createdAt: 'ASC' + }, + select: ["name", "description", "createdAt"] + }) - return { - page, - pageSize: orgs.length, - total, - orgs - }; + return { + page, + pageSize: orgs.length, + total, + orgs + }; + } catch (err) { + baseLogger.error(err); + throw createError(404); + } } diff --git a/src/controllers/organizationAdmin.ts b/src/controllers/organizationAdmin.ts index 9786abfa..c223a751 100644 --- a/src/controllers/organizationAdmin.ts +++ b/src/controllers/organizationAdmin.ts @@ -5,24 +5,28 @@ import bcrypt from 'bcrypt'; import createError from 'http-errors'; import { Role } from "../db/entities/Role.js"; import { Not } from "typeorm"; +import baseLogger from "../../logger.js"; const createOrganizationAdmin = async (payload: NSOrganizationAdmin.Item) => { + try { + const newOrganizationAdmin = OrganizationAdmin.create(payload); + const organization = await OrganizationProfile.findOne({ + where: { id: payload.organizationId }, + }); + + const role = await Role.findOne({ where: { name: "admin" } }); + if (role) { + newOrganizationAdmin.roles = role; + } - const newOrganizationAdmin = OrganizationAdmin.create(payload); - - const organization = await OrganizationProfile.findOne({ - where: { id: payload.organizationId }, - }); - - const role = await Role.findOne({ where: { name: "admin" } }); - if (role) { - newOrganizationAdmin.roles = role; - } - - if (organization) { - newOrganizationAdmin.orgProfile = organization; - return newOrganizationAdmin.save(); - } else { + if (organization) { + newOrganizationAdmin.orgProfile = organization; + return newOrganizationAdmin.save(); + } else { + throw "Organization not found"; + } + } catch (err) { + baseLogger.error(err); throw createError(404); } } @@ -38,95 +42,106 @@ const getOrganizationAdmins = async (payload: { const page = parseInt(payload.page); const pageSize = parseInt(payload.pageSize); + try { + if (payload.id) { + return OrganizationAdmin.findOne({ + where: { id: payload.id, name: Not("root") }, + select: ["name", "email", "createdAt"] + }) + } + if (payload.name) { + return OrganizationAdmin.findOne({ + where: { name: payload.name === 'root' ? "" : payload.name }, + select: ["name", "email", "createdAt"] + }) + } + if (payload.email) { + return OrganizationAdmin.findOne({ + where: { email: payload.email, name: Not("root") }, + select: ["name", "email", "createdAt"] + }) + } + if (payload.organizationName) { + + const organization = await OrganizationProfile.findOne({ where: { name: payload.organizationName } }); + if (organization) { + const admin = await OrganizationAdmin.findOne({ where: { orgProfile: { id: organization.id } } }); + return { name: admin?.name, createdAt: admin?.createdAt, email: admin?.email }; + } else { + throw "Organization name not found"; + } + } - if (payload.id) { - return OrganizationAdmin.findOne({ - where: { id: payload.id, name: Not("root") }, - select: ["name", "email", "createdAt"] - }) - } - if (payload.name) { - return OrganizationAdmin.findOne({ - where: { name: payload.name === 'root' ? "" : payload.name }, - select: ["name", "email", "createdAt"] - }) - } - if (payload.email) { - return OrganizationAdmin.findOne({ - where: { email: payload.email, name: Not("root") }, + const [admins, total] = await OrganizationAdmin.findAndCount({ + skip: pageSize * (page - 1), + take: pageSize, + order: { + createdAt: 'ASC' + }, + where: { + name: Not("root") + }, select: ["name", "email", "createdAt"] }) - } - if (payload.organizationName) { - - const organization = await OrganizationProfile.findOne({ where: { name: payload.organizationName } }); - if (organization) { - const admin = await OrganizationAdmin.findOne({ where: { orgProfile: { id: organization.id } } }); - return {name:admin?.name, createdAt:admin?.createdAt, email:admin?.email}; - } else { - throw createError(404); - } + return { + page, + pageSize: admins.length, + total, + admins + }; + } catch (err) { + baseLogger.error(err) + throw createError(404); } - - const [admins, total] = await OrganizationAdmin.findAndCount({ - skip: pageSize * (page - 1), - take: pageSize, - order: { - createdAt: 'ASC' - }, - where: { - name: Not("root") - }, - select: ["name", "email", "createdAt"] - }) - - return { - page, - pageSize: admins.length, - total, - admins - }; } const deleteOrganizationAdmin = async (adminId: string) => { - return OrganizationAdmin.delete(adminId); + try { + return OrganizationAdmin.delete(adminId); + } catch (err) { + baseLogger.error(err); + throw createError(404); + } } const editOrganizationAdmin = async (payload: { id: string, name: string, email: string, newPassword: string, oldPassword: string, organizationName: string }) => { - - const admin = await OrganizationAdmin.findOne({ where: { id: payload.id } }); - - if (admin) { - if (payload.name) - admin.name = payload.name; - - if (payload.email) - admin.email = payload.email; - - if (payload.newPassword) { - if (!payload.oldPassword) { - throw "Old password is needed !"; - } - - const passwordMatching = await bcrypt.compare(payload.oldPassword, admin?.password || ''); - if (passwordMatching) { - admin.password = await bcrypt.hash(payload.newPassword, 10); - } else { - throw "The old password isn't correct !" + try { + const admin = await OrganizationAdmin.findOne({ where: { id: payload.id } }); + if (admin) { + if (payload.name) + admin.name = payload.name; + + if (payload.email) + admin.email = payload.email; + + if (payload.newPassword) { + if (!payload.oldPassword) { + throw "Old password is needed !"; + } + + const passwordMatching = await bcrypt.compare(payload.oldPassword, admin?.password || ''); + if (passwordMatching) { + admin.password = await bcrypt.hash(payload.newPassword, 10); + } else { + throw "The old password isn't correct !" + } } - } - if (payload.organizationName) { + if (payload.organizationName) { - const profile = await OrganizationProfile.findOne({ where: { name: payload.organizationName } }); - if (profile) { - admin.orgProfile = profile; + const profile = await OrganizationProfile.findOne({ where: { name: payload.organizationName } }); + if (profile) { + admin.orgProfile = profile; + } } - } - return admin.save(); + return admin.save(); - } else { + } else { + throw "Organization admin not found"; + } + } catch (err) { + baseLogger.error(err) throw createError(404); } } diff --git a/src/controllers/permission.ts b/src/controllers/permission.ts index f8c4c50f..1e6a3c43 100644 --- a/src/controllers/permission.ts +++ b/src/controllers/permission.ts @@ -1,3 +1,4 @@ +import baseLogger from "../../logger.js"; import { NSPermission } from "../../types/permission.js"; import { Permission } from "../db/entities/Permission.js" import createError from 'http-errors'; @@ -8,23 +9,31 @@ const createPermission = async (payload: NSPermission.Item) => { return newPermission.save(); } catch (error) { - console.log(error); + baseLogger.error(error); + throw createError(404); } } const deletePermission = async (permissionId: number) => { - return Permission.delete(permissionId); - + try { + return Permission.delete(permissionId); + } catch (err) { + baseLogger.error(err); + throw createError(404); + } } const editPermission = async (payload: { name: string, id: number }) => { + try { - const permission = await Permission.findOne({ where: { id: payload.id } }); + const permission = await Permission.findOne({ where: { id: payload.id } }); - if (permission) { - permission.name = payload.name; - return permission.save(); - } else { + if (permission) { + permission.name = payload.name; + return permission.save(); + } + } catch (err) { + baseLogger.error(err); throw createError(404); } } @@ -35,32 +44,37 @@ const getPermissions = async (payload: { id: number, name: string }) => { + try { - const page = parseInt(payload.page); - const pageSize = parseInt(payload.pageSize); - - if (payload.id) { - return Permission.findOne({ where: { id: payload.id } }) - } + const page = parseInt(payload.page); + const pageSize = parseInt(payload.pageSize); - if (payload.name) { - return Permission.findOne({ where: { name: payload.name } }) - } + if (payload.id) { + return Permission.findOne({ where: { id: payload.id } }) + } - const [permissions, total] = await Permission.findAndCount({ - skip: pageSize * (page - 1), - take: pageSize, - order: { - createdAt: 'ASC' + if (payload.name) { + return Permission.findOne({ where: { name: payload.name } }) } - }) - return { - page, - pageSize: permissions.length, - total, - permissions - }; + const [permissions, total] = await Permission.findAndCount({ + skip: pageSize * (page - 1), + take: pageSize, + order: { + createdAt: 'ASC' + } + }) + + return { + page, + pageSize: permissions.length, + total, + permissions + }; + } catch (err) { + baseLogger.error(err); + throw err; + } } export { createPermission, deletePermission, editPermission, getPermissions } \ No newline at end of file diff --git a/src/controllers/role.ts b/src/controllers/role.ts index c14bb3d3..b429f9bb 100644 --- a/src/controllers/role.ts +++ b/src/controllers/role.ts @@ -3,56 +3,65 @@ import { NSRole } from "../../types/role.js"; import { Permission } from "../db/entities/Permission.js"; import { Role } from "../db/entities/Role.js"; import createError from 'http-errors'; +import baseLogger from "../../logger.js"; const createRole = async (payload: NSRole.Item) => { - try { - const newRole = Role.create(payload); - const permissions = await Permission.find({ - where: { id: In(payload.permissionsId) }, - }); - - newRole.permissions =permissions - return newRole.save(); - } - catch (error) { - console.log(error); - } + try { + const newRole = Role.create(payload); + const permissions = await Permission.find({ + where: { id: In(payload.permissionsId) }, + }); + + newRole.permissions = permissions + return newRole.save(); + } + catch (error) { + baseLogger.error(error); + throw error; + } } const deleteRole = async (roleId: number) => { + try { return Role.delete(roleId); + } catch (err) { + baseLogger.error(err); + throw createError(404); + } } const editRole = async (payload: { name: NSRole.Type, id: number }) => { + try { + const role = await Role.findOne({ where: { id: payload.id } }); - // need validation if (role) { - role.name = payload.name; - return role.save(); - - } else { - throw createError(404); + role.name = payload.name; + return role.save(); } + } catch (err) { + baseLogger.error(err); + throw createError(404); + } } const getRoles = async (payload: { - page: string, - pageSize: string, - id: number, - name: NSRole.Type - }) => { - + page: string, + pageSize: string, + id: number, + name: NSRole.Type +}) => { + try { const page = parseInt(payload.page); const pageSize = parseInt(payload.pageSize); - - if (payload.id){ + + if (payload.id) { return Role.findOne({ where: { id: payload.id } }) } - - if (payload.name){ + + if (payload.name) { return Role.findOne({ where: { name: payload.name } }) } - + const [roles, total] = await Role.findAndCount({ skip: pageSize * (page - 1), take: pageSize, @@ -60,13 +69,17 @@ const getRoles = async (payload: { createdAt: 'ASC' } }) - + return { page, pageSize: roles.length, total, roles }; + } catch (err) { + baseLogger.error(err); + throw err; } +} export { createRole, editRole, getRoles, deleteRole } \ No newline at end of file diff --git a/src/controllers/voluntaryWork.ts b/src/controllers/voluntaryWork.ts index 88037ebd..bbb06ba5 100644 --- a/src/controllers/voluntaryWork.ts +++ b/src/controllers/voluntaryWork.ts @@ -5,309 +5,359 @@ import { VoluntaryWork } from "../db/entities/VoluntaryWork.js"; import { getDate } from "./index.js"; import { Volunteer } from "../db/entities/Volunteer.js"; import createError from 'http-errors'; -import { VolunteerProfile } from "../db/entities/VolunteerProfile.js"; import { UploadedFile } from "express-fileupload"; import { configureS3Bucket } from "../utilites/AWS_configure_S3.js"; +import baseLogger from "../../logger.js"; const createVoluntaryWork = async (payload: NSVoluntaryWork.Item) => { - let payloadDate = { ...payload, startedDate: getDate(payload.startedDate), finishedDate: getDate(payload.finishedDate) }; - - let newVoluntaryWork = VoluntaryWork.create(payloadDate as DeepPartial); - const skillTags = await SkillTag.find({ - where: { id: In(payload.skillTagIds) }, - }); - newVoluntaryWork.skillTags = skillTags; - newVoluntaryWork.feedback = []; - newVoluntaryWork.images = []; - return newVoluntaryWork.save(); + try { + let payloadDate = { ...payload, startedDate: getDate(payload.startedDate), finishedDate: getDate(payload.finishedDate) }; + + let newVoluntaryWork = VoluntaryWork.create(payloadDate as DeepPartial); + const skillTags = await SkillTag.find({ + where: { id: In(payload.skillTagIds) }, + }); + newVoluntaryWork.skillTags = skillTags; + newVoluntaryWork.feedback = []; + newVoluntaryWork.images = []; + return newVoluntaryWork.save(); + } catch (err) { + baseLogger.error(err); + throw createError(404,); + } } const deleteVoluntaryWork = async (voluntaryWorkId: number) => { - return VoluntaryWork.delete(voluntaryWorkId); + try { + return VoluntaryWork.delete(voluntaryWorkId); + } catch (err) { + baseLogger.error(err); + throw createError(404,); + } } const editVoluntaryWork = async (payload: NSVoluntaryWork.Edit) => { - const id = Number(payload.id) || 0; - let voluntaryWork = await VoluntaryWork.findOne({ where: { id } }); - - if (voluntaryWork) { - voluntaryWork.name = payload.name || voluntaryWork.name; - voluntaryWork.description = payload.description || voluntaryWork.description; - voluntaryWork.location = payload.location || voluntaryWork.location; - voluntaryWork.capacity = payload.capacity || voluntaryWork.capacity; - voluntaryWork.days = payload.days || voluntaryWork.days; - voluntaryWork.images = payload.images || voluntaryWork.images; - voluntaryWork.time = payload.time || voluntaryWork.time; - voluntaryWork.status = payload.status || voluntaryWork.status; - - if (payload.skillTagIds) { - const skillTags = await SkillTag.find({ - where: { id: In(payload.skillTagIds) }, - }); - voluntaryWork.skillTags = skillTags; - } - if (payload.startedDate) { - voluntaryWork.startedDate = getDate(payload.startedDate); - } - if (payload.finishedDate) { - voluntaryWork.finishedDate = getDate(payload.finishedDate); - } + try { + + const id = Number(payload.id) || 0; + let voluntaryWork = await VoluntaryWork.findOne({ where: { id } }); + + if (voluntaryWork) { + voluntaryWork.name = payload.name || voluntaryWork.name; + voluntaryWork.description = payload.description || voluntaryWork.description; + voluntaryWork.location = payload.location || voluntaryWork.location; + voluntaryWork.capacity = payload.capacity || voluntaryWork.capacity; + voluntaryWork.days = payload.days || voluntaryWork.days; + voluntaryWork.images = payload.images || voluntaryWork.images; + voluntaryWork.time = payload.time || voluntaryWork.time; + voluntaryWork.status = payload.status || voluntaryWork.status; + + if (payload.skillTagIds) { + const skillTags = await SkillTag.find({ + where: { id: In(payload.skillTagIds) }, + }); + voluntaryWork.skillTags = skillTags; + } + if (payload.startedDate) { + voluntaryWork.startedDate = getDate(payload.startedDate); + } + if (payload.finishedDate) { + voluntaryWork.finishedDate = getDate(payload.finishedDate); + } - return voluntaryWork.save(); - } else { - throw createError(404); + return voluntaryWork.save(); + } + } catch (error) { + baseLogger.error(error); + throw createError(404,); } } const getVoluntaryWork = (payload: { id: number }) => { - return VoluntaryWork.findOne({ where: { id: payload.id } }) + try { + return VoluntaryWork.findOne({ where: { id: payload.id } }) + } catch (err) { + baseLogger.error(err); + throw err; + } } const getVoluntaryWorks = async (payload: NSVoluntaryWork.GetVoluntaryWorks) => { - const page = parseInt(payload.page); - const pageSize = parseInt(payload.pageSize); - const conditions: Record = {}; + try { - if (payload.id) { - conditions["id"] = payload.id; - } - if (payload.name) { - conditions["name"] = payload.name; - } - if (payload.time?.length > 0) { - conditions["time"] = In(payload.time); - } - if (payload.location) { - conditions["location"] = payload.location; - } - if (payload.rating) { - conditions["rating"] = payload.rating; - } - if (payload.status) { - conditions["status"] = payload.status; - } - if (payload.days?.length > 0) { - conditions["days"] = In(payload.days); - } - if (payload.skills?.length > 0) { - conditions["skillTags"] = In(payload.skills); - } - if (payload.startedDate) { - conditions["startedDate"] = payload.startedDate; // Assuming this is a specific date comparison - } - if (payload.finishedDate) { - conditions["finishedDate"] = payload.finishedDate; // Assuming this is a specific date comparison - } - if (payload.capacity) { - conditions["capacity"] = payload.capacity; - } - if (payload.creatorId) { - conditions["creatorId"] = payload.creatorId; - } + const page = parseInt(payload.page); + const pageSize = parseInt(payload.pageSize); + const conditions: Record = {}; - if (payload.startedAfter) { - const startedAfterDate = getDate(payload.startedAfter); - conditions["startedDate"] = MoreThan(payload.startedAfter); - } + if (payload.id) { + conditions["id"] = payload.id; + } + if (payload.name) { + conditions["name"] = payload.name; + } + if (payload.time?.length > 0) { + conditions["time"] = In(payload.time); + } + if (payload.location) { + conditions["location"] = payload.location; + } + if (payload.rating) { + conditions["rating"] = payload.rating; + } + if (payload.status) { + conditions["status"] = payload.status; + } + if (payload.days?.length > 0) { + conditions["days"] = In(payload.days); + } + if (payload.skills?.length > 0) { + conditions["skillTags"] = In(payload.skills); + } + if (payload.startedDate) { + conditions["startedDate"] = payload.startedDate; // Assuming this is a specific date comparison + } + if (payload.finishedDate) { + conditions["finishedDate"] = payload.finishedDate; // Assuming this is a specific date comparison + } + if (payload.capacity) { + conditions["capacity"] = payload.capacity; + } + if (payload.creatorId) { + conditions["creatorId"] = payload.creatorId; + } - if (payload.startedBefore) { - const startedBeforeDate = getDate(payload.startedBefore); - conditions["startedDate"] = LessThan(payload.startedBefore); - } + if (payload.startedAfter) { + const startedAfterDate = getDate(payload.startedAfter); + conditions["startedDate"] = MoreThan(payload.startedAfter); + } - if (payload.finishedAfter) { - const finishedAfterDate = getDate(payload.finishedAfter); - conditions["finishedDate"] = MoreThan(payload.finishedAfter); - } + if (payload.startedBefore) { + const startedBeforeDate = getDate(payload.startedBefore); + conditions["startedDate"] = LessThan(payload.startedBefore); + } - if (payload.finishedBefore) { - const finishedBeforeDate = getDate(payload.finishedBefore); - conditions["finishedDate"] = LessThan(payload.finishedBefore); - } + if (payload.finishedAfter) { + const finishedAfterDate = getDate(payload.finishedAfter); + conditions["finishedDate"] = MoreThan(payload.finishedAfter); + } - if (payload.ratingMore) { - conditions["rating"] = MoreThanOrEqual(payload.ratingMore); - } + if (payload.finishedBefore) { + const finishedBeforeDate = getDate(payload.finishedBefore); + conditions["finishedDate"] = LessThan(payload.finishedBefore); + } - if (payload.ratingLess) { - conditions["rating"] = LessThanOrEqual(payload.ratingLess); - } + if (payload.ratingMore) { + conditions["rating"] = MoreThanOrEqual(payload.ratingMore); + } - const [voluntaryWorks, total] = await VoluntaryWork.findAndCount({ - where: conditions, - skip: pageSize * (page - 1), - take: pageSize, - order: { - createdAt: 'ASC' - }, - relations: ['skillTags', 'volunteerProfiles'] - }); - const processedVW = await Promise.all(voluntaryWorks.map(async vw => { - const volunteers = []; - for (const vp of vw.volunteerProfiles) { - const v = await Volunteer.findOne({ where: { volunteerProfile: { id: vp.id } } }); - if (v) { - volunteers.push({ name: v.name }); - } + if (payload.ratingLess) { + conditions["rating"] = LessThanOrEqual(payload.ratingLess); } - return { - name: vw.name, - description: vw.description, - days: vw.days, - time: vw.time, - location: vw.location, - startedDate: vw.startedDate, - finishedDate: vw.finishedDate, - status: vw.status, - images: vw.images, - rating: vw.rating, - feedback: vw.feedback, - capacity: vw.capacity, - skillTags: vw.skillTags.map(st => { return { name: st.name } }), - volunteers, - volunteerNumbers: volunteers.length, - createdAt: vw.createdAt - }; - })); + + const [voluntaryWorks, total] = await VoluntaryWork.findAndCount({ + where: conditions, + skip: pageSize * (page - 1), + take: pageSize, + order: { + createdAt: 'ASC' + }, + relations: ['skillTags', 'volunteerProfiles'] + }); + const processedVW = await Promise.all(voluntaryWorks.map(async vw => { + const volunteers = []; + for (const vp of vw.volunteerProfiles) { + const v = await Volunteer.findOne({ where: { volunteerProfile: { id: vp.id } } }); + if (v) { + volunteers.push({ name: v.name }); + } + } + return { + name: vw.name, + description: vw.description, + days: vw.days, + time: vw.time, + location: vw.location, + startedDate: vw.startedDate, + finishedDate: vw.finishedDate, + status: vw.status, + images: vw.images, + rating: vw.rating, + feedback: vw.feedback, + capacity: vw.capacity, + skillTags: vw.skillTags.map(st => { return { name: st.name } }), + volunteers, + volunteerNumbers: volunteers.length, + createdAt: vw.createdAt + }; + })); - return { - page, - pageSize: voluntaryWorks.length, - total, - voluntaryWorks: processedVW - }; + return { + page, + pageSize: voluntaryWorks.length, + total, + voluntaryWorks: processedVW + }; + } catch (err) { + baseLogger.error(err); + throw createError(404,); + } } const putRating = async (id: number, rating: number) => { - let voluntaryWork = await VoluntaryWork.findOne({ where: { id } }); - if (voluntaryWork) { - if (voluntaryWork.rating) { - voluntaryWork.rating += rating; - voluntaryWork.rating /= 2; - } else { - voluntaryWork.rating = rating; + try { + let voluntaryWork = await VoluntaryWork.findOne({ where: { id } }); + if (voluntaryWork) { + if (voluntaryWork.rating) { + voluntaryWork.rating += rating; + voluntaryWork.rating /= 2; + } else { + voluntaryWork.rating = rating; + } + return voluntaryWork.save(); } - return voluntaryWork.save(); - } else { - throw createError(404); + } catch (err) { + baseLogger.error(err); + throw createError(404,); } } const putFeedback = async (id: number, feedback: string) => { - let voluntaryWork = await VoluntaryWork.findOne({ where: { id } }); - if (voluntaryWork) { - voluntaryWork.feedback.push(feedback); - await voluntaryWork.save(); - } else { - throw createError(404); + try { + let voluntaryWork = await VoluntaryWork.findOne({ where: { id } }); + if (voluntaryWork) { + voluntaryWork.feedback.push(feedback); + await voluntaryWork.save(); + } else { + throw "Voluntary work not found" + } + } catch (err) { + baseLogger.error(err); + throw createError(404,); } } const putImages = async (id: number, uploadedFiles: UploadedFile[]) => { - - let voluntaryWork = await VoluntaryWork.findOne({ where: { id } }); - if (voluntaryWork) { - - const S3 = await configureS3Bucket(); - const imageUrls = []; - - for (const file of uploadedFiles) { - const uploadParams = { - Bucket: process.env.AWS_BUCKET_NAME || '', - Body: Buffer.from(file.data), - Key: `${Date.now().toString()}.png`, - ACL: 'public-read', - }; + try { - const data = await S3.upload(uploadParams).promise(); - imageUrls.push(data.Location); - } + let voluntaryWork = await VoluntaryWork.findOne({ where: { id } }); + if (voluntaryWork) { - voluntaryWork.images.push(...imageUrls); - await voluntaryWork.save(); + const S3 = await configureS3Bucket(); + const imageUrls = []; + for (const file of uploadedFiles) { + const uploadParams = { + Bucket: process.env.AWS_BUCKET_NAME || '', + Body: Buffer.from(file.data), + Key: `${Date.now().toString()}.png`, + ACL: 'public-read', + }; - } else { - throw createError(404); + const data = await S3.upload(uploadParams).promise(); + imageUrls.push(data.Location); + } + + voluntaryWork.images.push(...imageUrls); + await voluntaryWork.save(); + } + } catch (err) { + baseLogger.error(err); + throw (err); } } const registerByVolunteer = async (workId: number, volunteerProfile: Volunteer["volunteerProfile"]) => { - const voluntaryWork = await VoluntaryWork.findOne({ where: { id: workId } }); - if (!voluntaryWork) { - throw createError(404); - } + try { - if ( - volunteerProfile.availableLocation !== voluntaryWork.location || - !(volunteerProfile.availableDays?.length > 0 && volunteerProfile.availableDays?.every(day => voluntaryWork.days.includes(day))) || - !(volunteerProfile.availableTime?.length > 0 && volunteerProfile.availableTime?.every(time => voluntaryWork.time.includes(time))) || - !(volunteerProfile.skillTags?.length > 0 && volunteerProfile.skillTags.every(skillTag => voluntaryWork.skillTags.some(workSkill => workSkill.id === skillTag.id))) - ) { - throw new Error("Volunteer's profile information does not align with the VoluntaryWork information"); - } + const voluntaryWork = await VoluntaryWork.findOne({ where: { id: workId } }); + if (!voluntaryWork) { + throw createError(404); + } - if (voluntaryWork.volunteerProfiles?.length >= voluntaryWork.capacity) { - throw new Error("VoluntaryWork is already at full capacity"); - } + if ( + volunteerProfile.availableLocation !== voluntaryWork.location || + !(volunteerProfile.availableDays?.length > 0 && volunteerProfile.availableDays?.every(day => voluntaryWork.days.includes(day))) || + !(volunteerProfile.availableTime?.length > 0 && volunteerProfile.availableTime?.every(time => voluntaryWork.time.includes(time))) || + !(volunteerProfile.skillTags?.length > 0 && volunteerProfile.skillTags.every(skillTag => voluntaryWork.skillTags.some(workSkill => workSkill.id === skillTag.id))) + ) { + throw new Error("Volunteer's profile information does not align with the VoluntaryWork information"); + } - if (voluntaryWork.volunteerProfiles) { - voluntaryWork.volunteerProfiles.push(volunteerProfile); - } else { - voluntaryWork.volunteerProfiles = [volunteerProfile]; - } + if (voluntaryWork.volunteerProfiles?.length >= voluntaryWork.capacity) { + throw new Error("VoluntaryWork is already at full capacity"); + } - await voluntaryWork.save(); - return "Registration successful!"; + if (voluntaryWork.volunteerProfiles) { + voluntaryWork.volunteerProfiles.push(volunteerProfile); + } else { + voluntaryWork.volunteerProfiles = [volunteerProfile]; + } + + await voluntaryWork.save(); + return "Registration successful!"; + } catch (err) { + baseLogger.error(err); + throw createError(400); + } } const registerByOrganizationAdmin = async (workId: number, volunteerId: string) => { - const voluntaryWork = await VoluntaryWork.findOne({ where: { id: workId } }); - const volunteer = await Volunteer.findOne({ - where: { id: volunteerId }, - relations: ["roles", "roles.permissions", "volunteerProfile"] - }); + try { - if (!voluntaryWork) { - throw createError(404); - } - if (!volunteer) { - throw createError(404); - } + const voluntaryWork = await VoluntaryWork.findOne({ where: { id: workId } }); + const volunteer = await Volunteer.findOne({ + where: { id: volunteerId }, + relations: ["roles", "roles.permissions", "volunteerProfile"] + }); - if (voluntaryWork.volunteerProfiles) { - voluntaryWork.volunteerProfiles.push(volunteer.volunteerProfile); - } else { - voluntaryWork.volunteerProfiles = [volunteer.volunteerProfile]; - } + if (!voluntaryWork) { + throw "Voluntary work not found"; + } + if (!volunteer) { + throw "Volunteer not found"; + } - await voluntaryWork.save(); - return "Registration successful!"; + if (voluntaryWork.volunteerProfiles) { + voluntaryWork.volunteerProfiles.push(volunteer.volunteerProfile); + } else { + voluntaryWork.volunteerProfiles = [volunteer.volunteerProfile]; + } + + await voluntaryWork.save(); + return "Registration successful!"; + } catch (err) { + baseLogger.error(err); + throw createError(404,); + } } const deregisterVoluntaryWork = async (workId: number, volunteerId: string) => { - const voluntaryWork = await VoluntaryWork.findOne({ where: { id: workId }, relations: ["volunteerProfiles"] }); - const volunteer = await Volunteer.findOne({ where: { id: volunteerId }, relations: ["volunteerProfile"] }); + try { - if (!voluntaryWork) { - throw createError(404); - } + const voluntaryWork = await VoluntaryWork.findOne({ where: { id: workId }, relations: ["volunteerProfiles"] }); + const volunteer = await Volunteer.findOne({ where: { id: volunteerId }, relations: ["volunteerProfile"] }); - if (!volunteer) { - throw createError(404); - } - const index = voluntaryWork.volunteerProfiles.findIndex(profile => profile.id === volunteer.volunteerProfile.id); - console.log(index); + if (!voluntaryWork) { + throw "Voluntary work not found"; + } - if (index !== -1) { - voluntaryWork.volunteerProfiles.splice(index, 1); - await voluntaryWork.save(); - return "Deregistration successful!"; - } else { - throw new Error("Volunteer is not registered for this voluntary work"); + if (!volunteer) { + throw "Volunteer not found" + } + const index = voluntaryWork.volunteerProfiles.findIndex(profile => profile.id === volunteer.volunteerProfile.id); + if (index !== -1) { + voluntaryWork.volunteerProfiles.splice(index, 1); + await voluntaryWork.save(); + return "Deregistration successful!"; + } else { + throw new Error("Volunteer is not registered for this voluntary work"); + } + } catch (err) { + baseLogger.error(err); + throw createError(404); } } diff --git a/src/controllers/volunteer.ts b/src/controllers/volunteer.ts index 87c66706..95f0563b 100644 --- a/src/controllers/volunteer.ts +++ b/src/controllers/volunteer.ts @@ -9,203 +9,217 @@ import { SkillTag } from "../db/entities/SkillTag.js"; import { In, Like } from "typeorm"; import createError from 'http-errors'; import { Role } from "../db/entities/Role.js"; +import baseLogger from "../../logger.js"; const createVolunteer = async (payload: NSVolunteer.Item) => { + try { + + return dataSource.manager.transaction(async (transaction) => { + const existingSkillTags = await SkillTag.find({ + where: { name: In(payload.skills) }, + }); + + const newSkillTags = await Promise.all( + payload.skills.map(async (skillName) => { + return existingSkillTags.find((tag) => tag.name === skillName) || + (await transaction.save(SkillTag.create({ name: skillName }))); + }) + ); + + const profile = VolunteerProfile.create({ + availableTime: payload.availableTime, + availableLocation: payload.availableLocation, + availableDays: payload.availableDays, + skillTags: newSkillTags + }); + await transaction.save(profile); + + const newVolunteer = Volunteer.create(payload); + newVolunteer.volunteerProfile = profile; + + const role = await Role.findOne({ where: { name: payload.type } }); + if (role) { + newVolunteer.roles = [role]; + } - return dataSource.manager.transaction(async (transaction) => { - - const existingSkillTags = await SkillTag.find({ - where: { name: In(payload.skills) }, - }); - - const newSkillTags = await Promise.all( - payload.skills.map(async (skillName) => { - return existingSkillTags.find((tag) => tag.name === skillName) || - (await transaction.save(SkillTag.create({ name: skillName }))); - }) - ); - - const profile = VolunteerProfile.create({ - availableTime: payload.availableTime, - availableLocation: payload.availableLocation, - availableDays: payload.availableDays, - skillTags: newSkillTags + await transaction.save(newVolunteer); + return newVolunteer }); - await transaction.save(profile); - - const newVolunteer = Volunteer.create(payload); - newVolunteer.volunteerProfile = profile; - - const role = await Role.findOne({where:{name:payload.type}}); - if (role){ - newVolunteer.roles = [role]; - } - - await transaction.save(newVolunteer); - return newVolunteer - }); + } catch (err) { + baseLogger.error(err); + throw createError(404); + } }; const deleteVolunteer = async (volunteerId: string) => { - const volunteer = await Volunteer.findOne({ - where: { id: volunteerId }, - }); - - if (volunteer) { + try { return Volunteer.delete(volunteerId); - } else { + } catch (err) { + baseLogger.error(err); throw createError(404); } } const editVolunteer = async (payload: { name: string, id: string, email: string, oldPassword: string, newPassword: string }) => { - const volunteer = await Volunteer.findOne({ where: { id: payload.id } }); - - if (volunteer) { - if (payload.name) - volunteer.name = payload.name; - - if (payload.email) - volunteer.email = payload.email; - - if (payload.newPassword) { - if (!payload.oldPassword) { - throw "Old password is needed !"; + try { + const volunteer = await Volunteer.findOne({ where: { id: payload.id } }); + if (volunteer) { + if (payload.name) + volunteer.name = payload.name; + + if (payload.email) + volunteer.email = payload.email; + + if (payload.newPassword) { + if (!payload.oldPassword) { + throw "Old password is needed !"; + } + + const passwordMatching = await bcrypt.compare(payload.oldPassword, volunteer?.password || ''); + if (passwordMatching) { + volunteer.password = await bcrypt.hash(payload.newPassword, 10); + } else { + throw "The old password isn't correct !" + } } - const passwordMatching = await bcrypt.compare(payload.oldPassword, volunteer?.password || ''); - if (passwordMatching) { - volunteer.password = await bcrypt.hash(payload.newPassword, 10); - } else { - throw "The old password isn't correct !" - } + return volunteer.save(); } - - return volunteer.save(); - - } else { + } catch (err) { + baseLogger.error(err); throw createError(404); } } const login = async (email: string, name: string, id: string) => { - const volunteer = await Volunteer.findOne({ - where: { email, name, id }, - relations: ["roles", "roles.permissions"], - }); - - const organizationAdmin = await OrganizationAdmin.findOne({ - where: { email, name, id }, - relations: ["roles", "roles.permissions"], - }); - - if (volunteer) { - const token = jwt.sign( - { email, name, id }, - process.env.SECRET_KEY || '', - { - expiresIn: "1d" - } - ); - return token; - } else if (organizationAdmin) { - const token = jwt.sign( - { email, name, id }, - process.env.SECRET_KEY || '', - { - expiresIn: "1d" - } - ); - return token; - } else { - throw ("Invalid email or name or id !"); + try { + const volunteer = await Volunteer.findOne({ + where: { email, name, id }, + relations: ["roles", "roles.permissions"], + }); + + const organizationAdmin = await OrganizationAdmin.findOne({ + where: { email, name, id }, + relations: ["roles", "roles.permissions"], + }); + + if (volunteer) { + const token = jwt.sign( + { email, name, id }, + process.env.SECRET_KEY || '', + { + expiresIn: "1d" + } + ); + return token; + } else if (organizationAdmin) { + const token = jwt.sign( + { email, name, id }, + process.env.SECRET_KEY || '', + { + expiresIn: "1d" + } + ); + return token; + } else { + throw ("Invalid email or name or id !"); + } + } catch (err) { + baseLogger.error(err); + throw err; } } const getVolunteers = async (payload: NSVolunteer.Item & { page: string; pageSize: string }) => { - const page = parseInt(payload.page); - const pageSize = parseInt(payload.pageSize); - const conditions: Record = {}; - - if (payload.id) { - conditions["id"] = payload.id; - } - if (payload.name) { - conditions["name"] = Like(`%${payload.name}%`); - } - if (payload.email) { - conditions["email"] = payload.email; - } - if (payload.availableTime.length > 0) { - conditions["availableTime"] = In(payload.availableTime); - } - if (payload.availableLocation) { - conditions["availableLocation"] = Like(`%${payload.availableLocation}%`); - } - if (payload.type) { - conditions["type"] = payload.type; - } - if (payload.availableDays.length > 0) { - conditions["availableDays"] = In(payload.availableDays); - } - const [volunteers, total] = await Volunteer.findAndCount({ - where: conditions, - order: { - createdAt: 'ASC', - }, - relations: [ - "volunteerProfile.skillTags", - "volunteerProfile" - ], - select: [ - "name", - "email", - "type", - "volunteerProfile" - ], - }); - - const processedVolunteers = volunteers.map((volunteer) => { - // Create a new volunteer object with the desired properties - return { - name: volunteer.name, - email: volunteer.email, - type: volunteer.type, - createdAt: volunteer.createdAt, - volunteerProfile: { - availableTime: volunteer.volunteerProfile?.availableTime, - availableDays: volunteer.volunteerProfile?.availableDays, - availableLocation: volunteer.volunteerProfile?.availableLocation, - dateOfBirth: volunteer.volunteerProfile?.dateOfBirth, - roles:volunteer.volunteerProfile?.roles, - skillTags: volunteer.volunteerProfile?.skillTags?.map((skillTag) => { - return { name: skillTag.name }; - }), - }, - }; - }); + try { + + const page = parseInt(payload.page); + const pageSize = parseInt(payload.pageSize); + const conditions: Record = {}; - const filteredVolunteers = processedVolunteers.filter((volunteer) => { - if (payload.skills.length > 0) { - const hasMatchingSkill = volunteer.volunteerProfile.skillTags.some((skillTag) => payload.skills.includes(skillTag.name)); - return hasMatchingSkill; + if (payload.id) { + conditions["id"] = payload.id; } - return true; - }); - const startIndex = (page - 1) * pageSize; - const endIndex = startIndex + pageSize; - const paginatedVolunteers = filteredVolunteers.slice(startIndex, endIndex); - - return { - page, - pageSize: paginatedVolunteers.length, - total: filteredVolunteers.length, - volunteers: paginatedVolunteers, - }; -}; + if (payload.name) { + conditions["name"] = Like(`%${payload.name}%`); + } + if (payload.email) { + conditions["email"] = payload.email; + } + if (payload.availableTime.length > 0) { + conditions["availableTime"] = In(payload.availableTime); + } + if (payload.availableLocation) { + conditions["availableLocation"] = Like(`%${payload.availableLocation}%`); + } + if (payload.type) { + conditions["type"] = payload.type; + } + if (payload.availableDays.length > 0) { + conditions["availableDays"] = In(payload.availableDays); + } + const [volunteers, total] = await Volunteer.findAndCount({ + where: conditions, + order: { + createdAt: 'ASC', + }, + relations: [ + "volunteerProfile.skillTags", + "volunteerProfile" + ], + select: [ + "name", + "email", + "type", + "volunteerProfile" + ], + }); + + const processedVolunteers = volunteers.map((volunteer) => { + // Create a new volunteer object with the desired properties + return { + name: volunteer.name, + email: volunteer.email, + type: volunteer.type, + createdAt: volunteer.createdAt, + volunteerProfile: { + availableTime: volunteer.volunteerProfile?.availableTime, + availableDays: volunteer.volunteerProfile?.availableDays, + availableLocation: volunteer.volunteerProfile?.availableLocation, + dateOfBirth: volunteer.volunteerProfile?.dateOfBirth, + roles: volunteer.volunteerProfile?.roles, + skillTags: volunteer.volunteerProfile?.skillTags?.map((skillTag) => { + return { name: skillTag.name }; + }), + }, + }; + }); + + + const filteredVolunteers = processedVolunteers.filter((volunteer) => { + if (payload.skills.length > 0) { + const hasMatchingSkill = volunteer.volunteerProfile.skillTags.some((skillTag) => payload.skills.includes(skillTag.name)); + return hasMatchingSkill; + } + return true; + }); + const startIndex = (page - 1) * pageSize; + const endIndex = startIndex + pageSize; + const paginatedVolunteers = filteredVolunteers.slice(startIndex, endIndex); + return { + page, + pageSize: paginatedVolunteers.length, + total: filteredVolunteers.length, + volunteers: paginatedVolunteers, + }; + } catch (err) { + baseLogger.error(err); + throw err; + } +} export { getVolunteers, login, createVolunteer, deleteVolunteer, editVolunteer } From 74b5b658c1fdd449f7a7e5130526907a0f5209dc Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Tue, 10 Oct 2023 13:15:53 +0300 Subject: [PATCH 103/146] Creat the basics for docker --- .dockerignore | 2 ++ Dockerfile | 11 ++++++++ docker-compose.yml | 31 ++++++++++++++++++++++ package.json | 3 ++- src/db/dataSource.ts | 3 +++ src/routes/voluntaryWork.ts | 53 ++++++++++++++++++++++++++++++++----- 6 files changed, 95 insertions(+), 8 deletions(-) create mode 100644 .dockerignore create mode 100644 Dockerfile create mode 100644 docker-compose.yml diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..76add878 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,2 @@ +node_modules +dist \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..69464189 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,11 @@ +FROM node:18-alpine + +WORKDIR /user/app +COPY package.json package-lock.json ./ + +RUN npm ci + +ADD . . +RUN npm run build + +CMD node ./dist/app.js \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 00000000..eeea3efe --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,31 @@ +version: "3" + +services: + mysql: + container_name: db + image: mysql + environment: + - MYSQL_ROOT_PASSWORD=root + - MYSQL_DATABASE=Serve-and-Shine + ports: + - "3306:3306" + healthcheck: + test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] + timeout: 20s + retries: 10 + + app: + container_name: app-docker + build: . + environment: + - PORT=80 + - DB_HOST=db + - DB_USERNAME=root + - DB_PASSWORD=root + - DB_NAME=Serve-and-Shine + - DB_PORT=3306 + ports: + - "3000:80" + depends_on: + mysql: + condition: service_healthy diff --git a/package.json b/package.json index d9b3e313..f974e55e 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,8 @@ "build-tsc": "tsc -w", "run-watch": "nodemon ./dist/app.js", "dev": "concurrently \"npm:build-tsc\" \"npm:run-watch\"", - "test": "tsc && jest" + "test": "tsc && jest", + "build": "tsc --project ." }, "dependencies": { "@types/express-fileupload": "^1.4.2", diff --git a/src/db/dataSource.ts b/src/db/dataSource.ts index 215aec0d..34599839 100644 --- a/src/db/dataSource.ts +++ b/src/db/dataSource.ts @@ -23,6 +23,9 @@ const dataSource = new DataSource({ logging: false }); +console.log(dataSource); + + export const initDB = async () => await dataSource.initialize().then(() => { console.log("Connected to DB!"); diff --git a/src/routes/voluntaryWork.ts b/src/routes/voluntaryWork.ts index f8efd87e..f3ea647a 100644 --- a/src/routes/voluntaryWork.ts +++ b/src/routes/voluntaryWork.ts @@ -309,8 +309,47 @@ router.put("/feedback/:id", validateVoluntaryWorkId, authorize("PUT_feedback"), }); }); +// router.put("/images/:id", validateVoluntaryWorkId, authorize("PUT_images"), async (req, res, next) => { +// putImages(Number(req.params.id), ((Array.isArray(req.files?.image) ? req.files?.image : [req.files?.image]).filter(Boolean)) as UploadedFile[]).then(() => { +// log({ +// userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, +// userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, +// userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, +// type: 'success' as NSLogs.Type, +// request: 'Add images to voluntary work with id' + req.params.id +// }).then(() => { +// console.log('logged'); +// }).catch(err => { +// console.log('NOT logged'); +// }) +// res.status(201).send("Images added successfully!!") +// }).catch(err => { +// log({ +// userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, +// userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, +// userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, +// type: 'failed' as NSLogs.Type, +// request: 'Add images to voluntary work with id' + req.params.id +// }).then(() => { +// console.log('logged'); +// }).catch(err => { +// console.log('NOT logged'); +// }) +// next(err); +// }); +// }); router.put("/images/:id", validateVoluntaryWorkId, authorize("PUT_images"), async (req, res, next) => { - putImages(Number(req.params.id), ((Array.isArray(req.files?.image) ? req.files?.image : [req.files?.image]).filter(Boolean)) as UploadedFile[]).then(() => { + const images = req.files?.image; + if (!images) { + // Handle the case when 'images' is undefined + return res.status(400).send("No images provided."); + } + + try { + const uploadedFiles = Array.isArray(images) ? images : [images]; + + await putImages(Number(req.params.id), uploadedFiles); + log({ userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, @@ -321,9 +360,10 @@ router.put("/images/:id", validateVoluntaryWorkId, authorize("PUT_images"), asyn console.log('logged'); }).catch(err => { console.log('NOT logged'); - }) - res.status(201).send("Images added successfully!!") - }).catch(err => { + }); + + res.status(201).send("Images added successfully!!"); + } catch (err) { log({ userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, @@ -334,11 +374,10 @@ router.put("/images/:id", validateVoluntaryWorkId, authorize("PUT_images"), asyn console.log('logged'); }).catch(err => { console.log('NOT logged'); - }) + }); next(err); - }); + } }); - router.put("/register/:id", validateVoluntaryWorkId, authorize("REGISTER_voluntaryWork"), async (req, res, next) => { if (res.locals.volunteer) { registerByVolunteer(Number(req.params.id), res.locals.volunteer?.volunteerProfile).then(() => { From e12b6e54245274ed9b875a7e5925c91a1c0ccf7e Mon Sep 17 00:00:00 2001 From: Khaled Ezzughayyar Date: Tue, 10 Oct 2023 15:01:12 +0300 Subject: [PATCH 104/146] use mysql2 --- package-lock.json | 149 ++++++++++++++++++++++++++++------------------ package.json | 2 +- 2 files changed, 91 insertions(+), 60 deletions(-) diff --git a/package-lock.json b/package-lock.json index f4e40ab8..7b2dff88 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,7 +22,7 @@ "jest": "^29.7.0", "jsonwebtoken": "^9.0.2", "morgan": "^1.10.0", - "mysql": "^2.18.1", + "mysql2": "^3.6.1", "typeorm": "^0.3.17", "typescript": "^5.2.2", "winston": "^3.11.0" @@ -3052,14 +3052,6 @@ "node": ">= 10.0.0" } }, - "node_modules/bignumber.js": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.0.tgz", - "integrity": "sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A==", - "engines": { - "node": "*" - } - }, "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -3663,11 +3655,6 @@ "url": "https://opencollective.com/core-js" } }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" - }, "node_modules/create-jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", @@ -3777,6 +3764,14 @@ "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==" }, + "node_modules/denque": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", + "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==", + "engines": { + "node": ">=0.10" + } + }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -4226,6 +4221,14 @@ "node": ">=10" } }, + "node_modules/generate-function": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", + "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", + "dependencies": { + "is-property": "^1.0.2" + } + }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -4691,6 +4694,11 @@ "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==" }, + "node_modules/is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==" + }, "node_modules/is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", @@ -5610,6 +5618,11 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, + "node_modules/long": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", + "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" + }, "node_modules/longest": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", @@ -5827,24 +5840,50 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, - "node_modules/mysql": { - "version": "2.18.1", - "resolved": "https://registry.npmjs.org/mysql/-/mysql-2.18.1.tgz", - "integrity": "sha512-Bca+gk2YWmqp2Uf6k5NFEurwY/0td0cpebAucFpY/3jhrwrVGuxU2uQFCHjU19SJfje0yQvi+rVWdq78hR5lig==", + "node_modules/mysql2": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.6.1.tgz", + "integrity": "sha512-O7FXjLtNkjcMBpLURwkXIhyVbX9i4lq4nNRCykPNOXfceq94kJ0miagmTEGCZieuO8JtwtXaZ41U6KT4eF9y3g==", "dependencies": { - "bignumber.js": "9.0.0", - "readable-stream": "2.3.7", - "safe-buffer": "5.1.2", - "sqlstring": "2.3.1" + "denque": "^2.1.0", + "generate-function": "^2.3.1", + "iconv-lite": "^0.6.3", + "long": "^5.2.1", + "lru-cache": "^8.0.0", + "named-placeholders": "^1.1.3", + "seq-queue": "^0.0.5", + "sqlstring": "^2.3.2" }, "engines": { - "node": ">= 0.6" + "node": ">= 8.0" } }, - "node_modules/mysql/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "node_modules/mysql2/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mysql2/node_modules/lru-cache": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-8.0.5.tgz", + "integrity": "sha512-MhWWlVnuab1RG5/zMRRcVGXZLCXrZTgfwMikgzCegsPnG62yDQo5JnqKkrK4jO5iKqDAZGItAqN5CtKBCBWRUA==", + "engines": { + "node": ">=16.14" + } + }, + "node_modules/mysql2/node_modules/sqlstring": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.3.tgz", + "integrity": "sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==", + "engines": { + "node": ">= 0.6" + } }, "node_modules/mz": { "version": "2.7.0", @@ -5856,6 +5895,25 @@ "thenify-all": "^1.0.0" } }, + "node_modules/named-placeholders": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.3.tgz", + "integrity": "sha512-eLoBxg6wE/rZkJPhU/xRX1WTpkFEwDJEN96oxFrTsqBdbT5ec295Q+CoHrL9IT0DipqKhmGcaZmwOt8OON5x1w==", + "dependencies": { + "lru-cache": "^7.14.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/named-placeholders/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "engines": { + "node": ">=12" + } + }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -6267,11 +6325,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, "node_modules/promise": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/promise/-/promise-6.1.0.tgz", @@ -6400,25 +6453,6 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" }, - "node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/readable-stream/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -6698,6 +6732,11 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, + "node_modules/seq-queue": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/seq-queue/-/seq-queue-0.0.5.tgz", + "integrity": "sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q==" + }, "node_modules/serve-static": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", @@ -6857,14 +6896,6 @@ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" }, - "node_modules/sqlstring": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz", - "integrity": "sha512-ooAzh/7dxIG5+uDik1z/Rd1vli0+38izZhGzSa34FwR7IbelPWCCKSNIl8jlL/F7ERvy8CB2jNeM1E9i9mXMAQ==", - "engines": { - "node": ">= 0.6" - } - }, "node_modules/stack-trace": { "version": "0.0.10", "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", diff --git a/package.json b/package.json index f974e55e..a29f8bb5 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "jest": "^29.7.0", "jsonwebtoken": "^9.0.2", "morgan": "^1.10.0", - "mysql": "^2.18.1", + "mysql2": "^3.6.1", "typeorm": "^0.3.17", "typescript": "^5.2.2", "winston": "^3.11.0" From d2eb382e30d13c684be8286cbee1bc2d8b17410b Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Tue, 10 Oct 2023 16:55:58 +0300 Subject: [PATCH 105/146] Adding docker compose file for production --- Dockerfile | 7 ++++++- docker-compose-prod.yml | 35 +++++++++++++++++++++++++++++++++++ docker-compose.yml | 20 ++++++++++++-------- src/db/dataSource.ts | 3 --- 4 files changed, 53 insertions(+), 12 deletions(-) create mode 100644 docker-compose-prod.yml diff --git a/Dockerfile b/Dockerfile index 69464189..520d9462 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,11 +1,16 @@ -FROM node:18-alpine +FROM node:20-alpine WORKDIR /user/app COPY package.json package-lock.json ./ RUN npm ci +RUN apk add curl + ADD . . RUN npm run build +HEALTHCHECK --interval=10s --timeout=3s \ + CMD curl -f http://localhost/ || exit 1 + CMD node ./dist/app.js \ No newline at end of file diff --git a/docker-compose-prod.yml b/docker-compose-prod.yml new file mode 100644 index 00000000..aa6748ee --- /dev/null +++ b/docker-compose-prod.yml @@ -0,0 +1,35 @@ +version: '3' + +services: + mysql: + image: mysql + environment: + - MYSQL_ROOT_PASSWORD=$DB_PASSWORD + - MYSQL_DATABASE=some + volumes: + - db-data:/var/lib/mysql + ports: + - "3306:3306" + healthcheck: + test: [ "CMD", "mysqladmin", "ping", "-h", "localhost" ] + timeout: 20s + retries: 10 + restart: always + + app: + image: ghcr.io/sarahabuirmeileh/express-docker:$GIT_VERSISON + restart: always #like sysd service + environment: + - PORT=80 + - DB_HOST=mysql # to comunicate the servies in the same project ny the name of the serevice + - DB_USERNAME=$DB_USERNAME + - DB_PASSWORD=$DB_PASSWORD + - DB_NAME=$DB_NAME + ports: + - "80:80" + depends_on: + mysql: + condition: service_healthy + +volumes: + db-data: \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index eeea3efe..34d9a73a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -5,12 +5,14 @@ services: container_name: db image: mysql environment: - - MYSQL_ROOT_PASSWORD=root - - MYSQL_DATABASE=Serve-and-Shine + - MYSQL_ROOT_PASSWORD=$DB_PASSWORD + - MYSQL_DATABASE=$DB_NAME + volumes: + - db-data:/var/lib/mysql ports: - "3306:3306" healthcheck: - test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] + test: [ "CMD", "mysqladmin", "ping", "-h", "localhost" ] timeout: 20s retries: 10 @@ -18,14 +20,16 @@ services: container_name: app-docker build: . environment: - - PORT=80 + - PORT=$PORT - DB_HOST=db - - DB_USERNAME=root - - DB_PASSWORD=root - - DB_NAME=Serve-and-Shine - - DB_PORT=3306 + - DB_USERNAME=$DB_USERNAME + - DB_PASSWORD=$DB_PASSWORD + - DB_NAME=$DB_NAME + - DB_PORT=$DB_PORT ports: - "3000:80" depends_on: mysql: condition: service_healthy +volumes: + db-data: \ No newline at end of file diff --git a/src/db/dataSource.ts b/src/db/dataSource.ts index 34599839..215aec0d 100644 --- a/src/db/dataSource.ts +++ b/src/db/dataSource.ts @@ -23,9 +23,6 @@ const dataSource = new DataSource({ logging: false }); -console.log(dataSource); - - export const initDB = async () => await dataSource.initialize().then(() => { console.log("Connected to DB!"); From 587900b5689d2a758279aa4b17a6dcc8e2722324 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Tue, 10 Oct 2023 17:36:49 +0300 Subject: [PATCH 106/146] Adding the github actions to deploy the app --- .github/workflows/build.yml | 60 +++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 .github/workflows/build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 00000000..fbb8fcc5 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,60 @@ +name: Docker Image CI + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +jobs: + + build: + + runs-on: ubuntu-latest + + permissions: + contents: read + packages: write + + + steps: + - uses: actions/checkout@v3 + + - name: Set image version (tag) + id: image_version + run: echo "gitsha=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT + + - name: login to Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + password: ${{ secrets.GITHUB_TOKEN }} + - name: Build the Docker image + run: docker build . --file Dockerfile --tag ghcr.io/sarahabuirmeileh/serve-and-shine:${{ steps.image_version.outputs.gitsha }} + - name: Puplish docker image + run: docker push ghcr.io/sarahabuirmeileh/serve-and-shine:${{ steps.image_version.outputs.gitsha }} + - name: configer docker host + uses: khaledez/configure-docker-host@v1 + with: + host: 52.56.237.63 + user: github + ssh-private-key: ${{ secrets.DEPLOYMENT_KEY }} + + - name: deploy + run: docker compose -f docker-compose-prod.yml up -d + env: + DB_PASSWORD: ${{ secrets.DB_PASSWORD}} + GIT_VERSISON: ${{steps.image_version.outputs.gitsha}} + SECRET_KEY: ${{ secrets.SECRET_KEY}} + DB_HOST: ${{ secrets. DB_HOST}} + DB_PORT: ${{ secrets.DB_PORT}} + DB_USERNAME: ${{ secrets.DB_USERNAME}} + DB_NAME: ${{ secrets.DB_NAME}} + AWS_BUCKET_NAME: ${{ secrets.AWS_BUCKET_NAME}} + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID}} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY}} + AWS_REGION: ${{ secrets.AWS_REGION}} + + - name: print logs + if: always() + run: docker compose logs \ No newline at end of file From 481fd311fd87233f6d8339bbbaacf217eac5dcb9 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Tue, 10 Oct 2023 17:43:03 +0300 Subject: [PATCH 107/146] Edit name for log in registry --- .github/workflows/build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fbb8fcc5..49f94eae 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -28,6 +28,7 @@ jobs: uses: docker/login-action@v3 with: registry: ghcr.io + username: sarahabuirmeileh password: ${{ secrets.GITHUB_TOKEN }} - name: Build the Docker image run: docker build . --file Dockerfile --tag ghcr.io/sarahabuirmeileh/serve-and-shine:${{ steps.image_version.outputs.gitsha }} From f6a845d1836cda4ce807566b68067582da9edf3b Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Tue, 10 Oct 2023 17:52:11 +0300 Subject: [PATCH 108/146] Delete the health checks --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 520d9462..92561815 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,7 +10,7 @@ RUN apk add curl ADD . . RUN npm run build -HEALTHCHECK --interval=10s --timeout=3s \ - CMD curl -f http://localhost/ || exit 1 +# HEALTHCHECK --interval=10s --timeout=3s \ +# CMD curl -f http://localhost/ || exit 1 CMD node ./dist/app.js \ No newline at end of file From 11a7ec1d6873189dc50a0514f0aec6e4546150ac Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Tue, 10 Oct 2023 18:08:28 +0300 Subject: [PATCH 109/146] Edit the iamge name --- Dockerfile | 4 ++-- docker-compose-prod.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index 92561815..520d9462 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,7 +10,7 @@ RUN apk add curl ADD . . RUN npm run build -# HEALTHCHECK --interval=10s --timeout=3s \ -# CMD curl -f http://localhost/ || exit 1 +HEALTHCHECK --interval=10s --timeout=3s \ + CMD curl -f http://localhost/ || exit 1 CMD node ./dist/app.js \ No newline at end of file diff --git a/docker-compose-prod.yml b/docker-compose-prod.yml index aa6748ee..6da94ad9 100644 --- a/docker-compose-prod.yml +++ b/docker-compose-prod.yml @@ -17,7 +17,7 @@ services: restart: always app: - image: ghcr.io/sarahabuirmeileh/express-docker:$GIT_VERSISON + image: ghcr.io/sarahabuirmeileh/serve-and-shine:$GIT_VERSISON restart: always #like sysd service environment: - PORT=80 From 3095ad8a9e92463a92b6d67b85c0c0600f8d682b Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Tue, 10 Oct 2023 18:17:20 +0300 Subject: [PATCH 110/146] Edit db_name --- docker-compose-prod.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose-prod.yml b/docker-compose-prod.yml index 6da94ad9..143acbe3 100644 --- a/docker-compose-prod.yml +++ b/docker-compose-prod.yml @@ -5,7 +5,7 @@ services: image: mysql environment: - MYSQL_ROOT_PASSWORD=$DB_PASSWORD - - MYSQL_DATABASE=some + - MYSQL_DATABASE=$DB_NAME volumes: - db-data:/var/lib/mysql ports: From d541a834a21fd7a979cd969beda4a96c348ea033 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Tue, 10 Oct 2023 18:44:54 +0300 Subject: [PATCH 111/146] Adding the script for instnces --- infrastructure/setup-instance.sh | 35 ++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 infrastructure/setup-instance.sh diff --git a/infrastructure/setup-instance.sh b/infrastructure/setup-instance.sh new file mode 100644 index 00000000..26549c6b --- /dev/null +++ b/infrastructure/setup-instance.sh @@ -0,0 +1,35 @@ +#!/bin/sh +set -e + +sudo apt update +sudo apt upgrade -y + +sudo apt-get install -y ca-certificates curl gnupg +sudo install -m 0755 -d /etc/apt/keyrings + +# install docker +for pkg in docker.io docker-doc docker-compose podman-docker containerd runc; do sudo apt-get remove $pkg; done + +curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg +sudo chmod a+r /etc/apt/keyrings/docker.gpg +# Add the repository to Apt sources: +echo \ + "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ + "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \ + sudo tee /etc/apt/sources.list.d/docker.list > /dev/null +sudo apt update + +sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin + +# create github user +sudo mkdir -p /home/app +sudo useradd --no-create-home --home-dir /home/app --shell /bin/bash github +sudo usermod --append --groups docker github +sudo usermod --append --groups docker ubuntu +sudo chown github:github -R /home/app + +github_pubkey='ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH/nuLtOesRq8NPmQT/Lurvz/qPsgpwyIPzyAyZIaD43 sarah@Sarah-Lenovo' + +sudo -u github sh -c "mkdir -p /home/app/.ssh && echo $github_pubkey > /home/app/.ssh/authorized_keys" + +sudo reboot \ No newline at end of file From 64d3b92052cf2950af5f632a86ad28ae3e579103 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Tue, 10 Oct 2023 19:46:48 +0300 Subject: [PATCH 112/146] Adding the AWS CloudWatch configration --- package-lock.json | 1096 ++++++++++++++++++++++ package.json | 1 + src/utilites/AWS_confugure_CloudWatch.ts | 22 + 3 files changed, 1119 insertions(+) create mode 100644 src/utilites/AWS_confugure_CloudWatch.ts diff --git a/package-lock.json b/package-lock.json index 7b2dff88..22278ed7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,7 @@ "name": "serve-and-shine", "version": "1.0.0", "dependencies": { + "@aws-sdk/client-cloudwatch": "^3.427.0", "@types/express-fileupload": "^1.4.2", "aws-sdk": "^2.1472.0", "bcrypt": "^5.1.1", @@ -52,6 +53,563 @@ "node": ">=6.0.0" } }, + "node_modules/@aws-crypto/crc32": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-3.0.0.tgz", + "integrity": "sha512-IzSgsrxUcsrejQbPVilIKy16kAT52EwB6zSaI+M3xxIhKh5+aldEyvI+z6erM7TCLB2BJsFrtHjp6/4/sr+3dA==", + "dependencies": { + "@aws-crypto/util": "^3.0.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/crc32/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@aws-crypto/ie11-detection": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/ie11-detection/-/ie11-detection-3.0.0.tgz", + "integrity": "sha512-341lBBkiY1DfDNKai/wXM3aujNBkXR7tq1URPQDL9wi3AUbI80NR74uF1TXHMm7po1AcnFk8iu2S2IeU/+/A+Q==", + "dependencies": { + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/ie11-detection/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@aws-crypto/sha256-browser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-3.0.0.tgz", + "integrity": "sha512-8VLmW2B+gjFbU5uMeqtQM6Nj0/F1bro80xQXCW6CQBWgosFWXTx77aeOF5CAIAmbOK64SdMBJdNr6J41yP5mvQ==", + "dependencies": { + "@aws-crypto/ie11-detection": "^3.0.0", + "@aws-crypto/sha256-js": "^3.0.0", + "@aws-crypto/supports-web-crypto": "^3.0.0", + "@aws-crypto/util": "^3.0.0", + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-locate-window": "^3.0.0", + "@aws-sdk/util-utf8-browser": "^3.0.0", + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/sha256-browser/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@aws-crypto/sha256-js": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-3.0.0.tgz", + "integrity": "sha512-PnNN7os0+yd1XvXAy23CFOmTbMaDxgxXtTKHybrJ39Y8kGzBATgBFibWJKH6BhytLI/Zyszs87xCOBNyBig6vQ==", + "dependencies": { + "@aws-crypto/util": "^3.0.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/sha256-js/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@aws-crypto/supports-web-crypto": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-3.0.0.tgz", + "integrity": "sha512-06hBdMwUAb2WFTuGG73LSC0wfPu93xWwo5vL2et9eymgmu3Id5vFAHBbajVWiGhPO37qcsdCap/FqXvJGJWPIg==", + "dependencies": { + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/supports-web-crypto/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@aws-crypto/util": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-3.0.0.tgz", + "integrity": "sha512-2OJlpeJpCR48CC8r+uKVChzs9Iungj9wkZrl8Z041DWEWvyIHILYKCPNzJghKsivj+S3mLo6BVc7mBNzdxA46w==", + "dependencies": { + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-utf8-browser": "^3.0.0", + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/util/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@aws-sdk/client-cloudwatch": { + "version": "3.427.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-cloudwatch/-/client-cloudwatch-3.427.0.tgz", + "integrity": "sha512-axyu0c53gznAUPIV+9sycDfYRWXRnddm73l1/J5iMboBEelJARhXAc23OMVGAmwoBHHVaziJLdCqHJAS0t8NHg==", + "dependencies": { + "@aws-crypto/sha256-browser": "3.0.0", + "@aws-crypto/sha256-js": "3.0.0", + "@aws-sdk/client-sts": "3.427.0", + "@aws-sdk/credential-provider-node": "3.427.0", + "@aws-sdk/middleware-host-header": "3.425.0", + "@aws-sdk/middleware-logger": "3.425.0", + "@aws-sdk/middleware-recursion-detection": "3.425.0", + "@aws-sdk/middleware-signing": "3.425.0", + "@aws-sdk/middleware-user-agent": "3.427.0", + "@aws-sdk/region-config-resolver": "3.425.0", + "@aws-sdk/types": "3.425.0", + "@aws-sdk/util-endpoints": "3.427.0", + "@aws-sdk/util-user-agent-browser": "3.425.0", + "@aws-sdk/util-user-agent-node": "3.425.0", + "@smithy/config-resolver": "^2.0.11", + "@smithy/fetch-http-handler": "^2.2.1", + "@smithy/hash-node": "^2.0.10", + "@smithy/invalid-dependency": "^2.0.10", + "@smithy/middleware-content-length": "^2.0.12", + "@smithy/middleware-endpoint": "^2.0.10", + "@smithy/middleware-retry": "^2.0.13", + "@smithy/middleware-serde": "^2.0.10", + "@smithy/middleware-stack": "^2.0.4", + "@smithy/node-config-provider": "^2.0.13", + "@smithy/node-http-handler": "^2.1.6", + "@smithy/protocol-http": "^3.0.6", + "@smithy/smithy-client": "^2.1.9", + "@smithy/types": "^2.3.4", + "@smithy/url-parser": "^2.0.10", + "@smithy/util-base64": "^2.0.0", + "@smithy/util-body-length-browser": "^2.0.0", + "@smithy/util-body-length-node": "^2.1.0", + "@smithy/util-defaults-mode-browser": "^2.0.13", + "@smithy/util-defaults-mode-node": "^2.0.15", + "@smithy/util-retry": "^2.0.3", + "@smithy/util-utf8": "^2.0.0", + "@smithy/util-waiter": "^2.0.10", + "fast-xml-parser": "4.2.5", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-sso": { + "version": "3.427.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.427.0.tgz", + "integrity": "sha512-sFVFEmsQ1rmgYO1SgrOTxE/MTKpeE4hpOkm1WqhLQK7Ij136vXpjCxjH1JYZiHiUzO1wr9t4ex4dlB5J3VS/Xg==", + "dependencies": { + "@aws-crypto/sha256-browser": "3.0.0", + "@aws-crypto/sha256-js": "3.0.0", + "@aws-sdk/middleware-host-header": "3.425.0", + "@aws-sdk/middleware-logger": "3.425.0", + "@aws-sdk/middleware-recursion-detection": "3.425.0", + "@aws-sdk/middleware-user-agent": "3.427.0", + "@aws-sdk/region-config-resolver": "3.425.0", + "@aws-sdk/types": "3.425.0", + "@aws-sdk/util-endpoints": "3.427.0", + "@aws-sdk/util-user-agent-browser": "3.425.0", + "@aws-sdk/util-user-agent-node": "3.425.0", + "@smithy/config-resolver": "^2.0.11", + "@smithy/fetch-http-handler": "^2.2.1", + "@smithy/hash-node": "^2.0.10", + "@smithy/invalid-dependency": "^2.0.10", + "@smithy/middleware-content-length": "^2.0.12", + "@smithy/middleware-endpoint": "^2.0.10", + "@smithy/middleware-retry": "^2.0.13", + "@smithy/middleware-serde": "^2.0.10", + "@smithy/middleware-stack": "^2.0.4", + "@smithy/node-config-provider": "^2.0.13", + "@smithy/node-http-handler": "^2.1.6", + "@smithy/protocol-http": "^3.0.6", + "@smithy/smithy-client": "^2.1.9", + "@smithy/types": "^2.3.4", + "@smithy/url-parser": "^2.0.10", + "@smithy/util-base64": "^2.0.0", + "@smithy/util-body-length-browser": "^2.0.0", + "@smithy/util-body-length-node": "^2.1.0", + "@smithy/util-defaults-mode-browser": "^2.0.13", + "@smithy/util-defaults-mode-node": "^2.0.15", + "@smithy/util-retry": "^2.0.3", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-sts": { + "version": "3.427.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.427.0.tgz", + "integrity": "sha512-le2wLJKILyWuRfPz2HbyaNtu5kEki+ojUkTqCU6FPDRrqUvEkaaCBH9Awo/2AtrCfRkiobop8RuTTj6cAnpiJg==", + "dependencies": { + "@aws-crypto/sha256-browser": "3.0.0", + "@aws-crypto/sha256-js": "3.0.0", + "@aws-sdk/credential-provider-node": "3.427.0", + "@aws-sdk/middleware-host-header": "3.425.0", + "@aws-sdk/middleware-logger": "3.425.0", + "@aws-sdk/middleware-recursion-detection": "3.425.0", + "@aws-sdk/middleware-sdk-sts": "3.425.0", + "@aws-sdk/middleware-signing": "3.425.0", + "@aws-sdk/middleware-user-agent": "3.427.0", + "@aws-sdk/region-config-resolver": "3.425.0", + "@aws-sdk/types": "3.425.0", + "@aws-sdk/util-endpoints": "3.427.0", + "@aws-sdk/util-user-agent-browser": "3.425.0", + "@aws-sdk/util-user-agent-node": "3.425.0", + "@smithy/config-resolver": "^2.0.11", + "@smithy/fetch-http-handler": "^2.2.1", + "@smithy/hash-node": "^2.0.10", + "@smithy/invalid-dependency": "^2.0.10", + "@smithy/middleware-content-length": "^2.0.12", + "@smithy/middleware-endpoint": "^2.0.10", + "@smithy/middleware-retry": "^2.0.13", + "@smithy/middleware-serde": "^2.0.10", + "@smithy/middleware-stack": "^2.0.4", + "@smithy/node-config-provider": "^2.0.13", + "@smithy/node-http-handler": "^2.1.6", + "@smithy/protocol-http": "^3.0.6", + "@smithy/smithy-client": "^2.1.9", + "@smithy/types": "^2.3.4", + "@smithy/url-parser": "^2.0.10", + "@smithy/util-base64": "^2.0.0", + "@smithy/util-body-length-browser": "^2.0.0", + "@smithy/util-body-length-node": "^2.1.0", + "@smithy/util-defaults-mode-browser": "^2.0.13", + "@smithy/util-defaults-mode-node": "^2.0.15", + "@smithy/util-retry": "^2.0.3", + "@smithy/util-utf8": "^2.0.0", + "fast-xml-parser": "4.2.5", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-env": { + "version": "3.425.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.425.0.tgz", + "integrity": "sha512-J20etnLvMKXRVi5FK4F8yOCNm2RTaQn5psQTGdDEPWJNGxohcSpzzls8U2KcMyUJ+vItlrThr4qwgpHG3i/N0w==", + "dependencies": { + "@aws-sdk/types": "3.425.0", + "@smithy/property-provider": "^2.0.0", + "@smithy/types": "^2.3.4", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-ini": { + "version": "3.427.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.427.0.tgz", + "integrity": "sha512-NmH1cO/w98CKMltYec3IrJIIco19wRjATFNiw83c+FGXZ+InJwReqBnruxIOmKTx2KDzd6fwU1HOewS7UjaaaQ==", + "dependencies": { + "@aws-sdk/credential-provider-env": "3.425.0", + "@aws-sdk/credential-provider-process": "3.425.0", + "@aws-sdk/credential-provider-sso": "3.427.0", + "@aws-sdk/credential-provider-web-identity": "3.425.0", + "@aws-sdk/types": "3.425.0", + "@smithy/credential-provider-imds": "^2.0.0", + "@smithy/property-provider": "^2.0.0", + "@smithy/shared-ini-file-loader": "^2.0.6", + "@smithy/types": "^2.3.4", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-node": { + "version": "3.427.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.427.0.tgz", + "integrity": "sha512-wYYbQ57nKL8OfgRbl8k6uXcdnYml+p3LSSfDUAuUEp1HKlQ8lOXFJ3BdLr5qrk7LhpyppSRnWBmh2c3kWa7ANQ==", + "dependencies": { + "@aws-sdk/credential-provider-env": "3.425.0", + "@aws-sdk/credential-provider-ini": "3.427.0", + "@aws-sdk/credential-provider-process": "3.425.0", + "@aws-sdk/credential-provider-sso": "3.427.0", + "@aws-sdk/credential-provider-web-identity": "3.425.0", + "@aws-sdk/types": "3.425.0", + "@smithy/credential-provider-imds": "^2.0.0", + "@smithy/property-provider": "^2.0.0", + "@smithy/shared-ini-file-loader": "^2.0.6", + "@smithy/types": "^2.3.4", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-process": { + "version": "3.425.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.425.0.tgz", + "integrity": "sha512-YY6tkLdvtb1Fgofp3b1UWO+5vwS14LJ/smGmuGpSba0V7gFJRdcrJ9bcb9vVgAGuMdjzRJ+bUKlLLtqXkaykEw==", + "dependencies": { + "@aws-sdk/types": "3.425.0", + "@smithy/property-provider": "^2.0.0", + "@smithy/shared-ini-file-loader": "^2.0.6", + "@smithy/types": "^2.3.4", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-sso": { + "version": "3.427.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.427.0.tgz", + "integrity": "sha512-c+tXyS/i49erHs4bAp6vKNYeYlyQ0VNMBgoco0LCn1rL0REtHbfhWMnqDLF6c2n3yIWDOTrQu0D73Idnpy16eA==", + "dependencies": { + "@aws-sdk/client-sso": "3.427.0", + "@aws-sdk/token-providers": "3.427.0", + "@aws-sdk/types": "3.425.0", + "@smithy/property-provider": "^2.0.0", + "@smithy/shared-ini-file-loader": "^2.0.6", + "@smithy/types": "^2.3.4", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-web-identity": { + "version": "3.425.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.425.0.tgz", + "integrity": "sha512-/0R65TgRzL01JU3SzloivWNwdkbIhr06uY/F5pBHf/DynQqaspKNfdHn6AiozgSVDfwRHFjKBTUy6wvf3QFkuA==", + "dependencies": { + "@aws-sdk/types": "3.425.0", + "@smithy/property-provider": "^2.0.0", + "@smithy/types": "^2.3.4", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/middleware-host-header": { + "version": "3.425.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.425.0.tgz", + "integrity": "sha512-E5Gt41LObQ+cr8QnLthwsH3MtVSNXy1AKJMowDr85h0vzqA/FHUkgHyOGntgozzjXT5M0MaSRYxS0xwTR5D4Ew==", + "dependencies": { + "@aws-sdk/types": "3.425.0", + "@smithy/protocol-http": "^3.0.6", + "@smithy/types": "^2.3.4", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/middleware-logger": { + "version": "3.425.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.425.0.tgz", + "integrity": "sha512-INE9XWRXx2f4a/r2vOU0tAmgctVp7nEaEasemNtVBYhqbKLZvr9ndLBSgKGgJ8LIcXAoISipaMuFiqIGkFsm7A==", + "dependencies": { + "@aws-sdk/types": "3.425.0", + "@smithy/types": "^2.3.4", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/middleware-recursion-detection": { + "version": "3.425.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.425.0.tgz", + "integrity": "sha512-77gnzJ5b91bgD75L/ugpOyerx6lR3oyS4080X1YI58EzdyBMkDrHM4FbMcY2RynETi3lwXCFzLRyZjWXY1mRlw==", + "dependencies": { + "@aws-sdk/types": "3.425.0", + "@smithy/protocol-http": "^3.0.6", + "@smithy/types": "^2.3.4", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/middleware-sdk-sts": { + "version": "3.425.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-sts/-/middleware-sdk-sts-3.425.0.tgz", + "integrity": "sha512-JFojrg76oKAoBknnr9EL5N2aJ1mRCtBqXoZYST58GSx8uYdFQ89qS65VNQ8JviBXzsrCNAn4vDhZ5Ch5E6TxGQ==", + "dependencies": { + "@aws-sdk/middleware-signing": "3.425.0", + "@aws-sdk/types": "3.425.0", + "@smithy/types": "^2.3.4", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/middleware-signing": { + "version": "3.425.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-signing/-/middleware-signing-3.425.0.tgz", + "integrity": "sha512-ZpOfgJHk7ovQ0sSwg3tU4NxFOnz53lJlkJRf7S+wxQALHM0P2MJ6LYBrZaFMVsKiJxNIdZBXD6jclgHg72ZW6Q==", + "dependencies": { + "@aws-sdk/types": "3.425.0", + "@smithy/property-provider": "^2.0.0", + "@smithy/protocol-http": "^3.0.6", + "@smithy/signature-v4": "^2.0.0", + "@smithy/types": "^2.3.4", + "@smithy/util-middleware": "^2.0.3", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/middleware-user-agent": { + "version": "3.427.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.427.0.tgz", + "integrity": "sha512-y9HxYsNvnA3KqDl8w1jHeCwz4P9CuBEtu/G+KYffLeAMBsMZmh4SIkFFCO9wE/dyYg6+yo07rYcnnIfy7WA0bw==", + "dependencies": { + "@aws-sdk/types": "3.425.0", + "@aws-sdk/util-endpoints": "3.427.0", + "@smithy/protocol-http": "^3.0.6", + "@smithy/types": "^2.3.4", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/region-config-resolver": { + "version": "3.425.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.425.0.tgz", + "integrity": "sha512-u7uv/iUOapIJdRgRkO3wnpYsUgV6ponsZJQgVg/8L+n+Vo5PQL5gAcIuAOwcYSKQPFaeK+KbmByI4SyOK203Vw==", + "dependencies": { + "@smithy/node-config-provider": "^2.0.13", + "@smithy/types": "^2.3.4", + "@smithy/util-config-provider": "^2.0.0", + "@smithy/util-middleware": "^2.0.3", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/token-providers": { + "version": "3.427.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.427.0.tgz", + "integrity": "sha512-4E5E+4p8lJ69PBY400dJXF06LUHYx5lkKzBEsYqWWhoZcoftrvi24ltIhUDoGVLkrLcTHZIWSdFAWSos4hXqeg==", + "dependencies": { + "@aws-crypto/sha256-browser": "3.0.0", + "@aws-crypto/sha256-js": "3.0.0", + "@aws-sdk/middleware-host-header": "3.425.0", + "@aws-sdk/middleware-logger": "3.425.0", + "@aws-sdk/middleware-recursion-detection": "3.425.0", + "@aws-sdk/middleware-user-agent": "3.427.0", + "@aws-sdk/types": "3.425.0", + "@aws-sdk/util-endpoints": "3.427.0", + "@aws-sdk/util-user-agent-browser": "3.425.0", + "@aws-sdk/util-user-agent-node": "3.425.0", + "@smithy/config-resolver": "^2.0.11", + "@smithy/fetch-http-handler": "^2.2.1", + "@smithy/hash-node": "^2.0.10", + "@smithy/invalid-dependency": "^2.0.10", + "@smithy/middleware-content-length": "^2.0.12", + "@smithy/middleware-endpoint": "^2.0.10", + "@smithy/middleware-retry": "^2.0.13", + "@smithy/middleware-serde": "^2.0.10", + "@smithy/middleware-stack": "^2.0.4", + "@smithy/node-config-provider": "^2.0.13", + "@smithy/node-http-handler": "^2.1.6", + "@smithy/property-provider": "^2.0.0", + "@smithy/protocol-http": "^3.0.6", + "@smithy/shared-ini-file-loader": "^2.0.6", + "@smithy/smithy-client": "^2.1.9", + "@smithy/types": "^2.3.4", + "@smithy/url-parser": "^2.0.10", + "@smithy/util-base64": "^2.0.0", + "@smithy/util-body-length-browser": "^2.0.0", + "@smithy/util-body-length-node": "^2.1.0", + "@smithy/util-defaults-mode-browser": "^2.0.13", + "@smithy/util-defaults-mode-node": "^2.0.15", + "@smithy/util-retry": "^2.0.3", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/types": { + "version": "3.425.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.425.0.tgz", + "integrity": "sha512-6lqbmorwerN4v+J5dqbHPAsjynI0mkEF+blf+69QTaKKGaxBBVaXgqoqul9RXYcK5MMrrYRbQIMd0zYOoy90kA==", + "dependencies": { + "@smithy/types": "^2.3.4", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/util-endpoints": { + "version": "3.427.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.427.0.tgz", + "integrity": "sha512-rSyiAIFF/EVvity/+LWUqoTMJ0a25RAc9iqx0WZ4tf1UjuEXRRXxZEb+jEZg1bk+pY84gdLdx9z5E+MSJCZxNQ==", + "dependencies": { + "@aws-sdk/types": "3.425.0", + "@smithy/node-config-provider": "^2.0.13", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/util-locate-window": { + "version": "3.310.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.310.0.tgz", + "integrity": "sha512-qo2t/vBTnoXpjKxlsC2e1gBrRm80M3bId27r0BRB2VniSSe7bL1mmzM+/HFtujm0iAxtPM+aLEflLJlJeDPg0w==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/util-user-agent-browser": { + "version": "3.425.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.425.0.tgz", + "integrity": "sha512-22Y9iMtjGcFjGILR6/xdp1qRezlHVLyXtnpEsbuPTiernRCPk6zfAnK/ATH77r02MUjU057tdxVkd5umUBTn9Q==", + "dependencies": { + "@aws-sdk/types": "3.425.0", + "@smithy/types": "^2.3.4", + "bowser": "^2.11.0", + "tslib": "^2.5.0" + } + }, + "node_modules/@aws-sdk/util-user-agent-node": { + "version": "3.425.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.425.0.tgz", + "integrity": "sha512-SIR4F5uQeeVAi8lv4OgRirtdtNi5zeyogTuQgGi9su8F/WP1N6JqxofcwpUY5f8/oJ2UlXr/tx1f09UHfJJzvA==", + "dependencies": { + "@aws-sdk/types": "3.425.0", + "@smithy/node-config-provider": "^2.0.13", + "@smithy/types": "^2.3.4", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "aws-crt": ">=1.0.0" + }, + "peerDependenciesMeta": { + "aws-crt": { + "optional": true + } + } + }, + "node_modules/@aws-sdk/util-utf8-browser": { + "version": "3.259.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.259.0.tgz", + "integrity": "sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw==", + "dependencies": { + "tslib": "^2.3.1" + } + }, "node_modules/@babel/code-frame": { "version": "7.22.13", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", @@ -2345,6 +2903,513 @@ "@sinonjs/commons": "^3.0.0" } }, + "node_modules/@smithy/abort-controller": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-2.0.11.tgz", + "integrity": "sha512-MSzE1qR2JNyb7ot3blIOT3O3H0Jn06iNDEgHRaqZUwBgx5EG+VIx24Y21tlKofzYryIOcWpIohLrIIyocD6LMA==", + "dependencies": { + "@smithy/types": "^2.3.5", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/config-resolver": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-2.0.14.tgz", + "integrity": "sha512-K1K+FuWQoy8j/G7lAmK85o03O89s2Vvh6kMFmzEmiHUoQCRH1rzbDtMnGNiaMHeSeYJ6y79IyTusdRG+LuWwtg==", + "dependencies": { + "@smithy/node-config-provider": "^2.1.1", + "@smithy/types": "^2.3.5", + "@smithy/util-config-provider": "^2.0.0", + "@smithy/util-middleware": "^2.0.4", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/credential-provider-imds": { + "version": "2.0.16", + "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-2.0.16.tgz", + "integrity": "sha512-tKa2xF+69TvGxJT+lnJpGrKxUuAZDLYXFhqnPEgnHz+psTpkpcB4QRjHj63+uj83KaeFJdTfW201eLZeRn6FfA==", + "dependencies": { + "@smithy/node-config-provider": "^2.1.1", + "@smithy/property-provider": "^2.0.12", + "@smithy/types": "^2.3.5", + "@smithy/url-parser": "^2.0.11", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/eventstream-codec": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-2.0.11.tgz", + "integrity": "sha512-BQCTjxhCYRZIfXapa2LmZSaH8QUBGwMZw7XRN83hrdixbLjIcj+o549zjkedFS07Ve2TlvWUI6BTzP+nv7snBA==", + "dependencies": { + "@aws-crypto/crc32": "3.0.0", + "@smithy/types": "^2.3.5", + "@smithy/util-hex-encoding": "^2.0.0", + "tslib": "^2.5.0" + } + }, + "node_modules/@smithy/fetch-http-handler": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-2.2.2.tgz", + "integrity": "sha512-K7aRtRuaBjzlk+jWWeyfDTLAmRRvmA4fU8eHUXtjsuEDgi3f356ZE32VD2ssxIH13RCLVZbXMt5h7wHzYiSuVA==", + "dependencies": { + "@smithy/protocol-http": "^3.0.7", + "@smithy/querystring-builder": "^2.0.11", + "@smithy/types": "^2.3.5", + "@smithy/util-base64": "^2.0.0", + "tslib": "^2.5.0" + } + }, + "node_modules/@smithy/hash-node": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-2.0.11.tgz", + "integrity": "sha512-PbleVugN2tbhl1ZoNWVrZ1oTFFas/Hq+s6zGO8B9bv4w/StTriTKA9W+xZJACOj9X7zwfoTLbscM+avCB1KqOQ==", + "dependencies": { + "@smithy/types": "^2.3.5", + "@smithy/util-buffer-from": "^2.0.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/invalid-dependency": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-2.0.11.tgz", + "integrity": "sha512-zazq99ujxYv/NOf9zh7xXbNgzoVLsqE0wle8P/1zU/XdhPi/0zohTPKWUzIxjGdqb5hkkwfBkNkl5H+LE0mvgw==", + "dependencies": { + "@smithy/types": "^2.3.5", + "tslib": "^2.5.0" + } + }, + "node_modules/@smithy/is-array-buffer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.0.0.tgz", + "integrity": "sha512-z3PjFjMyZNI98JFRJi/U0nGoLWMSJlDjAW4QUX2WNZLas5C0CmVV6LJ01JI0k90l7FvpmixjWxPFmENSClQ7ug==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/middleware-content-length": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-2.0.13.tgz", + "integrity": "sha512-Md2kxWpaec3bXp1oERFPQPBhOXCkGSAF7uc1E+4rkwjgw3/tqAXRtbjbggu67HJdwaif76As8AV6XxbD1HzqTQ==", + "dependencies": { + "@smithy/protocol-http": "^3.0.7", + "@smithy/types": "^2.3.5", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/middleware-endpoint": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-2.0.11.tgz", + "integrity": "sha512-mCugsvB15up6fqpzUEpMT4CuJmFkEI+KcozA7QMzYguXCaIilyMKsyxgamwmr+o7lo3QdjN0//XLQ9bWFL129g==", + "dependencies": { + "@smithy/middleware-serde": "^2.0.11", + "@smithy/types": "^2.3.5", + "@smithy/url-parser": "^2.0.11", + "@smithy/util-middleware": "^2.0.4", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/middleware-retry": { + "version": "2.0.16", + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-2.0.16.tgz", + "integrity": "sha512-Br5+0yoiMS0ugiOAfJxregzMMGIRCbX4PYo1kDHtLgvkA/d++aHbnHB819m5zOIAMPvPE7AThZgcsoK+WOsUTA==", + "dependencies": { + "@smithy/node-config-provider": "^2.1.1", + "@smithy/protocol-http": "^3.0.7", + "@smithy/service-error-classification": "^2.0.4", + "@smithy/types": "^2.3.5", + "@smithy/util-middleware": "^2.0.4", + "@smithy/util-retry": "^2.0.4", + "tslib": "^2.5.0", + "uuid": "^8.3.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/middleware-retry/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/@smithy/middleware-serde": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-2.0.11.tgz", + "integrity": "sha512-NuxnjMyf4zQqhwwdh0OTj5RqpnuT6HcH5Xg5GrPijPcKzc2REXVEVK4Yyk8ckj8ez1XSj/bCmJ+oNjmqB02GWA==", + "dependencies": { + "@smithy/types": "^2.3.5", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/middleware-stack": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-2.0.5.tgz", + "integrity": "sha512-bVQU/rZzBY7CbSxIrDTGZYnBWKtIw+PL/cRc9B7etZk1IKSOe0NvKMJyWllfhfhrTeMF6eleCzOihIQympAvPw==", + "dependencies": { + "@smithy/types": "^2.3.5", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/node-config-provider": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-2.1.1.tgz", + "integrity": "sha512-1lF6s1YWBi1LBu2O30tD3jyTgMtuvk/Z1twzXM4GPYe4dmZix4nNREPJIPOcfFikNU2o0eTYP80+izx5F2jIJA==", + "dependencies": { + "@smithy/property-provider": "^2.0.12", + "@smithy/shared-ini-file-loader": "^2.2.0", + "@smithy/types": "^2.3.5", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/node-http-handler": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-2.1.7.tgz", + "integrity": "sha512-PQIKZXlp3awCDn/xNlCSTFE7aYG/5Tx33M05NfQmWYeB5yV1GZZOSz4dXpwiNJYTXb9jPqjl+ueXXkwtEluFFA==", + "dependencies": { + "@smithy/abort-controller": "^2.0.11", + "@smithy/protocol-http": "^3.0.7", + "@smithy/querystring-builder": "^2.0.11", + "@smithy/types": "^2.3.5", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/property-provider": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-2.0.12.tgz", + "integrity": "sha512-Un/OvvuQ1Kg8WYtoMCicfsFFuHb/TKL3pCA6ZIo/WvNTJTR94RtoRnL7mY4XkkUAoFMyf6KjcQJ76y1FX7S5rw==", + "dependencies": { + "@smithy/types": "^2.3.5", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/protocol-http": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-3.0.7.tgz", + "integrity": "sha512-HnZW8y+r66ntYueCDbLqKwWcMNWW8o3eVpSrHNluwtBJ/EUWfQHRKSiu6vZZtc6PGfPQWgVfucoCE/C3QufMAA==", + "dependencies": { + "@smithy/types": "^2.3.5", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/querystring-builder": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-2.0.11.tgz", + "integrity": "sha512-b4kEbVMxpmfv2VWUITn2otckTi7GlMteZQxi+jlwedoATOGEyrCJPfRcYQJjbCi3fZ2QTfh3PcORvB27+j38Yg==", + "dependencies": { + "@smithy/types": "^2.3.5", + "@smithy/util-uri-escape": "^2.0.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/querystring-parser": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-2.0.11.tgz", + "integrity": "sha512-YXe7jhi7s3dQ0Fu9dLoY/gLu6NCyy8tBWJL/v2c9i7/RLpHgKT+uT96/OqZkHizCJ4kr0ZD46tzMjql/o60KLg==", + "dependencies": { + "@smithy/types": "^2.3.5", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/service-error-classification": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-2.0.4.tgz", + "integrity": "sha512-77506l12I5gxTZqBkx3Wb0RqMG81bMYLaVQ+EqIWFwQDJRs5UFeXogKxSKojCmz1wLUziHZQXm03MBzPQiumQw==", + "dependencies": { + "@smithy/types": "^2.3.5" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/shared-ini-file-loader": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-2.2.0.tgz", + "integrity": "sha512-xFXqs4vAb5BdkzHSRrTapFoaqS4/3m/CGZzdw46fBjYZ0paYuLAoMY60ICCn1FfGirG+PiJ3eWcqJNe4/SkfyA==", + "dependencies": { + "@smithy/types": "^2.3.5", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/signature-v4": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-2.0.11.tgz", + "integrity": "sha512-EFVU1dT+2s8xi227l1A9O27edT/GNKvyAK6lZnIZ0zhIHq/jSLznvkk15aonGAM1kmhmZBVGpI7Tt0odueZK9A==", + "dependencies": { + "@smithy/eventstream-codec": "^2.0.11", + "@smithy/is-array-buffer": "^2.0.0", + "@smithy/types": "^2.3.5", + "@smithy/util-hex-encoding": "^2.0.0", + "@smithy/util-middleware": "^2.0.4", + "@smithy/util-uri-escape": "^2.0.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/smithy-client": { + "version": "2.1.10", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-2.1.10.tgz", + "integrity": "sha512-2OEmZDiW1Z196QHuQZ5M6cBE8FCSG0H2HADP1G+DY8P3agsvb0YJyfhyKuJbxIQy15tr3eDAK6FOrlbxgKOOew==", + "dependencies": { + "@smithy/middleware-stack": "^2.0.5", + "@smithy/types": "^2.3.5", + "@smithy/util-stream": "^2.0.15", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/types": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.3.5.tgz", + "integrity": "sha512-ehyDt8M9hehyxrLQGoA1BGPou8Js1Ocoh5M0ngDhJMqbFmNK5N6Xhr9/ZExWkyIW8XcGkiMPq3ZUEE0ScrhbuQ==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/url-parser": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-2.0.11.tgz", + "integrity": "sha512-h89yXMCCF+S5k9XIoKltMIWTYj+FcEkU/IIFZ6RtE222fskOTL4Iak6ZRG+ehSvZDt8yKEcxqheTDq7JvvtK3g==", + "dependencies": { + "@smithy/querystring-parser": "^2.0.11", + "@smithy/types": "^2.3.5", + "tslib": "^2.5.0" + } + }, + "node_modules/@smithy/util-base64": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-2.0.0.tgz", + "integrity": "sha512-Zb1E4xx+m5Lud8bbeYi5FkcMJMnn+1WUnJF3qD7rAdXpaL7UjkFQLdmW5fHadoKbdHpwH9vSR8EyTJFHJs++tA==", + "dependencies": { + "@smithy/util-buffer-from": "^2.0.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/util-body-length-browser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-2.0.0.tgz", + "integrity": "sha512-JdDuS4ircJt+FDnaQj88TzZY3+njZ6O+D3uakS32f2VNnDo3vyEuNdBOh/oFd8Df1zSZOuH1HEChk2AOYDezZg==", + "dependencies": { + "tslib": "^2.5.0" + } + }, + "node_modules/@smithy/util-body-length-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-2.1.0.tgz", + "integrity": "sha512-/li0/kj/y3fQ3vyzn36NTLGmUwAICb7Jbe/CsWCktW363gh1MOcpEcSO3mJ344Gv2dqz8YJCLQpb6hju/0qOWw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/util-buffer-from": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.0.0.tgz", + "integrity": "sha512-/YNnLoHsR+4W4Vf2wL5lGv0ksg8Bmk3GEGxn2vEQt52AQaPSCuaO5PM5VM7lP1K9qHRKHwrPGktqVoAHKWHxzw==", + "dependencies": { + "@smithy/is-array-buffer": "^2.0.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/util-config-provider": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-2.0.0.tgz", + "integrity": "sha512-xCQ6UapcIWKxXHEU4Mcs2s7LcFQRiU3XEluM2WcCjjBtQkUN71Tb+ydGmJFPxMUrW/GWMgQEEGipLym4XG0jZg==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/util-defaults-mode-browser": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-2.0.14.tgz", + "integrity": "sha512-NupG7SWUucm3vJrvlpt9jG1XeoPJphjcivgcUUXhDJbUPy4F04LhlTiAhWSzwlCNcF8OJsMvZ/DWbpYD3pselw==", + "dependencies": { + "@smithy/property-provider": "^2.0.12", + "@smithy/smithy-client": "^2.1.10", + "@smithy/types": "^2.3.5", + "bowser": "^2.11.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@smithy/util-defaults-mode-node": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-2.0.18.tgz", + "integrity": "sha512-+3jMom/b/Cdp21tDnY4vKu249Al+G/P0HbRbct7/aSZDlROzv1tksaYukon6UUv7uoHn+/McqnsvqZHLlqvQ0g==", + "dependencies": { + "@smithy/config-resolver": "^2.0.14", + "@smithy/credential-provider-imds": "^2.0.16", + "@smithy/node-config-provider": "^2.1.1", + "@smithy/property-provider": "^2.0.12", + "@smithy/smithy-client": "^2.1.10", + "@smithy/types": "^2.3.5", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@smithy/util-hex-encoding": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-2.0.0.tgz", + "integrity": "sha512-c5xY+NUnFqG6d7HFh1IFfrm3mGl29lC+vF+geHv4ToiuJCBmIfzx6IeHLg+OgRdPFKDXIw6pvi+p3CsscaMcMA==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/util-middleware": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-2.0.4.tgz", + "integrity": "sha512-Pbu6P4MBwRcjrLgdTR1O4Y3c0sTZn2JdOiJNcgL7EcIStcQodj+6ZTXtbyU/WTEU3MV2NMA10LxFc3AWHZ3+4A==", + "dependencies": { + "@smithy/types": "^2.3.5", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/util-retry": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-2.0.4.tgz", + "integrity": "sha512-b+n1jBBKc77C1E/zfBe1Zo7S9OXGBiGn55N0apfhZHxPUP/fMH5AhFUUcWaJh7NAnah284M5lGkBKuhnr3yK5w==", + "dependencies": { + "@smithy/service-error-classification": "^2.0.4", + "@smithy/types": "^2.3.5", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@smithy/util-stream": { + "version": "2.0.15", + "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-2.0.15.tgz", + "integrity": "sha512-A/hkYJPH2N5MCWYvky4tTpQihpYAEzqnUfxDyG3L/yMndy/2sLvxnyQal9Opuj1e9FiKSTeMyjnU9xxZGs0mRw==", + "dependencies": { + "@smithy/fetch-http-handler": "^2.2.2", + "@smithy/node-http-handler": "^2.1.7", + "@smithy/types": "^2.3.5", + "@smithy/util-base64": "^2.0.0", + "@smithy/util-buffer-from": "^2.0.0", + "@smithy/util-hex-encoding": "^2.0.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/util-uri-escape": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-2.0.0.tgz", + "integrity": "sha512-ebkxsqinSdEooQduuk9CbKcI+wheijxEb3utGXkCoYQkJnwTnLbH1JXGimJtUkQwNQbsbuYwG2+aFVyZf5TLaw==", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/util-utf8": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.0.0.tgz", + "integrity": "sha512-rctU1VkziY84n5OXe3bPNpKR001ZCME2JCaBBFgtiM2hfKbHFudc/BkMuPab8hRbLd0j3vbnBTTZ1igBf0wgiQ==", + "dependencies": { + "@smithy/util-buffer-from": "^2.0.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/util-waiter": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-2.0.11.tgz", + "integrity": "sha512-8SJWUl9O1YhjC77EccgltI3q4XZQp3vp9DGEW6o0OdkUcwqm/H4qOLnMkA2n+NDojuM5Iia2jWoCdbluIiG7TA==", + "dependencies": { + "@smithy/abort-controller": "^2.0.11", + "@smithy/types": "^2.3.5", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@sqltools/formatter": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/@sqltools/formatter/-/formatter-1.2.5.tgz", @@ -3104,6 +4169,11 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, + "node_modules/bowser": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.11.0.tgz", + "integrity": "sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==" + }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -4075,6 +5145,27 @@ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" }, + "node_modules/fast-xml-parser": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.2.5.tgz", + "integrity": "sha512-B9/wizE4WngqQftFPmdaMYlXoJlJOYxGQOanC77fq9k8+Z0v5dDSVh+3glErdIROP//s/jgb7ZuxKfB8nVyo0g==", + "funding": [ + { + "type": "paypal", + "url": "https://paypal.me/naturalintelligence" + }, + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "dependencies": { + "strnum": "^1.0.5" + }, + "bin": { + "fxparser": "src/cli/cli.js" + } + }, "node_modules/fb-watchman": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", @@ -7007,6 +8098,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/strnum": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", + "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==" + }, "node_modules/supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", diff --git a/package.json b/package.json index a29f8bb5..5816ddd2 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "build": "tsc --project ." }, "dependencies": { + "@aws-sdk/client-cloudwatch": "^3.427.0", "@types/express-fileupload": "^1.4.2", "aws-sdk": "^2.1472.0", "bcrypt": "^5.1.1", diff --git a/src/utilites/AWS_confugure_CloudWatch.ts b/src/utilites/AWS_confugure_CloudWatch.ts new file mode 100644 index 00000000..e92f62ae --- /dev/null +++ b/src/utilites/AWS_confugure_CloudWatch.ts @@ -0,0 +1,22 @@ +import AWS from 'aws-sdk'; + +const configureCloudWatch = async () => { + const accessKeyId = process.env.AWS_ACCESS_KEY_ID; + const secretAccessKey = process.env.AWS_SECRET_ACCESS_KEY; + + if (!accessKeyId || !secretAccessKey) { + throw 'AWS information to concent are missing :(' + } + + AWS.config.update({ + credentials: { + accessKeyId, + secretAccessKey, + }, + region: process.env.AWS_REGION, + }); + + return new AWS.CloudWatchLogs(); +} + +export { configureCloudWatch }; From 6e16ecb4d2e37a2225170b74f0bda9048ac7f6aa Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Tue, 10 Oct 2023 20:34:16 +0300 Subject: [PATCH 113/146] Creat AWS Cloud Watch controller --- src/controllers/cloudWatch-logger.ts | 40 +++++++++++++++++++ .../{logs.ts => dataBase-logger.ts} | 0 src/middleware/auth/authenticate.ts | 2 +- src/middleware/auth/authorize.ts | 2 +- .../validation/organizationAdmin.ts | 2 +- .../validation/organizationProfile.ts | 2 +- src/middleware/validation/permission.ts | 2 +- src/middleware/validation/role.ts | 2 +- src/middleware/validation/voluntaryWork.ts | 2 +- src/middleware/validation/volunteer.ts | 2 +- src/routes/organizationAdmin.ts | 2 +- src/routes/organizationProfile.ts | 2 +- src/routes/permission.ts | 2 +- src/routes/role.ts | 2 +- src/routes/voluntaryWork.ts | 2 +- src/routes/volunteer.ts | 2 +- ...udWatch.ts => AWS_configure_CloudWatch.ts} | 0 17 files changed, 54 insertions(+), 14 deletions(-) create mode 100644 src/controllers/cloudWatch-logger.ts rename src/controllers/{logs.ts => dataBase-logger.ts} (100%) rename src/utilites/{AWS_confugure_CloudWatch.ts => AWS_configure_CloudWatch.ts} (100%) diff --git a/src/controllers/cloudWatch-logger.ts b/src/controllers/cloudWatch-logger.ts new file mode 100644 index 00000000..ddfbfdcf --- /dev/null +++ b/src/controllers/cloudWatch-logger.ts @@ -0,0 +1,40 @@ +import { configureCloudWatch } from '../utilites/AWS_configure_CloudWatch.js'; + +const cloudWatchLogs = await configureCloudWatch(); + +if (!cloudWatchLogs) { + throw new Error('CloudWatch Logs initialization failed!'); +} + +export const logToCloudWatch = async (logGroupName:string, logStreamName:string, logMessage:string, id:string, name:string) => { + const logEvent = { + message: `${logMessage}\n- User ID: ${id}, User Name: ${name}`, + timestamp: new Date().getTime(), + }; + + const params = { + logGroupName: logGroupName, + logStreamName: logStreamName, + logEvents: [logEvent], + }; + + try { + await cloudWatchLogs.putLogEvents(params).promise(); + console.log('Log event sent successfully'); + } catch (error) { + console.error('Error sending log event:', error); + } +}; + +// await logToCloudWatch( +// 'failed', +// '', +// 'Volunteer registered successfully!' +// ); +// +// await logToCloudWatch( +// 'success', +// '', +// 'Volunteer registered successfully!' +// ); +// diff --git a/src/controllers/logs.ts b/src/controllers/dataBase-logger.ts similarity index 100% rename from src/controllers/logs.ts rename to src/controllers/dataBase-logger.ts diff --git a/src/middleware/auth/authenticate.ts b/src/middleware/auth/authenticate.ts index 1064c3bc..221eafa3 100644 --- a/src/middleware/auth/authenticate.ts +++ b/src/middleware/auth/authenticate.ts @@ -4,7 +4,7 @@ import { OrganizationAdmin } from '../../db/entities/OrganizationAdmin.js'; import { Volunteer } from '../../db/entities/Volunteer.js'; import createError from 'http-errors'; import { NSLogs } from '../../../types/logs.js'; -import { log } from '../../controllers/logs.js'; +import { log } from '../../controllers/dataBase-logger.js'; const authenticate = async ( req: express.Request, diff --git a/src/middleware/auth/authorize.ts b/src/middleware/auth/authorize.ts index b63de56d..faa6ee26 100644 --- a/src/middleware/auth/authorize.ts +++ b/src/middleware/auth/authorize.ts @@ -4,7 +4,7 @@ import { OrganizationAdmin } from '../../db/entities/OrganizationAdmin.js'; import { Volunteer } from '../../db/entities/Volunteer.js'; import { VoluntaryWork } from '../../db/entities/VoluntaryWork.js'; import createError from 'http-errors'; -import { log } from '../../controllers/logs.js'; +import { log } from '../../controllers/dataBase-logger.js'; import { NSLogs } from '../../../types/logs.js'; const authorize = (api: string) => { diff --git a/src/middleware/validation/organizationAdmin.ts b/src/middleware/validation/organizationAdmin.ts index 2964926a..85a0bb86 100644 --- a/src/middleware/validation/organizationAdmin.ts +++ b/src/middleware/validation/organizationAdmin.ts @@ -4,7 +4,7 @@ import { isValidPassword } from '../../controllers/index.js'; import { OrganizationAdmin } from '../../db/entities/OrganizationAdmin.js'; import createError from 'http-errors'; import { NSLogs } from '../../../types/logs.js'; -import { log } from '../../controllers/logs.js'; +import { log } from '../../controllers/dataBase-logger.js'; const validateOrganizationAdmin = (req: express.Request, diff --git a/src/middleware/validation/organizationProfile.ts b/src/middleware/validation/organizationProfile.ts index 2af1d717..1b698510 100644 --- a/src/middleware/validation/organizationProfile.ts +++ b/src/middleware/validation/organizationProfile.ts @@ -2,7 +2,7 @@ import express from 'express'; import { OrganizationProfile } from '../../db/entities/OrganizationProfile.js'; import createError from 'http-errors'; import { NSLogs } from '../../../types/logs.js'; -import { log } from '../../controllers/logs.js'; +import { log } from '../../controllers/dataBase-logger.js'; const validateOrganizationProfile = (req: express.Request, res: express.Response, diff --git a/src/middleware/validation/permission.ts b/src/middleware/validation/permission.ts index ae426885..b072cbdc 100644 --- a/src/middleware/validation/permission.ts +++ b/src/middleware/validation/permission.ts @@ -2,7 +2,7 @@ import express from 'express'; import { Permission } from '../../db/entities/Permission.js'; import createError from 'http-errors'; import { NSLogs } from '../../../types/logs.js'; -import { log } from '../../controllers/logs.js'; +import { log } from '../../controllers/dataBase-logger.js'; const validatePermission = (req: express.Request, res: express.Response, diff --git a/src/middleware/validation/role.ts b/src/middleware/validation/role.ts index fdadd622..11fd1264 100644 --- a/src/middleware/validation/role.ts +++ b/src/middleware/validation/role.ts @@ -2,7 +2,7 @@ import express from 'express'; import { Role } from '../../db/entities/Role.js'; import createError from 'http-errors'; import { NSLogs } from '../../../types/logs.js'; -import { log } from '../../controllers/logs.js'; +import { log } from '../../controllers/dataBase-logger.js'; const validateRole = (req: express.Request, res: express.Response, diff --git a/src/middleware/validation/voluntaryWork.ts b/src/middleware/validation/voluntaryWork.ts index 214595a9..0ac69bd7 100644 --- a/src/middleware/validation/voluntaryWork.ts +++ b/src/middleware/validation/voluntaryWork.ts @@ -5,7 +5,7 @@ import { getDate, isValidDate } from '../../controllers/index.js'; import { VoluntaryWork } from '../../db/entities/VoluntaryWork.js'; import createError from 'http-errors'; import { NSLogs } from '../../../types/logs.js'; -import { log } from '../../controllers/logs.js'; +import { log } from '../../controllers/dataBase-logger.js'; const validateVoluntaryWork = (req: express.Request, res: express.Response, diff --git a/src/middleware/validation/volunteer.ts b/src/middleware/validation/volunteer.ts index 0bc7ab0b..42a40d7f 100644 --- a/src/middleware/validation/volunteer.ts +++ b/src/middleware/validation/volunteer.ts @@ -5,7 +5,7 @@ import { NSVolunteer } from '../../../types/volunteer.js'; import { Volunteer } from '../../db/entities/Volunteer.js'; import createError from 'http-errors' import { NSLogs } from '../../../types/logs.js'; -import { log } from '../../controllers/logs.js'; +import { log } from '../../controllers/dataBase-logger.js'; const validateVolunteer = (req: express.Request, res: express.Response, next: express.NextFunction) => { diff --git a/src/routes/organizationAdmin.ts b/src/routes/organizationAdmin.ts index 153112c4..5047b9ca 100644 --- a/src/routes/organizationAdmin.ts +++ b/src/routes/organizationAdmin.ts @@ -2,7 +2,7 @@ import express from "express"; import { createOrganizationAdmin, deleteOrganizationAdmin, editOrganizationAdmin, getOrganizationAdmins } from "../controllers/organizationAdmin.js"; import { authorize, checkMe } from "../middleware/auth/authorize.js"; import { validateAdminEdited, validateAdminId, validateOrganizationAdmin } from "../middleware/validation/organizationAdmin.js"; -import { log } from "../controllers/logs.js"; +import { log } from "../controllers/dataBase-logger.js"; import { NSLogs } from "../../types/logs.js"; const router = express.Router(); diff --git a/src/routes/organizationProfile.ts b/src/routes/organizationProfile.ts index eec51e2e..afbe72a3 100644 --- a/src/routes/organizationProfile.ts +++ b/src/routes/organizationProfile.ts @@ -2,7 +2,7 @@ import express from "express"; import { createOrganizationProfile, deleteOrganizationProfile, editOrganizationProfile, getOrganizationProfile } from "../controllers/OrganizationProfile .js"; import { authorize, checkAdmin } from "../middleware/auth/authorize.js"; import { validateOrgId, validateOrganizationProfile } from "../middleware/validation/organizationProfile.js"; -import { log } from "../controllers/logs.js"; +import { log } from "../controllers/dataBase-logger.js"; import { NSLogs } from "../../types/logs.js"; const router = express.Router(); diff --git a/src/routes/permission.ts b/src/routes/permission.ts index 665c508b..a3d81ce4 100644 --- a/src/routes/permission.ts +++ b/src/routes/permission.ts @@ -2,7 +2,7 @@ import express from 'express'; import { createPermission, deletePermission, editPermission, getPermissions } from '../controllers/permission.js'; import { authorize } from '../middleware/auth/authorize.js'; import { validatePermission, validatePermissionId } from '../middleware/validation/permission.js'; -import { log } from '../controllers/logs.js'; +import { log } from '../controllers/dataBase-logger.js'; import { NSLogs } from '../../types/logs.js'; var router = express.Router(); diff --git a/src/routes/role.ts b/src/routes/role.ts index 9c375e7e..4e02bfee 100644 --- a/src/routes/role.ts +++ b/src/routes/role.ts @@ -3,7 +3,7 @@ import { createRole, deleteRole, editRole, getRoles } from '../controllers/role. import { NSRole } from '../../types/role.js'; import { authorize } from '../middleware/auth/authorize.js'; import { validateEditedRole, validateRole, validateRoleId } from '../middleware/validation/role.js'; -import { log } from '../controllers/logs.js'; +import { log } from '../controllers/dataBase-logger.js'; import { NSLogs } from '../../types/logs.js'; var router = express.Router(); diff --git a/src/routes/voluntaryWork.ts b/src/routes/voluntaryWork.ts index f3ea647a..9fc4ffc1 100644 --- a/src/routes/voluntaryWork.ts +++ b/src/routes/voluntaryWork.ts @@ -5,7 +5,7 @@ import { NSVoluntaryWork } from '../../types/voluntaryWork.js'; import { authorize, checkParticipation } from '../middleware/auth/authorize.js'; import { validateEditedVoluntaryWork, validateVoluntaryWork, validateVoluntaryWorkId } from '../middleware/validation/voluntaryWork.js'; import { UploadedFile } from 'express-fileupload'; -import { log } from '../controllers/logs.js'; +import { log } from '../controllers/dataBase-logger.js'; import { NSLogs } from '../../types/logs.js'; var router = express.Router(); diff --git a/src/routes/volunteer.ts b/src/routes/volunteer.ts index ba3a1213..12a21c6a 100644 --- a/src/routes/volunteer.ts +++ b/src/routes/volunteer.ts @@ -4,7 +4,7 @@ import { authenticate } from '../middleware/auth/authenticate.js'; import { validateEditedVolunteer, validateVolunteer } from '../middleware/validation/volunteer.js'; import { createVolunteer, deleteVolunteer, editVolunteer, getVolunteers, login } from '../controllers/volunteer.js'; import { NSVolunteer } from '../../types/volunteer.js'; -import { log } from '../controllers/logs.js'; +import { log } from '../controllers/dataBase-logger.js'; import { NSLogs } from '../../types/logs.js'; var router = express.Router(); diff --git a/src/utilites/AWS_confugure_CloudWatch.ts b/src/utilites/AWS_configure_CloudWatch.ts similarity index 100% rename from src/utilites/AWS_confugure_CloudWatch.ts rename to src/utilites/AWS_configure_CloudWatch.ts From a3fcd3f72d3cc94aed8cb1e1d6b52cd57666dc6e Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Tue, 10 Oct 2023 21:39:02 +0300 Subject: [PATCH 114/146] Creat migration files --- package-lock.json | 155 +++++++++++++++++- package.json | 3 +- src/db/dataSource.ts | 10 +- .../1696962955556-CreatePermissions.ts | 85 ++++++++++ src/db/migration/1696963025886-CreateRoles.ts | 133 +++++++++++++++ src/db/migration/1696963078357-CreateRoot.ts | 31 ++++ 6 files changed, 410 insertions(+), 7 deletions(-) create mode 100644 src/db/migration/1696962955556-CreatePermissions.ts create mode 100644 src/db/migration/1696963025886-CreateRoles.ts create mode 100644 src/db/migration/1696963078357-CreateRoot.ts diff --git a/package-lock.json b/package-lock.json index 7b2dff88..16c8a7f7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -37,7 +37,8 @@ "@types/morgan": "^1.9.6", "@types/node": "^20.5.6", "concurrently": "^8.2.1", - "nodemon": "^3.0.1" + "nodemon": "^3.0.1", + "ts-node": "^10.9.1" } }, "node_modules/@ampproject/remapping": { @@ -1957,6 +1958,28 @@ "node": ">=0.1.90" } }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "devOptional": true, + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "devOptional": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, "node_modules/@dabh/diagnostics": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz", @@ -2350,6 +2373,30 @@ "resolved": "https://registry.npmjs.org/@sqltools/formatter/-/formatter-1.2.5.tgz", "integrity": "sha512-Uy0+khmZqUrUGm5dmMqVlnvufZRSK0FbYzVgp0UMstm+F5+W2/jnEEQyc9vo1ZR/E5ZI/B1WjjoTqBqwJL6Krw==" }, + "node_modules/@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "devOptional": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "devOptional": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "devOptional": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "devOptional": true + }, "node_modules/@types/babel__core": { "version": "7.20.2", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.2.tgz", @@ -2621,6 +2668,15 @@ "acorn": "^2.1.0" } }, + "node_modules/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "devOptional": true, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/agent-base": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", @@ -2765,6 +2821,12 @@ "node": ">= 6" } }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "devOptional": true + }, "node_modules/argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -3675,6 +3737,12 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "devOptional": true + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -3805,6 +3873,15 @@ "node": ">=8" } }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "devOptional": true, + "engines": { + "node": ">=0.3.1" + } + }, "node_modules/diff-sequences": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", @@ -5664,6 +5741,12 @@ "semver": "bin/semver.js" } }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "devOptional": true + }, "node_modules/makeerror": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", @@ -7227,6 +7310,61 @@ "node": ">= 14.0.0" } }, + "node_modules/ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "devOptional": true, + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/ts-node/node_modules/acorn": { + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", + "devOptional": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/tslib": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", @@ -7642,6 +7780,12 @@ "uuid": "dist/bin/uuid" } }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "devOptional": true + }, "node_modules/v8-to-istanbul": { "version": "9.1.3", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.3.tgz", @@ -7920,6 +8064,15 @@ "node": ">=12" } }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "devOptional": true, + "engines": { + "node": ">=6" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index a29f8bb5..9050729b 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,7 @@ "@types/morgan": "^1.9.6", "@types/node": "^20.5.6", "concurrently": "^8.2.1", - "nodemon": "^3.0.1" + "nodemon": "^3.0.1", + "ts-node": "^10.9.1" } } diff --git a/src/db/dataSource.ts b/src/db/dataSource.ts index 215aec0d..8789ca97 100644 --- a/src/db/dataSource.ts +++ b/src/db/dataSource.ts @@ -11,11 +11,11 @@ import { Logs } from "./entities/Logs.js"; const dataSource = new DataSource({ type: 'mysql', - host: process.env.DB_HOST, - port: Number(process.env.DB_PORT), - username: process.env.DB_USERNAME, - password: process.env.DB_PASSWORD, - database: process.env.DB_NAME, + host: "localhost"||process.env.DB_HOST, + port: 3306||Number(process.env.DB_PORT), + username: "root"||process.env.DB_USERNAME, + password:""|| process.env.DB_PASSWORD, + database:"Serve-and-Shine"|| process.env.DB_NAME, entities: [OrganizationAdmin, OrganizationProfile, Permission, Role, SkillTag, VoluntaryWork, Volunteer, VolunteerProfile, Logs], migrations: ['./**/migration/*.ts'], diff --git a/src/db/migration/1696962955556-CreatePermissions.ts b/src/db/migration/1696962955556-CreatePermissions.ts new file mode 100644 index 00000000..a874f85e --- /dev/null +++ b/src/db/migration/1696962955556-CreatePermissions.ts @@ -0,0 +1,85 @@ +import { MigrationInterface, QueryRunner } from "typeorm" + +export class CreatePermissions1696962955556 implements MigrationInterface { + + // creat permaissions + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + INSERT INTO permission (name, createdAt) + VALUES + ('GET_me', NOW()), + ('GET_volunteers', NOW()), + ('PUT_volunteer', NOW()), + ('DELETE_volunteer', NOW()), + ('GET_organizationAdmins', NOW()), + ('POST_organizationAdmin', NOW()), + ('PUT_organizationAdmin', NOW()), + ('DELETE_organizationAdmin', NOW()), + ('GET_organizationProfiles', NOW()), + ('POST_organizationProfile', NOW()), + ('PUT_organizationProfile', NOW()), + ('DELETE_organizationProfile', NOW()), + ('GET_voluntaryWorks', NOW()), + ('POST_voluntaryWork', NOW()), + ('PUT_voluntaryWork', NOW()), + ('REGISTER_voluntaryWork', NOW()), + ('DEREGISTER_voluntaryWork', NOW()), + ('DELETE_voluntaryWork', NOW()), + ('GET_recommendation', NOW()), + ('GET_analysis', NOW()), + ('PUT_rating', NOW()), + ('PUT_feedback', NOW()), + ('PUT_images', NOW()), + ('GET_permissions', NOW()), + ('POST_permission', NOW()), + ('PUT_permission', NOW()), + ('DELETE_permission', NOW()), + ('GET_roles', NOW()), + ('POST_role', NOW()), + ('PUT_role', NOW()), + ('DELETE_role', NOW()) + `); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + DELETE FROM permission + WHERE name IN ( + 'GET_me', + 'GET_volunteers', + 'PUT_volunteer', + 'DELETE_volunteer', + 'GET_organizationAdmins', + 'POST_organizationAdmin', + 'PUT_organizationAdmin', + 'DELETE_organizationAdmin', + 'GET_organizationProfiles', + 'POST_organizationProfile', + 'PUT_organizationProfile', + 'DELETE_organizationProfile', + 'GET_voluntaryWorks', + 'POST_voluntaryWork', + 'PUT_voluntaryWork', + 'REGISTER_voluntaryWork', + 'DEREGISTER_voluntaryWork', + 'DELETE_voluntaryWork', + 'GET_recommendation', + 'GET_analysis', + 'PUT_rating', + 'PUT_feedback', + 'PUT_images', + 'GET_permissions', + 'POST_permission', + 'PUT_permission', + 'DELETE_permission', + 'GET_roles', + 'POST_role', + 'PUT_role', + 'DELETE_role' + ) + `); + } +} + + diff --git a/src/db/migration/1696963025886-CreateRoles.ts b/src/db/migration/1696963025886-CreateRoles.ts new file mode 100644 index 00000000..e3869ab5 --- /dev/null +++ b/src/db/migration/1696963025886-CreateRoles.ts @@ -0,0 +1,133 @@ +import { MigrationInterface, QueryRunner } from "typeorm" + +export class CreateRoles1696963025886 implements MigrationInterface { + +// for permissions + +public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + INSERT INTO role (name) + VALUES ('root') + `); + + const result = await queryRunner.query(` + SELECT id FROM role WHERE name = 'root' + `); + + const roleId = result[0].id; + const permissionIds = [ + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 + ]; + + for (const permissionId of permissionIds) { + await queryRunner.query(` + INSERT INTO role_permissions_permission (roleId, permissionId) + VALUES (${roleId}, ${permissionId}) + `); + } + + await queryRunner.query(` + INSERT INTO role (name) + VALUES ('admin') +`); + +// Get the ID of the inserted 'admin' role +const adminRoleId = (await queryRunner.query(` + SELECT id FROM role WHERE name = 'admin' +`))[0].id; + +// Insert permissions for the 'admin' role +const adminPermissionIds = [1, 2, 3, 4, 5, 9, 13, 14, 16, 17]; + +for (const permissionId of adminPermissionIds) { + await queryRunner.query(` + INSERT INTO role_permissions_permission (roleId, permissionId) + VALUES (${adminRoleId}, ${permissionId}) + `); +} + +await queryRunner.query(` + INSERT INTO role (name) + VALUES ('premium') +`); + +const premiumRoleId = (await queryRunner.query(` + SELECT id FROM role WHERE name = 'premium' +`))[0].id; + +const premiumPermissionIds = [1, 2, 5, 9, 13, 14, 16, 17, 19, 21, 22]; + +for (const permissionId of premiumPermissionIds) { + await queryRunner.query(` + INSERT INTO role_permissions_permission (roleId, permissionId) + VALUES (${premiumRoleId}, ${permissionId}) + `); +} + +// Insert the 'volunteer' role +await queryRunner.query(` + INSERT INTO role (name) + VALUES ('volunteer') +`); + +// Get the ID of the inserted 'volunteer' role +const volunteerRoleId = (await queryRunner.query(` + SELECT id FROM role WHERE name = 'volunteer' +`))[0].id; + +// Insert permissions for the 'volunteer' role +const volunteerPermissionIds = [1, 2, 5, 9, 13, 16, 17, 19, 21, 22]; + +for (const permissionId of volunteerPermissionIds) { + await queryRunner.query(` + INSERT INTO role_permissions_permission (roleId, permissionId) + VALUES (${volunteerRoleId}, ${permissionId}) + `); +} +} + +public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + DELETE FROM role WHERE name = 'root' +`); + + const permissionIdsToDelete = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]; + + for (const permissionId of permissionIdsToDelete) { + await queryRunner.query(` + DELETE FROM role_permissions_permission + WHERE roleId = (SELECT id FROM role WHERE name = 'root') AND permissionId = ${permissionId} + `); + } + await queryRunner.query(` + DELETE FROM role_permissions_permission + WHERE roleId = (SELECT id FROM role WHERE name = 'admin') +`); + +await queryRunner.query(` + DELETE FROM role WHERE name = 'admin' +`); + +// Delete the 'premium' role and its associated permissions +await queryRunner.query(` + DELETE FROM role_permissions_permission + WHERE roleId = (SELECT id FROM role WHERE name = 'premium') +`); + +await queryRunner.query(` + DELETE FROM role WHERE name = 'premium' +`); + +// Delete the 'volunteer' role and its associated permissions +await queryRunner.query(` + DELETE FROM role_permissions_permission + WHERE roleId = (SELECT id FROM role WHERE name = 'volunteer') +`); + +await queryRunner.query(` + DELETE FROM role WHERE name = 'volunteer' +`); +} +} diff --git a/src/db/migration/1696963078357-CreateRoot.ts b/src/db/migration/1696963078357-CreateRoot.ts new file mode 100644 index 00000000..1d187361 --- /dev/null +++ b/src/db/migration/1696963078357-CreateRoot.ts @@ -0,0 +1,31 @@ +import { MigrationInterface, QueryRunner } from "typeorm" +import { OrganizationAdmin } from "../entities/OrganizationAdmin.js"; +import { Role } from "../entities/Role.js"; + +export class CreateRoot1696963078357 implements MigrationInterface { + + // root user + + public async up(queryRunner: QueryRunner): Promise { + const newOrgAdmin = new OrganizationAdmin(); + newOrgAdmin.name = "root"; + newOrgAdmin.email = ""; + newOrgAdmin.password = "root"; + + const rootRole = await queryRunner.manager.findOne(Role, { where: { name: "root" } }); + + if (rootRole) { + newOrgAdmin.roles = rootRole; + } else { + console.error("The 'root' role does not exist."); + } + await newOrgAdmin.save(); + } + public async down(queryRunner: QueryRunner): Promise { + + const orgAdminToDelete = await queryRunner.manager.findOne(OrganizationAdmin, { where: { name: "root" } }); + if (orgAdminToDelete) { + await orgAdminToDelete.remove(); + } + } +} From 158fd3ca41b887ee9290acf2aae3cdce4f2b71ff Mon Sep 17 00:00:00 2001 From: Waleed Date: Tue, 10 Oct 2023 23:03:39 +0300 Subject: [PATCH 115/146] Solve ERR_UNKNOWN_FILE_EXTENSION error --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9050729b..ed665a13 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "scripts": { "start": "node ./bin/www", "build-tsc": "tsc -w", - "run-watch": "nodemon ./dist/app.js", + "run-watch": "nodemon --loader ts-node/esm ./dist/app.js", "dev": "concurrently \"npm:build-tsc\" \"npm:run-watch\"", "test": "tsc && jest", "build": "tsc --project ." From 7a028764fdbef69166e8aa5eb7854d141d9910e3 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Wed, 11 Oct 2023 10:28:19 +0300 Subject: [PATCH 116/146] Edit the megrations and add them to docker and git hub actions --- .github/workflows/build.yml | 10 +- Dockerfile | 2 +- src/db/dataSource.ts | 22 +-- src/db/migration/1696963025886-CreateRoles.ts | 133 ------------------ src/db/migration/1696963078357-CreateRoot.ts | 31 ---- ....ts => 1697004288562-CreatePermissions.ts} | 7 +- .../migrations/1697005494066-CreateRoles.ts | 132 +++++++++++++++++ src/db/migrations/1697005554406-RootUser.ts | 29 ++++ 8 files changed, 184 insertions(+), 182 deletions(-) delete mode 100644 src/db/migration/1696963025886-CreateRoles.ts delete mode 100644 src/db/migration/1696963078357-CreateRoot.ts rename src/db/migration/{1696962955556-CreatePermissions.ts => 1697004288562-CreatePermissions.ts} (96%) create mode 100644 src/db/migrations/1697005494066-CreateRoles.ts create mode 100644 src/db/migrations/1697005554406-RootUser.ts diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 49f94eae..0d59d110 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -58,4 +58,12 @@ jobs: - name: print logs if: always() - run: docker compose logs \ No newline at end of file + run: docker compose logs + + - name: Run Migrations + run: | + docker compose -f docker-compose-prod.yml exec app npx typeorm-ts-node-esm migration:run -d ./src/db/dataSource.ts && + docker compose -f docker-compose-prod.yml exec app mv ./src/db/migrations/1697005494066-CreateRoles.ts ./src/db/migration && + docker compose -f docker-compose-prod.yml exec app npx typeorm-ts-node-esm migration:run -d ./src/db/dataSource.ts && + docker compose -f docker-compose-prod.yml exec app mv ./src/db/migrations/1697005554406-RootUser.ts + \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 520d9462..62dc4a32 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,4 +13,4 @@ RUN npm run build HEALTHCHECK --interval=10s --timeout=3s \ CMD curl -f http://localhost/ || exit 1 -CMD node ./dist/app.js \ No newline at end of file +CMD node --loader ts-node/esm ./dist/app.js \ No newline at end of file diff --git a/src/db/dataSource.ts b/src/db/dataSource.ts index 8789ca97..464eb96f 100644 --- a/src/db/dataSource.ts +++ b/src/db/dataSource.ts @@ -10,17 +10,17 @@ import { VolunteerProfile } from "./entities/VolunteerProfile.js"; import { Logs } from "./entities/Logs.js"; const dataSource = new DataSource({ - type: 'mysql', - host: "localhost"||process.env.DB_HOST, - port: 3306||Number(process.env.DB_PORT), - username: "root"||process.env.DB_USERNAME, - password:""|| process.env.DB_PASSWORD, - database:"Serve-and-Shine"|| process.env.DB_NAME, - entities: [OrganizationAdmin, OrganizationProfile, Permission, - Role, SkillTag, VoluntaryWork, Volunteer, VolunteerProfile, Logs], - migrations: ['./**/migration/*.ts'], - synchronize: true, - logging: false + type: 'mysql', + host: process.env.DB_HOST, + port: 3306 || Number(process.env.DB_PORT), + username: "root" || process.env.DB_USERNAME, + password: "" || process.env.DB_PASSWORD, + database: "Serve-and-Shine" || process.env.DB_NAME, + entities: [OrganizationAdmin, OrganizationProfile, Permission, + Role, SkillTag, VoluntaryWork, Volunteer, VolunteerProfile, Logs], + migrations: ['./**/migration/*.ts'], + synchronize: true, + logging: false }); export const initDB = async () => diff --git a/src/db/migration/1696963025886-CreateRoles.ts b/src/db/migration/1696963025886-CreateRoles.ts deleted file mode 100644 index e3869ab5..00000000 --- a/src/db/migration/1696963025886-CreateRoles.ts +++ /dev/null @@ -1,133 +0,0 @@ -import { MigrationInterface, QueryRunner } from "typeorm" - -export class CreateRoles1696963025886 implements MigrationInterface { - -// for permissions - -public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(` - INSERT INTO role (name) - VALUES ('root') - `); - - const result = await queryRunner.query(` - SELECT id FROM role WHERE name = 'root' - `); - - const roleId = result[0].id; - const permissionIds = [ - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, - 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 - ]; - - for (const permissionId of permissionIds) { - await queryRunner.query(` - INSERT INTO role_permissions_permission (roleId, permissionId) - VALUES (${roleId}, ${permissionId}) - `); - } - - await queryRunner.query(` - INSERT INTO role (name) - VALUES ('admin') -`); - -// Get the ID of the inserted 'admin' role -const adminRoleId = (await queryRunner.query(` - SELECT id FROM role WHERE name = 'admin' -`))[0].id; - -// Insert permissions for the 'admin' role -const adminPermissionIds = [1, 2, 3, 4, 5, 9, 13, 14, 16, 17]; - -for (const permissionId of adminPermissionIds) { - await queryRunner.query(` - INSERT INTO role_permissions_permission (roleId, permissionId) - VALUES (${adminRoleId}, ${permissionId}) - `); -} - -await queryRunner.query(` - INSERT INTO role (name) - VALUES ('premium') -`); - -const premiumRoleId = (await queryRunner.query(` - SELECT id FROM role WHERE name = 'premium' -`))[0].id; - -const premiumPermissionIds = [1, 2, 5, 9, 13, 14, 16, 17, 19, 21, 22]; - -for (const permissionId of premiumPermissionIds) { - await queryRunner.query(` - INSERT INTO role_permissions_permission (roleId, permissionId) - VALUES (${premiumRoleId}, ${permissionId}) - `); -} - -// Insert the 'volunteer' role -await queryRunner.query(` - INSERT INTO role (name) - VALUES ('volunteer') -`); - -// Get the ID of the inserted 'volunteer' role -const volunteerRoleId = (await queryRunner.query(` - SELECT id FROM role WHERE name = 'volunteer' -`))[0].id; - -// Insert permissions for the 'volunteer' role -const volunteerPermissionIds = [1, 2, 5, 9, 13, 16, 17, 19, 21, 22]; - -for (const permissionId of volunteerPermissionIds) { - await queryRunner.query(` - INSERT INTO role_permissions_permission (roleId, permissionId) - VALUES (${volunteerRoleId}, ${permissionId}) - `); -} -} - -public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(` - DELETE FROM role WHERE name = 'root' -`); - - const permissionIdsToDelete = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]; - - for (const permissionId of permissionIdsToDelete) { - await queryRunner.query(` - DELETE FROM role_permissions_permission - WHERE roleId = (SELECT id FROM role WHERE name = 'root') AND permissionId = ${permissionId} - `); - } - await queryRunner.query(` - DELETE FROM role_permissions_permission - WHERE roleId = (SELECT id FROM role WHERE name = 'admin') -`); - -await queryRunner.query(` - DELETE FROM role WHERE name = 'admin' -`); - -// Delete the 'premium' role and its associated permissions -await queryRunner.query(` - DELETE FROM role_permissions_permission - WHERE roleId = (SELECT id FROM role WHERE name = 'premium') -`); - -await queryRunner.query(` - DELETE FROM role WHERE name = 'premium' -`); - -// Delete the 'volunteer' role and its associated permissions -await queryRunner.query(` - DELETE FROM role_permissions_permission - WHERE roleId = (SELECT id FROM role WHERE name = 'volunteer') -`); - -await queryRunner.query(` - DELETE FROM role WHERE name = 'volunteer' -`); -} -} diff --git a/src/db/migration/1696963078357-CreateRoot.ts b/src/db/migration/1696963078357-CreateRoot.ts deleted file mode 100644 index 1d187361..00000000 --- a/src/db/migration/1696963078357-CreateRoot.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { MigrationInterface, QueryRunner } from "typeorm" -import { OrganizationAdmin } from "../entities/OrganizationAdmin.js"; -import { Role } from "../entities/Role.js"; - -export class CreateRoot1696963078357 implements MigrationInterface { - - // root user - - public async up(queryRunner: QueryRunner): Promise { - const newOrgAdmin = new OrganizationAdmin(); - newOrgAdmin.name = "root"; - newOrgAdmin.email = ""; - newOrgAdmin.password = "root"; - - const rootRole = await queryRunner.manager.findOne(Role, { where: { name: "root" } }); - - if (rootRole) { - newOrgAdmin.roles = rootRole; - } else { - console.error("The 'root' role does not exist."); - } - await newOrgAdmin.save(); - } - public async down(queryRunner: QueryRunner): Promise { - - const orgAdminToDelete = await queryRunner.manager.findOne(OrganizationAdmin, { where: { name: "root" } }); - if (orgAdminToDelete) { - await orgAdminToDelete.remove(); - } - } -} diff --git a/src/db/migration/1696962955556-CreatePermissions.ts b/src/db/migration/1697004288562-CreatePermissions.ts similarity index 96% rename from src/db/migration/1696962955556-CreatePermissions.ts rename to src/db/migration/1697004288562-CreatePermissions.ts index a874f85e..840cdd17 100644 --- a/src/db/migration/1696962955556-CreatePermissions.ts +++ b/src/db/migration/1697004288562-CreatePermissions.ts @@ -1,8 +1,6 @@ import { MigrationInterface, QueryRunner } from "typeorm" -export class CreatePermissions1696962955556 implements MigrationInterface { - - // creat permaissions +export class CreatePermissions1697004288562 implements MigrationInterface { public async up(queryRunner: QueryRunner): Promise { await queryRunner.query(` @@ -80,6 +78,5 @@ export class CreatePermissions1696962955556 implements MigrationInterface { ) `); } -} - +} diff --git a/src/db/migrations/1697005494066-CreateRoles.ts b/src/db/migrations/1697005494066-CreateRoles.ts new file mode 100644 index 00000000..565e5dfb --- /dev/null +++ b/src/db/migrations/1697005494066-CreateRoles.ts @@ -0,0 +1,132 @@ +import { MigrationInterface, QueryRunner } from "typeorm" + +export class CreateRoles1697005494066 implements MigrationInterface { + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + INSERT INTO role (name) + VALUES ('root') + `); + + const result = await queryRunner.query(` + SELECT id FROM role WHERE name = 'root' + `); + + const roleId = result[0].id; + const permissionIds = [ + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 + ]; + + for (const permissionId of permissionIds) { + await queryRunner.query(` + INSERT INTO role_permissions_permission (roleId, permissionId) + VALUES (${roleId}, ${permissionId}) + `); + } + + await queryRunner.query(` + INSERT INTO role (name) + VALUES ('admin') +`); + + // Get the ID of the inserted 'admin' role + const adminRoleId = (await queryRunner.query(` + SELECT id FROM role WHERE name = 'admin' +`))[0].id; + + // Insert permissions for the 'admin' role + const adminPermissionIds = [1, 2, 3, 4, 5, 9, 13, 14, 16, 17]; + + for (const permissionId of adminPermissionIds) { + await queryRunner.query(` + INSERT INTO role_permissions_permission (roleId, permissionId) + VALUES (${adminRoleId}, ${permissionId}) + `); + } + + await queryRunner.query(` + INSERT INTO role (name) + VALUES ('premium') +`); + + const premiumRoleId = (await queryRunner.query(` + SELECT id FROM role WHERE name = 'premium' +`))[0].id; + + const premiumPermissionIds = [1, 2, 5, 9, 13, 14, 16, 17, 19, 21, 22]; + + for (const permissionId of premiumPermissionIds) { + await queryRunner.query(` + INSERT INTO role_permissions_permission (roleId, permissionId) + VALUES (${premiumRoleId}, ${permissionId}) + `); + } + + // Insert the 'volunteer' role + await queryRunner.query(` + INSERT INTO role (name) + VALUES ('volunteer') +`); + + // Get the ID of the inserted 'volunteer' role + const volunteerRoleId = (await queryRunner.query(` + SELECT id FROM role WHERE name = 'volunteer' +`))[0].id; + + // Insert permissions for the 'volunteer' role + const volunteerPermissionIds = [1, 2, 5, 9, 13, 16, 17, 19, 21, 22]; + + for (const permissionId of volunteerPermissionIds) { + await queryRunner.query(` + INSERT INTO role_permissions_permission (roleId, permissionId) + VALUES (${volunteerRoleId}, ${permissionId}) + `); + } + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + DELETE FROM role WHERE name = 'root' +`); + + const permissionIdsToDelete = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]; + + for (const permissionId of permissionIdsToDelete) { + await queryRunner.query(` + DELETE FROM role_permissions_permission + WHERE roleId = (SELECT id FROM role WHERE name = 'root') AND permissionId = ${permissionId} + `); + } + await queryRunner.query(` + DELETE FROM role_permissions_permission + WHERE roleId = (SELECT id FROM role WHERE name = 'admin') +`); + + await queryRunner.query(` + DELETE FROM role WHERE name = 'admin' +`); + + // Delete the 'premium' role and its associated permissions + await queryRunner.query(` + DELETE FROM role_permissions_permission + WHERE roleId = (SELECT id FROM role WHERE name = 'premium') +`); + + await queryRunner.query(` + DELETE FROM role WHERE name = 'premium' +`); + + // Delete the 'volunteer' role and its associated permissions + await queryRunner.query(` + DELETE FROM role_permissions_permission + WHERE roleId = (SELECT id FROM role WHERE name = 'volunteer') +`); + + await queryRunner.query(` + DELETE FROM role WHERE name = 'volunteer' +`); + } + +} diff --git a/src/db/migrations/1697005554406-RootUser.ts b/src/db/migrations/1697005554406-RootUser.ts new file mode 100644 index 00000000..a79bf748 --- /dev/null +++ b/src/db/migrations/1697005554406-RootUser.ts @@ -0,0 +1,29 @@ +import { MigrationInterface, QueryRunner } from "typeorm" +import { OrganizationAdmin } from "../entities/OrganizationAdmin.js"; +import { Role } from "../entities/Role.js"; + +export class RootUser1697005554406 implements MigrationInterface { + +public async up(queryRunner: QueryRunner): Promise { + const newOrgAdmin = new OrganizationAdmin(); + newOrgAdmin.name = "root"; + newOrgAdmin.email = ""; + newOrgAdmin.password = "root"; + + const rootRole = await queryRunner.manager.findOne(Role, { where: { name: "root" } }); + + if (rootRole) { + newOrgAdmin.roles = rootRole; + } else { + console.error("The 'root' role does not exist."); + } + await newOrgAdmin.save(); +} +public async down(queryRunner: QueryRunner): Promise { + + const orgAdminToDelete = await queryRunner.manager.findOne(OrganizationAdmin, { where: { name: "root" } }); + if (orgAdminToDelete) { + await orgAdminToDelete.remove(); + } +} +} From dd7b8674a8f50389e6da7cbf205a22099155a234 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Wed, 11 Oct 2023 11:09:04 +0300 Subject: [PATCH 117/146] Test megration with github actions --- .github/workflows/build.yml | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0d59d110..1ae8b003 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -41,24 +41,24 @@ jobs: user: github ssh-private-key: ${{ secrets.DEPLOYMENT_KEY }} - - name: deploy - run: docker compose -f docker-compose-prod.yml up -d - env: - DB_PASSWORD: ${{ secrets.DB_PASSWORD}} - GIT_VERSISON: ${{steps.image_version.outputs.gitsha}} - SECRET_KEY: ${{ secrets.SECRET_KEY}} - DB_HOST: ${{ secrets. DB_HOST}} - DB_PORT: ${{ secrets.DB_PORT}} - DB_USERNAME: ${{ secrets.DB_USERNAME}} - DB_NAME: ${{ secrets.DB_NAME}} - AWS_BUCKET_NAME: ${{ secrets.AWS_BUCKET_NAME}} - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID}} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY}} - AWS_REGION: ${{ secrets.AWS_REGION}} + # - name: deploy + # run: docker compose -f docker-compose-prod.yml up -d + # env: + # DB_PASSWORD: ${{ secrets.DB_PASSWORD}} + # GIT_VERSISON: ${{steps.image_version.outputs.gitsha}} + # SECRET_KEY: ${{ secrets.SECRET_KEY}} + # DB_HOST: ${{ secrets. DB_HOST}} + # DB_PORT: ${{ secrets.DB_PORT}} + # DB_USERNAME: ${{ secrets.DB_USERNAME}} + # DB_NAME: ${{ secrets.DB_NAME}} + # AWS_BUCKET_NAME: ${{ secrets.AWS_BUCKET_NAME}} + # AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID}} + # AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY}} + # AWS_REGION: ${{ secrets.AWS_REGION}} - - name: print logs - if: always() - run: docker compose logs + # - name: print logs + # if: always() + # run: docker compose logs - name: Run Migrations run: | From a9341fe86e1c2c3c932b03a99517b80caf95da2b Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Wed, 11 Oct 2023 11:16:26 +0300 Subject: [PATCH 118/146] megration testing --- .github/workflows/build.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1ae8b003..623b5f1b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -34,15 +34,15 @@ jobs: run: docker build . --file Dockerfile --tag ghcr.io/sarahabuirmeileh/serve-and-shine:${{ steps.image_version.outputs.gitsha }} - name: Puplish docker image run: docker push ghcr.io/sarahabuirmeileh/serve-and-shine:${{ steps.image_version.outputs.gitsha }} - - name: configer docker host - uses: khaledez/configure-docker-host@v1 - with: - host: 52.56.237.63 - user: github - ssh-private-key: ${{ secrets.DEPLOYMENT_KEY }} + # - name: configer docker host + # uses: khaledez/configure-docker-host@v1 + # with: + # host: 52.56.237.63 + # user: github + # ssh-private-key: ${{ secrets.DEPLOYMENT_KEY }} - # - name: deploy - # run: docker compose -f docker-compose-prod.yml up -d + - name: deploy + run: docker compose -f docker-compose-prod.yml up -d # env: # DB_PASSWORD: ${{ secrets.DB_PASSWORD}} # GIT_VERSISON: ${{steps.image_version.outputs.gitsha}} From a843086c32474f68a110d4bdeb7420a942405632 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Wed, 11 Oct 2023 11:18:48 +0300 Subject: [PATCH 119/146] Adding env var --- .github/workflows/build.yml | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 623b5f1b..22529103 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -43,18 +43,18 @@ jobs: - name: deploy run: docker compose -f docker-compose-prod.yml up -d - # env: - # DB_PASSWORD: ${{ secrets.DB_PASSWORD}} - # GIT_VERSISON: ${{steps.image_version.outputs.gitsha}} - # SECRET_KEY: ${{ secrets.SECRET_KEY}} - # DB_HOST: ${{ secrets. DB_HOST}} - # DB_PORT: ${{ secrets.DB_PORT}} - # DB_USERNAME: ${{ secrets.DB_USERNAME}} - # DB_NAME: ${{ secrets.DB_NAME}} - # AWS_BUCKET_NAME: ${{ secrets.AWS_BUCKET_NAME}} - # AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID}} - # AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY}} - # AWS_REGION: ${{ secrets.AWS_REGION}} + env: + DB_PASSWORD: ${{ secrets.DB_PASSWORD}} + GIT_VERSISON: ${{steps.image_version.outputs.gitsha}} + SECRET_KEY: ${{ secrets.SECRET_KEY}} + DB_HOST: ${{ secrets. DB_HOST}} + DB_PORT: ${{ secrets.DB_PORT}} + DB_USERNAME: ${{ secrets.DB_USERNAME}} + DB_NAME: ${{ secrets.DB_NAME}} + AWS_BUCKET_NAME: ${{ secrets.AWS_BUCKET_NAME}} + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID}} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY}} + AWS_REGION: ${{ secrets.AWS_REGION}} # - name: print logs # if: always() From c0d9553c7bd4909bc9adbd97935ba7cb3d791f38 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Wed, 11 Oct 2023 12:15:44 +0300 Subject: [PATCH 120/146] Preparing the migrations --- .github/workflows/build.yml | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 22529103..eef7d8ef 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -34,12 +34,12 @@ jobs: run: docker build . --file Dockerfile --tag ghcr.io/sarahabuirmeileh/serve-and-shine:${{ steps.image_version.outputs.gitsha }} - name: Puplish docker image run: docker push ghcr.io/sarahabuirmeileh/serve-and-shine:${{ steps.image_version.outputs.gitsha }} - # - name: configer docker host - # uses: khaledez/configure-docker-host@v1 - # with: - # host: 52.56.237.63 - # user: github - # ssh-private-key: ${{ secrets.DEPLOYMENT_KEY }} + - name: configer docker host + uses: khaledez/configure-docker-host@v1 + with: + host: 52.56.237.63 + user: github + ssh-private-key: ${{ secrets.DEPLOYMENT_KEY }} - name: deploy run: docker compose -f docker-compose-prod.yml up -d @@ -47,7 +47,7 @@ jobs: DB_PASSWORD: ${{ secrets.DB_PASSWORD}} GIT_VERSISON: ${{steps.image_version.outputs.gitsha}} SECRET_KEY: ${{ secrets.SECRET_KEY}} - DB_HOST: ${{ secrets. DB_HOST}} + DB_HOST: ${{ secrets.DB_HOST}} DB_PORT: ${{ secrets.DB_PORT}} DB_USERNAME: ${{ secrets.DB_USERNAME}} DB_NAME: ${{ secrets.DB_NAME}} @@ -56,14 +56,15 @@ jobs: AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY}} AWS_REGION: ${{ secrets.AWS_REGION}} - # - name: print logs - # if: always() - # run: docker compose logs + - name: print logs + if: always() + run: docker compose logs - name: Run Migrations run: | docker compose -f docker-compose-prod.yml exec app npx typeorm-ts-node-esm migration:run -d ./src/db/dataSource.ts && docker compose -f docker-compose-prod.yml exec app mv ./src/db/migrations/1697005494066-CreateRoles.ts ./src/db/migration && docker compose -f docker-compose-prod.yml exec app npx typeorm-ts-node-esm migration:run -d ./src/db/dataSource.ts && - docker compose -f docker-compose-prod.yml exec app mv ./src/db/migrations/1697005554406-RootUser.ts + docker compose -f docker-compose-prod.yml exec app mv ./src/db/migrations/1697005554406-RootUser.ts ./src/db/migration && + docker compose -f docker-compose-prod.yml exec app npx typeorm-ts-node-esm migration:run -d ./src/db/dataSource.ts \ No newline at end of file From 37dd377e3f2c85bd1bc1a7753e051f116600afa8 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Wed, 11 Oct 2023 12:42:54 +0300 Subject: [PATCH 121/146] Calling loging to aws-cloudWatch in org admin rout --- src/controllers/cloudWatch-logger.ts | 17 +-- src/controllers/voluntaryWork.ts | 2 +- src/routes/organizationAdmin.ts | 138 +++++++++++------- .../AWS_configure_CloudWatch.ts | 0 .../AWS_configure_S3.ts | 0 5 files changed, 86 insertions(+), 71 deletions(-) rename src/{utilites => utilities}/AWS_configure_CloudWatch.ts (100%) rename src/{utilites => utilities}/AWS_configure_S3.ts (100%) diff --git a/src/controllers/cloudWatch-logger.ts b/src/controllers/cloudWatch-logger.ts index ddfbfdcf..252af17d 100644 --- a/src/controllers/cloudWatch-logger.ts +++ b/src/controllers/cloudWatch-logger.ts @@ -1,4 +1,4 @@ -import { configureCloudWatch } from '../utilites/AWS_configure_CloudWatch.js'; +import { configureCloudWatch } from '../utilities/AWS_configure_CloudWatch.js'; const cloudWatchLogs = await configureCloudWatch(); @@ -24,17 +24,4 @@ export const logToCloudWatch = async (logGroupName:string, logStreamName:string, } catch (error) { console.error('Error sending log event:', error); } -}; - -// await logToCloudWatch( -// 'failed', -// '', -// 'Volunteer registered successfully!' -// ); -// -// await logToCloudWatch( -// 'success', -// '', -// 'Volunteer registered successfully!' -// ); -// +}; \ No newline at end of file diff --git a/src/controllers/voluntaryWork.ts b/src/controllers/voluntaryWork.ts index bbb06ba5..01aa9420 100644 --- a/src/controllers/voluntaryWork.ts +++ b/src/controllers/voluntaryWork.ts @@ -6,7 +6,7 @@ import { getDate } from "./index.js"; import { Volunteer } from "../db/entities/Volunteer.js"; import createError from 'http-errors'; import { UploadedFile } from "express-fileupload"; -import { configureS3Bucket } from "../utilites/AWS_configure_S3.js"; +import { configureS3Bucket } from "../utilities/AWS_configure_S3.js"; import baseLogger from "../../logger.js"; const createVoluntaryWork = async (payload: NSVoluntaryWork.Item) => { diff --git a/src/routes/organizationAdmin.ts b/src/routes/organizationAdmin.ts index 5047b9ca..2427ce04 100644 --- a/src/routes/organizationAdmin.ts +++ b/src/routes/organizationAdmin.ts @@ -4,36 +4,43 @@ import { authorize, checkMe } from "../middleware/auth/authorize.js"; import { validateAdminEdited, validateAdminId, validateOrganizationAdmin } from "../middleware/validation/organizationAdmin.js"; import { log } from "../controllers/dataBase-logger.js"; import { NSLogs } from "../../types/logs.js"; +import { logToCloudWatch } from "../controllers/cloudWatch-logger.js"; const router = express.Router(); router.post('/', authorize("POST_organizationAdmin"), validateOrganizationAdmin, (req, res, next) => { - createOrganizationAdmin(req.body).then((data) => { - log({ + createOrganizationAdmin(req.body).then(async (data) => { + await log({ userId: res.locals.organizationAdmin?.id, userName: res.locals.organizationAdmin?.name, userType: 'root' as NSLogs.userType, type: 'success' as NSLogs.Type, - request: 'Create Organization Admin '+ data.name - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); + request: 'Create Organization Admin ' + data.name }) + await logToCloudWatch( + 'success', + 'organization admin', + 'Create Organization Admin ' + data.name, + res.locals.organizationAdmin?.id, + res.locals.organizationAdmin?.name + ); res.status(201).send("Organization Admin created successfully!!") - }).catch(err => { - log({ + }).catch(async err => { + await log({ userId: res.locals.organizationAdmin?.id, userName: res.locals.organizationAdmin?.name, userType: 'root' as NSLogs.userType, type: 'failed' as NSLogs.Type, request: 'Create Organization Admin ' + req.body.name - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); }) + await logToCloudWatch( + 'failed', + 'organization admin', + 'Create Organization Admin ' + req.body.name, + res.locals.organizationAdmin?.id, + res.locals.organizationAdmin?.name + ); next(err); }); }); @@ -42,62 +49,76 @@ router.delete('/:id', validateAdminId, authorize("DELETE_organizationAdmin"), as const id = req.params.id?.toString(); deleteOrganizationAdmin(id) - .then(data => { - log({ + .then(async data => { + await log({ userId: res.locals.organizationAdmin?.id, userName: res.locals.organizationAdmin?.name, userType: (res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'success' as NSLogs.Type, - request: 'Delete Organization Admin with id: '+ id - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); + request: 'Delete Organization Admin with id: ' + id }) + + await logToCloudWatch( + 'success', + 'organization admin', + 'Delete Organization Admin with id: ' + id, + res.locals.organizationAdmin?.id, + res.locals.organizationAdmin?.name + ); res.send(data); }) - .catch(err => { - log({ + .catch(async err => { + await log({ userId: res.locals.organizationAdmin?.id, userName: res.locals.organizationAdmin?.name, userType: (res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'failed' as NSLogs.Type, - request: 'Delete Organization Admin with id: '+ id - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); + request: 'Delete Organization Admin with id: ' + id }) + await logToCloudWatch( + 'failed', + 'organization admin', + 'Delete Organization Admin with id: ' + id, + res.locals.organizationAdmin?.id, + res.locals.organizationAdmin?.name + ); next(err); }); }); router.put("/:id", authorize("PUT_organizationAdmin"), validateAdminEdited, async (req, res, next) => { - editOrganizationAdmin({ ...req.body, id: req.params.id }).then(() => { - log({ + editOrganizationAdmin({ ...req.body, id: req.params.id }).then(async () => { + await log({ userId: res.locals.organizationAdmin?.id, userName: res.locals.organizationAdmin?.name, userType: (res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'success' as NSLogs.Type, - request: 'Edit Organization Admin with id: '+ req.params.id - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); + request: 'Edit Organization Admin with id: ' + req.params.id }) + + await logToCloudWatch( + 'success', + 'organization admin', + 'Edit Organization Admin with id: ' + req.params.id, + res.locals.organizationAdmin?.id, + res.locals.organizationAdmin?.name + ); res.status(201).send("Organization Admin edited successfully!!") - }).catch(err => { - log({ + }).catch(async err => { + await log({ userId: res.locals.organizationAdmin?.id, userName: res.locals.organizationAdmin?.name, userType: (res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'failed' as NSLogs.Type, - request: 'Edit Organization Admin with id: '+ req.params.id - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); + request: 'Edit Organization Admin with id: ' + req.params.id }) + await logToCloudWatch( + 'failed', + 'organization admin', + 'Edit Organization Admin with id: ' + req.params.id, + res.locals.organizationAdmin?.id, + res.locals.organizationAdmin?.name + ); next(err); }); }); @@ -113,32 +134,39 @@ router.get('/', authorize("GET_organizationAdmins"), async (req, res, next) => { }; getOrganizationAdmins(payload) - .then(data => { - log({ + .then(async data => { + await log({ userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, - userType: (res.locals.volunteer?.type ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + userType: (res.locals.volunteer?.type ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'success' as NSLogs.Type, request: 'Get Organization Admin/s' - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); }) + + await logToCloudWatch( + 'success', + 'organization admin', + 'Get Organization Admin/s', + res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + res.locals.organizationAdmin?.name || res.locals.volunteer?.name + ); res.send(data); }) - .catch(err => { - log({ + .catch(async err => { + await log({ userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, - userType: (res.locals.volunteer?.type ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + userType: (res.locals.volunteer?.type ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'failed' as NSLogs.Type, request: 'Get Organization Admin/s' - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); }) + await logToCloudWatch( + 'failed', + 'organization admin', + 'Get Organization Admin/s', + res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + res.locals.organizationAdmin?.name || res.locals.volunteer?.name + ); next(err); }); }); diff --git a/src/utilites/AWS_configure_CloudWatch.ts b/src/utilities/AWS_configure_CloudWatch.ts similarity index 100% rename from src/utilites/AWS_configure_CloudWatch.ts rename to src/utilities/AWS_configure_CloudWatch.ts diff --git a/src/utilites/AWS_configure_S3.ts b/src/utilities/AWS_configure_S3.ts similarity index 100% rename from src/utilites/AWS_configure_S3.ts rename to src/utilities/AWS_configure_S3.ts From 2278e16ad3269fef54447ffff286411acebca564 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Wed, 11 Oct 2023 13:08:10 +0300 Subject: [PATCH 122/146] Call the loggers by .then .catch --- src/routes/organizationAdmin.ts | 74 +++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 31 deletions(-) diff --git a/src/routes/organizationAdmin.ts b/src/routes/organizationAdmin.ts index 2427ce04..3bc0f03d 100644 --- a/src/routes/organizationAdmin.ts +++ b/src/routes/organizationAdmin.ts @@ -10,37 +10,40 @@ const router = express.Router(); router.post('/', authorize("POST_organizationAdmin"), validateOrganizationAdmin, (req, res, next) => { createOrganizationAdmin(req.body).then(async (data) => { - await log({ + log({ userId: res.locals.organizationAdmin?.id, userName: res.locals.organizationAdmin?.name, userType: 'root' as NSLogs.userType, type: 'success' as NSLogs.Type, request: 'Create Organization Admin ' + data.name - }) + }).then().catch() - await logToCloudWatch( + logToCloudWatch( 'success', 'organization admin', 'Create Organization Admin ' + data.name, res.locals.organizationAdmin?.id, res.locals.organizationAdmin?.name - ); + ).then().catch() + res.status(201).send("Organization Admin created successfully!!") }).catch(async err => { - await log({ + log({ userId: res.locals.organizationAdmin?.id, userName: res.locals.organizationAdmin?.name, userType: 'root' as NSLogs.userType, type: 'failed' as NSLogs.Type, request: 'Create Organization Admin ' + req.body.name - }) - await logToCloudWatch( + }).then().catch() + + logToCloudWatch( 'failed', 'organization admin', 'Create Organization Admin ' + req.body.name, res.locals.organizationAdmin?.id, res.locals.organizationAdmin?.name - ); + ).then().catch() + next(err); }); }); @@ -50,75 +53,81 @@ router.delete('/:id', validateAdminId, authorize("DELETE_organizationAdmin"), as deleteOrganizationAdmin(id) .then(async data => { - await log({ + log({ userId: res.locals.organizationAdmin?.id, userName: res.locals.organizationAdmin?.name, userType: (res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'success' as NSLogs.Type, request: 'Delete Organization Admin with id: ' + id - }) + }).then().catch() - await logToCloudWatch( + logToCloudWatch( 'success', 'organization admin', 'Delete Organization Admin with id: ' + id, res.locals.organizationAdmin?.id, res.locals.organizationAdmin?.name - ); + ).then().catch() + res.send(data); }) .catch(async err => { - await log({ + log({ userId: res.locals.organizationAdmin?.id, userName: res.locals.organizationAdmin?.name, userType: (res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'failed' as NSLogs.Type, request: 'Delete Organization Admin with id: ' + id - }) - await logToCloudWatch( + }).then().catch() + + logToCloudWatch( 'failed', 'organization admin', 'Delete Organization Admin with id: ' + id, res.locals.organizationAdmin?.id, res.locals.organizationAdmin?.name - ); + ).then().catch() + next(err); }); }); router.put("/:id", authorize("PUT_organizationAdmin"), validateAdminEdited, async (req, res, next) => { editOrganizationAdmin({ ...req.body, id: req.params.id }).then(async () => { - await log({ + log({ userId: res.locals.organizationAdmin?.id, userName: res.locals.organizationAdmin?.name, userType: (res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'success' as NSLogs.Type, request: 'Edit Organization Admin with id: ' + req.params.id - }) + }).then().catch() - await logToCloudWatch( + logToCloudWatch( 'success', 'organization admin', 'Edit Organization Admin with id: ' + req.params.id, res.locals.organizationAdmin?.id, res.locals.organizationAdmin?.name - ); + ).then().catch() + res.status(201).send("Organization Admin edited successfully!!") }).catch(async err => { - await log({ + log({ userId: res.locals.organizationAdmin?.id, userName: res.locals.organizationAdmin?.name, userType: (res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'failed' as NSLogs.Type, request: 'Edit Organization Admin with id: ' + req.params.id }) - await logToCloudWatch( + + logToCloudWatch( 'failed', 'organization admin', 'Edit Organization Admin with id: ' + req.params.id, res.locals.organizationAdmin?.id, res.locals.organizationAdmin?.name - ); + ).then().catch() + next(err); }); }); @@ -135,38 +144,41 @@ router.get('/', authorize("GET_organizationAdmins"), async (req, res, next) => { getOrganizationAdmins(payload) .then(async data => { - await log({ + log({ userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, userType: (res.locals.volunteer?.type ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'success' as NSLogs.Type, request: 'Get Organization Admin/s' - }) + }).then().catch() - await logToCloudWatch( + logToCloudWatch( 'success', 'organization admin', 'Get Organization Admin/s', res.locals.organizationAdmin?.id || res.locals.volunteer?.id, res.locals.organizationAdmin?.name || res.locals.volunteer?.name - ); + ).then().catch() + res.send(data); }) .catch(async err => { - await log({ + log({ userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, userType: (res.locals.volunteer?.type ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'failed' as NSLogs.Type, request: 'Get Organization Admin/s' - }) - await logToCloudWatch( + }).then().catch() + + logToCloudWatch( 'failed', 'organization admin', 'Get Organization Admin/s', res.locals.organizationAdmin?.id || res.locals.volunteer?.id, res.locals.organizationAdmin?.name || res.locals.volunteer?.name - ); + ).then().catch() + next(err); }); }); From 9ba321da694a9038b444a297a6d7e27b4da28c31 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Wed, 11 Oct 2023 13:15:58 +0300 Subject: [PATCH 123/146] Calling loging to aws-cloudWatch in org profile rout --- src/controllers/cloudWatch-logger.ts | 19 ++++- src/routes/organizationProfile.ts | 121 ++++++++++++++++++--------- 2 files changed, 99 insertions(+), 41 deletions(-) diff --git a/src/controllers/cloudWatch-logger.ts b/src/controllers/cloudWatch-logger.ts index 252af17d..6d8112a6 100644 --- a/src/controllers/cloudWatch-logger.ts +++ b/src/controllers/cloudWatch-logger.ts @@ -24,4 +24,21 @@ export const logToCloudWatch = async (logGroupName:string, logStreamName:string, } catch (error) { console.error('Error sending log event:', error); } -}; \ No newline at end of file +}; + + logToCloudWatch( + 'failed', + '', + 'Volunteer registered successfully!', + '', + '' +).then().catch() + + logToCloudWatch( + 'success', + '', + 'Volunteer registered successfully!', + '', + '' +).then().catch() + diff --git a/src/routes/organizationProfile.ts b/src/routes/organizationProfile.ts index afbe72a3..30db439c 100644 --- a/src/routes/organizationProfile.ts +++ b/src/routes/organizationProfile.ts @@ -4,6 +4,7 @@ import { authorize, checkAdmin } from "../middleware/auth/authorize.js"; import { validateOrgId, validateOrganizationProfile } from "../middleware/validation/organizationProfile.js"; import { log } from "../controllers/dataBase-logger.js"; import { NSLogs } from "../../types/logs.js"; +import { logToCloudWatch } from "../controllers/cloudWatch-logger.js"; const router = express.Router(); @@ -15,11 +16,16 @@ router.post('/', authorize("POST_organizationProfile"), validateOrganizationProf userType: 'root' as NSLogs.userType, type: 'success' as NSLogs.Type, request: 'Create Organization Profile ' + data.name - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'success', + 'organization profile', + 'Create Organization Profile ' + data.name, + res.locals.organizationAdmin?.id, + res.locals.organizationAdmin?.name + ).then().catch() + res.status(201).send("Organization Profile created successfully!!") }).catch(err => { log({ @@ -28,11 +34,16 @@ router.post('/', authorize("POST_organizationProfile"), validateOrganizationProf userType: 'root' as NSLogs.userType, type: 'failed' as NSLogs.Type, request: 'Create Organization Profile ' + req.body.name - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'failed', + 'organization profile', + 'Create Organization Profile ' + req.body.name, + res.locals.organizationAdmin?.id, + res.locals.organizationAdmin?.name + ).then().catch() + next(err); }); }); @@ -48,11 +59,16 @@ router.delete('/:id', validateOrgId, authorize("DELETE_organizationProfile"), as userType: (res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'success' as NSLogs.Type, request: 'Delete Organization Profile with id: ' + id - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'success', + 'organization profile', + 'Volunteer registered successfully!', + res.locals.organizationAdmin?.id, + res.locals.organizationAdmin?.name + ).then().catch() + res.send(data); }) .catch(err => { @@ -62,11 +78,16 @@ router.delete('/:id', validateOrgId, authorize("DELETE_organizationProfile"), as userType: (res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'failed' as NSLogs.Type, request: 'Delete Organization Profile with id: ' + id - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'failed', + 'organization profile', + 'Volunteer registered successfully!', + res.locals.organizationAdmin?.id, + res.locals.organizationAdmin?.name + ).then().catch() + next(err); }); }); @@ -79,11 +100,16 @@ router.put("/:id", validateOrgId, authorize("PUT_organizationProfile"), async (r userType: (res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'success' as NSLogs.Type, request: 'Edit Organization Profile with id: ' + req.params.id - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'success', + 'organization profile', + 'Volunteer registered successfully!', + res.locals.organizationAdmin?.id, + res.locals.organizationAdmin?.name + ).then().catch() + res.status(201).send("Organization Profile edited successfully!!") }).catch(err => { log({ @@ -92,11 +118,16 @@ router.put("/:id", validateOrgId, authorize("PUT_organizationProfile"), async (r userType: (res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'failed' as NSLogs.Type, request: 'Edit Organization Profile with id: ' + req.params.id - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'failed', + 'organization profile', + 'Volunteer registered successfully!', + res.locals.organizationAdmin?.id, + res.locals.organizationAdmin?.name + ).then().catch() + next(err); }); }); @@ -118,11 +149,16 @@ router.get('/', authorize("GET_organizationProfiles"), async (req, res, next) => userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'success' as NSLogs.Type, request: 'Get Organization Profiles' - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'success', + 'organization profile', + 'Volunteer registered successfully!', + res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + res.locals.organizationAdmin?.name || res.locals.volunteer?.name + ).then().catch() + res.send(data); }) .catch(err => { @@ -132,11 +168,16 @@ router.get('/', authorize("GET_organizationProfiles"), async (req, res, next) => userType: (res.locals.volunteer?.type ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'failed' as NSLogs.Type, request: 'Get Organization Profiles' - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'failed', + 'organization profile', + 'Volunteer registered successfully!', + res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + res.locals.organizationAdmin?.name || res.locals.volunteer?.name + ).then().catch() + next(err); }); }); From 7d10918de9cfe72401674a040998070916e0d677 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Wed, 11 Oct 2023 13:23:42 +0300 Subject: [PATCH 124/146] Calling loging to aws-cloudWatch in permission rout --- src/routes/permission.ts | 121 ++++++++++++++++++++++++++------------- 1 file changed, 81 insertions(+), 40 deletions(-) diff --git a/src/routes/permission.ts b/src/routes/permission.ts index a3d81ce4..8458c2ee 100644 --- a/src/routes/permission.ts +++ b/src/routes/permission.ts @@ -4,6 +4,7 @@ import { authorize } from '../middleware/auth/authorize.js'; import { validatePermission, validatePermissionId } from '../middleware/validation/permission.js'; import { log } from '../controllers/dataBase-logger.js'; import { NSLogs } from '../../types/logs.js'; +import { logToCloudWatch } from '../controllers/cloudWatch-logger.js'; var router = express.Router(); @@ -16,11 +17,16 @@ router.post('/', authorize("POST_permission"), validatePermission, (req, res, ne userType: 'root' as NSLogs.userType, type: 'success' as NSLogs.Type, request: 'Create Permission ' + req.body.name - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'success', + 'permission', + 'Create Permission ' + req.body.name, + res.locals.organizationAdmin?.id, + res.locals.organizationAdmin?.name + ).then().catch() + res.status(201).send("Permission created successfully!!") }).catch(err => { log({ @@ -29,11 +35,16 @@ router.post('/', authorize("POST_permission"), validatePermission, (req, res, ne userType: 'root' as NSLogs.userType, type: 'failed' as NSLogs.Type, request: 'Create Permission ' + req.body.name - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'failed', + 'permission', + 'Create Permission ' + req.body.name, + res.locals.organizationAdmin?.id, + res.locals.organizationAdmin?.name + ).then().catch() + next(err); }); }); @@ -49,11 +60,16 @@ router.delete('/:id', validatePermissionId, authorize("DELETE_permission"), asyn userType: 'root' as NSLogs.userType, type: 'success' as NSLogs.Type, request: 'Delete Permission with id: ' + id - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'success', + 'permission', + 'Delete Permission with id: ' + id, + res.locals.organizationAdmin?.id, + res.locals.organizationAdmin?.name, + ).then().catch() + res.send(data); }) .catch(err => { @@ -63,11 +79,16 @@ router.delete('/:id', validatePermissionId, authorize("DELETE_permission"), asyn userType: 'root' as NSLogs.userType, type: 'failed' as NSLogs.Type, request: 'Delete Permission with id: ' + id - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'failed', + 'permission', + 'Delete Permission with id: ' + id, + res.locals.organizationAdmin?.id, + res.locals.organizationAdmin?.name, + ).then().catch() + next(err); }); }) @@ -80,11 +101,16 @@ router.put("/:id", authorize("PUT_permission"), validatePermissionId, async (req userType: 'root' as NSLogs.userType, type: 'success' as NSLogs.Type, request: 'Edit Permission with id: ' + req.params.id - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'success', + 'permission', + 'Edit Permission with id: ' + req.params.id, + res.locals.organizationAdmin?.id, + res.locals.organizationAdmin?.name + ).then().catch() + res.status(201).send("Permission edited successfully!!") }).catch(err => { log({ @@ -93,11 +119,16 @@ router.put("/:id", authorize("PUT_permission"), validatePermissionId, async (req userType: 'root' as NSLogs.userType, type: 'failed' as NSLogs.Type, request: 'Edit Permission with id: ' + req.params.id - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'failed', + 'permission', + 'Edit Permission with id: ' + req.params.id, + res.locals.organizationAdmin?.id, + res.locals.organizationAdmin?.name + ).then().catch() + next(err); }); }); @@ -118,11 +149,16 @@ router.get('/', authorize("GET_permissions"), async (req, res, next) => { userType: 'root' as NSLogs.userType, type: 'success' as NSLogs.Type, request: 'Get Permission/s' - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'success', + 'permission', + 'Get Permission/s', + res.locals.organizationAdmin?.id, + res.locals.organizationAdmin?.name + ).then().catch() + res.send(data); }) .catch(err => { @@ -132,11 +168,16 @@ router.get('/', authorize("GET_permissions"), async (req, res, next) => { userType: 'root' as NSLogs.userType, type: 'failed' as NSLogs.Type, request: 'Get Permission/s' - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'failed', + 'permission', + 'Get Permission/s', + res.locals.organizationAdmin?.id, + res.locals.organizationAdmin?.name + ).then().catch() + next(err); }); }); From ffa99a8f5295e5d71b1e030b7b1e87d2733c35b0 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Wed, 11 Oct 2023 14:00:05 +0300 Subject: [PATCH 125/146] Calling loging to aws-cloudWatch in role rout --- src/routes/role.ts | 125 ++++++++++++++++++++++++++++++--------------- 1 file changed, 83 insertions(+), 42 deletions(-) diff --git a/src/routes/role.ts b/src/routes/role.ts index 4e02bfee..1fb1bc04 100644 --- a/src/routes/role.ts +++ b/src/routes/role.ts @@ -5,6 +5,7 @@ import { authorize } from '../middleware/auth/authorize.js'; import { validateEditedRole, validateRole, validateRoleId } from '../middleware/validation/role.js'; import { log } from '../controllers/dataBase-logger.js'; import { NSLogs } from '../../types/logs.js'; +import { logToCloudWatch } from '../controllers/cloudWatch-logger.js'; var router = express.Router(); @@ -16,11 +17,16 @@ router.post('/', authorize("POST_role"), validateRole, (req, res, next) => { userType: 'root' as NSLogs.userType, type: 'success' as NSLogs.Type, request: 'Create Role ' + req.body.name - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'success', + 'role', + 'Create Role ' + req.body.name, + res.locals.organizationAdmin?.id, + res.locals.organizationAdmin?.name + ).then().catch() + res.status(201).send("Role created successfully!!") }).catch(err => { log({ @@ -29,11 +35,16 @@ router.post('/', authorize("POST_role"), validateRole, (req, res, next) => { userType: 'root' as NSLogs.userType, type: 'failed' as NSLogs.Type, request: 'Create Role ' + req.body.name - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'failed', + 'role', + 'Create Role ' + req.body.name, + res.locals.organizationAdmin?.id, + res.locals.organizationAdmin?.name + ).then().catch() + next(err); }); }); @@ -49,11 +60,16 @@ router.delete('/:id', validateRoleId, authorize("DELETE_role"), async (req, res, userType: 'root' as NSLogs.userType, type: 'success' as NSLogs.Type, request: 'Delete Role with id: ' + id - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'success', + 'role', + 'Delete Role with id: ' + id, + res.locals.organizationAdmin?.id, + res.locals.organizationAdmin?.name + ).then().catch() + res.send(data); }) .catch(err => { @@ -63,11 +79,16 @@ router.delete('/:id', validateRoleId, authorize("DELETE_role"), async (req, res, userType: 'root' as NSLogs.userType, type: 'failed' as NSLogs.Type, request: 'Delete Role with id: ' + id - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'failed', + 'role', + 'Delete Role with id: ' + id, + res.locals.organizationAdmin?.id, + res.locals.organizationAdmin?.name + ).then().catch() + next(err); }); }) @@ -80,11 +101,16 @@ router.put("/:id", authorize("PUT_role"), validateEditedRole, async (req, res, n userType: 'root' as NSLogs.userType, type: 'success' as NSLogs.Type, request: 'Edit Role with id: ' + req.params.id - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'success', + 'role', + 'Edit Role with id: ' + req.params.id, + res.locals.organizationAdmin?.id, + res.locals.organizationAdmin?.name + ).then().catch() + res.status(201).send("Role edited successfully!!") }).catch(err => { log({ @@ -93,11 +119,16 @@ router.put("/:id", authorize("PUT_role"), validateEditedRole, async (req, res, n userType: 'root' as NSLogs.userType, type: 'failed' as NSLogs.Type, request: 'Edit Role with id: ' + req.params.id - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'failed', + 'role', + 'Edit Role with id: ' + req.params.id, + res.locals.organizationAdmin?.id, + res.locals.organizationAdmin?.name + ).then().catch() + next(err); }); }); @@ -118,25 +149,35 @@ router.get('/', authorize("GET_roles"), async (req, res, next) => { userType: 'root' as NSLogs.userType, type: 'success' as NSLogs.Type, request: 'Get Role/s' - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'success', + 'role', + 'Get Role/s', + res.locals.organizationAdmin?.id, + res.locals.organizationAdmin?.name + ).then().catch() + res.send(data); }) .catch(err => { log({ - userId: res.locals.organizationAdmin.id, - userName: res.locals.organizationAdmin.name, + userId: res.locals.organizationAdmin?.id, + userName: res.locals.organizationAdmin?.name, userType: 'root' as NSLogs.userType, type: 'failed' as NSLogs.Type, request: 'Get Role/s' - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'failed', + 'role', + 'Get Role/s', + res.locals.organizationAdmin?.id, + res.locals.organizationAdmin?.name, + ).then().catch() + next(err); }); }); From 94a4ee311e0176afcf8eb09810d88f6d3a194585 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Wed, 11 Oct 2023 14:19:20 +0300 Subject: [PATCH 126/146] Calling loging to aws-cloudWatch in voluntary work rout --- src/routes/voluntaryWork.ts | 392 ++++++++++++++++++++++-------------- 1 file changed, 241 insertions(+), 151 deletions(-) diff --git a/src/routes/voluntaryWork.ts b/src/routes/voluntaryWork.ts index 9fc4ffc1..894d3f65 100644 --- a/src/routes/voluntaryWork.ts +++ b/src/routes/voluntaryWork.ts @@ -7,23 +7,29 @@ import { validateEditedVoluntaryWork, validateVoluntaryWork, validateVoluntaryWo import { UploadedFile } from 'express-fileupload'; import { log } from '../controllers/dataBase-logger.js'; import { NSLogs } from '../../types/logs.js'; +import { logToCloudWatch } from '../controllers/cloudWatch-logger.js'; var router = express.Router(); router.post('/', authorize("POST_voluntaryWork"), validateVoluntaryWork, (req, res, next) => { createVoluntaryWork({ ...req.body, creatorId: res.locals.volunteer?.id || res.locals.organizationAdmin?.id }).then(() => { - res.status(201).send("Voluntary work created successfully!!") log({ userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'success' as NSLogs.Type, request: 'Create Voluntary Work ' + req.body.name - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'success', + 'voluntary work', + 'Create Voluntary Work ' + req.body.name, + res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + res.locals.organizationAdmin?.name || res.locals.volunteer?.name + ).then().catch() + + res.status(201).send("Voluntary work created successfully!!") }).catch(err => { log({ userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, @@ -31,11 +37,16 @@ router.post('/', authorize("POST_voluntaryWork"), validateVoluntaryWork, (req, r userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'failed' as NSLogs.Type, request: 'Create Voluntary Work ' + req.body.name - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'failed', + 'voluntary work', + 'Create Voluntary Work ' + req.body.name, + res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + res.locals.organizationAdmin?.name || res.locals.volunteer?.name + ).then().catch() + next(err); }); }); @@ -51,11 +62,16 @@ router.delete('/:id', validateVoluntaryWorkId, authorize("DELETE_voluntaryWork") userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'success' as NSLogs.Type, request: 'Delete Voluntary Work with id: ' + id - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'success', + 'voluntary work', + 'Delete Voluntary Work with id: ' + id, + res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + res.locals.organizationAdmin?.name || res.locals.volunteer?.name + ).then().catch() + res.send(data); }) .catch(err => { @@ -65,11 +81,16 @@ router.delete('/:id', validateVoluntaryWorkId, authorize("DELETE_voluntaryWork") userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'failed' as NSLogs.Type, request: 'Delete Voluntary Work with id: ' + id - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'failed', + 'voluntary work', + 'Delete Voluntary Work with id: ' + id, + res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + res.locals.organizationAdmin?.name || res.locals.volunteer?.name + ).then().catch() + next(err); }); }) @@ -82,11 +103,16 @@ router.put("/:id", authorize("PUT_voluntaryWork"), validateEditedVoluntaryWork, userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'success' as NSLogs.Type, request: 'Edit Voluntary Work with id: ' + req.params.id - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'success', + 'voluntary work', + 'Edit Voluntary Work with id: ' + req.params.id, + res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + res.locals.organizationAdmin?.name || res.locals.volunteer?.name + ).then().catch() + res.status(201).send("Voluntary Work edited successfully!!") }).catch(err => { log({ @@ -95,11 +121,16 @@ router.put("/:id", authorize("PUT_voluntaryWork"), validateEditedVoluntaryWork, userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'failed' as NSLogs.Type, request: 'Edit Voluntary Work with id: ' + req.params.id - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'failed', + 'voluntary work', + 'Edit Voluntary Work with id: ' + req.params.id, + res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + res.locals.organizationAdmin?.name || res.locals.volunteer?.name + ).then().catch() + next(err); }); }); @@ -137,11 +168,16 @@ router.get('/', authorize("GET_voluntaryWorks"), async (req, res, next) => { userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'success' as NSLogs.Type, request: 'Get Voluntary Work/s' - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'success', + 'voluntary work', + 'Get Voluntary Work/s', + res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + res.locals.organizationAdmin?.name || res.locals.volunteer?.name + ).then().catch() + res.send(data); }) .catch(err => { @@ -151,11 +187,16 @@ router.get('/', authorize("GET_voluntaryWorks"), async (req, res, next) => { userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'failed' as NSLogs.Type, request: 'Get Voluntary Work/s' - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'failed', + 'voluntary work', + 'Get Voluntary Work/s', + res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + res.locals.organizationAdmin?.name || res.locals.volunteer?.name + ).then().catch() + next(err); }); }); @@ -193,11 +234,16 @@ router.get('/analysis', authorize("GET_analysis"), async (req, res, next) => { userType: 'root' as NSLogs.userType, type: 'success' as NSLogs.Type, request: 'Analysis Voluntary Work/s' - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'success', + 'voluntary work', + 'Analysis Voluntary Work/s', + res.locals.organizationAdmin?.id, + res.locals.organizationAdmin?.name + ).then().catch() + res.send(data); }) .catch(err => { @@ -207,11 +253,16 @@ router.get('/analysis', authorize("GET_analysis"), async (req, res, next) => { userType: "root" as NSLogs.userType, type: 'failed' as NSLogs.Type, request: 'Analysis Voluntary Work/s' - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'failed', + 'voluntary work', + 'Analysis Voluntary Work/s', + res.locals.organizationAdmin?.id, + res.locals.organizationAdmin?.name + ).then().catch() + next(err); }); }); @@ -226,11 +277,16 @@ router.get('/recommendation', authorize("GET_recommendation"), async (req, res, userType: res.locals.volunteer?.type as NSLogs.userType, type: 'success' as NSLogs.Type, request: 'Get recommendation' - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'success', + 'voluntary work', + 'Get recommendation', + res.locals.volunteer?.id, + res.locals.volunteer?.name + ).then().catch() + res.send(data); }) .catch(err => { @@ -240,11 +296,16 @@ router.get('/recommendation', authorize("GET_recommendation"), async (req, res, userType: res.locals.volunteer?.type as NSLogs.userType, type: 'failed' as NSLogs.Type, request: 'Get recommendation' - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'failed', + 'voluntary work', + 'Get recommendation', + res.locals.volunteer?.id, + res.locals.volunteer?.name + ).then().catch() + next(err); }); }); @@ -257,11 +318,16 @@ router.put("/rating/:id", validateVoluntaryWorkId, authorize("PUT_rating"), chec userType: res.locals.volunteer?.type as NSLogs.userType, type: 'success' as NSLogs.Type, request: 'Add Rating to voluntary work with id' + req.params.id - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'success', + 'voluntary work', + 'Add Rating to voluntary work with id' + req.params.id, + res.locals.volunteer?.id, + res.locals.volunteer?.name + ).then().catch() + res.status(201).send("Rating added successfully!!") }).catch(err => { log({ @@ -270,11 +336,16 @@ router.put("/rating/:id", validateVoluntaryWorkId, authorize("PUT_rating"), chec userType: res.locals.volunteer?.type as NSLogs.userType, type: 'failed' as NSLogs.Type, request: 'Add Rating to voluntary work with id' + req.params.id - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'failed', + 'voluntary work', + 'Add Rating to voluntary work with id' + req.params.id, + res.locals.volunteer?.id, + res.locals.volunteer?.name + ).then().catch() + next(err); }); }); @@ -287,11 +358,16 @@ router.put("/feedback/:id", validateVoluntaryWorkId, authorize("PUT_feedback"), userType: res.locals.volunteer?.type as NSLogs.userType, type: 'success' as NSLogs.Type, request: 'Add feedback to voluntary work with id' + req.params.id - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'success', + 'voluntary work', + 'Add feedback to voluntary work with id' + req.params.id, + res.locals.volunteer?.id, + res.locals.volunteer?.name + ).then().catch() + res.status(201).send("Feedback added successfully!!") }).catch(err => { log({ @@ -300,48 +376,23 @@ router.put("/feedback/:id", validateVoluntaryWorkId, authorize("PUT_feedback"), userType: res.locals.volunteer?.type as NSLogs.userType, type: 'failed' as NSLogs.Type, request: 'Add feedback to voluntary work with id' + req.params.id - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'failed', + 'voluntary work', + 'Add feedback to voluntary work with id' + req.params.id, + res.locals.volunteer?.id, + res.locals.volunteer?.name + ).then().catch() + next(err); }); }); -// router.put("/images/:id", validateVoluntaryWorkId, authorize("PUT_images"), async (req, res, next) => { -// putImages(Number(req.params.id), ((Array.isArray(req.files?.image) ? req.files?.image : [req.files?.image]).filter(Boolean)) as UploadedFile[]).then(() => { -// log({ -// userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, -// userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, -// userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, -// type: 'success' as NSLogs.Type, -// request: 'Add images to voluntary work with id' + req.params.id -// }).then(() => { -// console.log('logged'); -// }).catch(err => { -// console.log('NOT logged'); -// }) -// res.status(201).send("Images added successfully!!") -// }).catch(err => { -// log({ -// userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, -// userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, -// userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, -// type: 'failed' as NSLogs.Type, -// request: 'Add images to voluntary work with id' + req.params.id -// }).then(() => { -// console.log('logged'); -// }).catch(err => { -// console.log('NOT logged'); -// }) -// next(err); -// }); -// }); router.put("/images/:id", validateVoluntaryWorkId, authorize("PUT_images"), async (req, res, next) => { const images = req.files?.image; if (!images) { - // Handle the case when 'images' is undefined return res.status(400).send("No images provided."); } @@ -356,11 +407,15 @@ router.put("/images/:id", validateVoluntaryWorkId, authorize("PUT_images"), asyn userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'success' as NSLogs.Type, request: 'Add images to voluntary work with id' + req.params.id - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }); + }).then().catch() + + logToCloudWatch( + 'success', + 'voluntary work', + 'Add images to voluntary work with id' + req.params.id, + res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + res.locals.organizationAdmin?.name || res.locals.volunteer?.name + ).then().catch() res.status(201).send("Images added successfully!!"); } catch (err) { @@ -370,11 +425,16 @@ router.put("/images/:id", validateVoluntaryWorkId, authorize("PUT_images"), asyn userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'failed' as NSLogs.Type, request: 'Add images to voluntary work with id' + req.params.id - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }); + }).then().catch() + + logToCloudWatch( + 'failed', + 'voluntary work', + 'Add images to voluntary work with id' + req.params.id, + res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + res.locals.organizationAdmin?.name || res.locals.volunteer?.name + ).then().catch() + next(err); } }); @@ -387,11 +447,16 @@ router.put("/register/:id", validateVoluntaryWorkId, authorize("REGISTER_volunta userType: res.locals.volunteer?.type as NSLogs.userType, type: 'success' as NSLogs.Type, request: 'Register to voluntary work with id' + req.params.id - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'success', + 'voluntary work', + 'Register to voluntary work with id' + req.params.id, + res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + res.locals.organizationAdmin?.name || res.locals.volunteer?.name + ).then().catch() + res.status(201).send("Registration done successfully!!") }).catch(err => { log({ @@ -400,11 +465,16 @@ router.put("/register/:id", validateVoluntaryWorkId, authorize("REGISTER_volunta userType: res.locals.volunteer?.type as NSLogs.userType, type: 'failed' as NSLogs.Type, request: 'Register to voluntary work with id' + req.params.id - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'failed', + 'voluntary work', + 'Register to voluntary work with id' + req.params.id, + res.locals.volunteer?.id, + res.locals.volunteer?.name + ).then().catch() + next(err); }); } else if (res.locals.organizationAdmin) { @@ -418,11 +488,16 @@ router.put("/register/:id", validateVoluntaryWorkId, authorize("REGISTER_volunta userType: (res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'success' as NSLogs.Type, request: 'Register By Organization Admin to voluntary work with id' + req.params.id + " volunteer id: " + req.body.volunteerId.toString() - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'success', + 'voluntary work', + 'Register By Organization Admin to voluntary work with id' + req.params.id + " volunteer id: " + req.body.volunteerId.toString(), + res.locals.organizationAdmin?.id, + res.locals.organizationAdmin?.name + ).then().catch() + res.status(201).send("Registration done successfully!!") }).catch(err => { log({ @@ -431,11 +506,16 @@ router.put("/register/:id", validateVoluntaryWorkId, authorize("REGISTER_volunta userType: (res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'failed' as NSLogs.Type, request: 'Register By Organization Admin to voluntary work with id' + req.params.id + " volunteer id: " + req.body.volunteerId.toString() - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'failed', + 'voluntary work', + 'Register By Organization Admin to voluntary work with id' + req.params.id + " volunteer id: " + req.body.volunteerId.toString(), + res.locals.organizationAdmin?.id, + res.locals.organizationAdmin?.name + ).then().catch() + next(err); }); } @@ -449,11 +529,16 @@ router.put("/deregister/:id", validateVoluntaryWorkId, authorize("DEREGISTER_vol userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'success' as NSLogs.Type, request: 'Deregister to voluntary work with id' + req.params.id + " volunteer id: " + res.locals.volunteer?.id || req.body.volunteerId.toString() - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'success', + 'voluntary work', + 'Deregister to voluntary work with id' + req.params.id + " volunteer id: " + res.locals.volunteer?.id || req.body.volunteerId.toString(), + res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + res.locals.organizationAdmin?.name || res.locals.volunteer?.name + ).then().catch() + res.status(201).send("Deregistration done successfully!!") }).catch(err => { log({ @@ -462,11 +547,16 @@ router.put("/deregister/:id", validateVoluntaryWorkId, authorize("DEREGISTER_vol userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'failed' as NSLogs.Type, request: 'Deregister to voluntary work with id' + req.params.id + " volunteer id: " + res.locals.volunteer?.id || req.body.volunteerId.toString() - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'failed', + 'voluntary work', + 'Deregister to voluntary work with id' + req.params.id + " volunteer id: " + res.locals.volunteer?.id || req.body.volunteerId.toString(), + res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + res.locals.organizationAdmin?.name || res.locals.volunteer?.name + ).then().catch() + next(err); }); }); From fecc3c5c43641568a0cc6af86bc021f2794be323 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Wed, 11 Oct 2023 14:48:07 +0300 Subject: [PATCH 127/146] Calling loging to aws-cloudWatch in volunteer rout --- src/controllers/cloudWatch-logger.ts | 19 +-- src/routes/volunteer.ts | 196 ++++++++++++++++++--------- 2 files changed, 132 insertions(+), 83 deletions(-) diff --git a/src/controllers/cloudWatch-logger.ts b/src/controllers/cloudWatch-logger.ts index 6d8112a6..252af17d 100644 --- a/src/controllers/cloudWatch-logger.ts +++ b/src/controllers/cloudWatch-logger.ts @@ -24,21 +24,4 @@ export const logToCloudWatch = async (logGroupName:string, logStreamName:string, } catch (error) { console.error('Error sending log event:', error); } -}; - - logToCloudWatch( - 'failed', - '', - 'Volunteer registered successfully!', - '', - '' -).then().catch() - - logToCloudWatch( - 'success', - '', - 'Volunteer registered successfully!', - '', - '' -).then().catch() - +}; \ No newline at end of file diff --git a/src/routes/volunteer.ts b/src/routes/volunteer.ts index 12a21c6a..5fe6562e 100644 --- a/src/routes/volunteer.ts +++ b/src/routes/volunteer.ts @@ -6,6 +6,7 @@ import { createVolunteer, deleteVolunteer, editVolunteer, getVolunteers, login } import { NSVolunteer } from '../../types/volunteer.js'; import { log } from '../controllers/dataBase-logger.js'; import { NSLogs } from '../../types/logs.js'; +import { logToCloudWatch } from '../controllers/cloudWatch-logger.js'; var router = express.Router(); @@ -17,11 +18,16 @@ router.post('/register', validateVolunteer, (req, res, next) => { userType: req.body.type as NSLogs.userType, type: 'success' as NSLogs.Type, request: 'Register volunteer ' + req.body.name - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'success', + 'volunteer', + 'Register volunteer ' + req.body.name, + req.body.id, + req.body.name + ).then().catch() + res.status(201).send("Volunteer created successfully!!") }).catch(err => { log({ @@ -30,11 +36,16 @@ router.post('/register', validateVolunteer, (req, res, next) => { userType: req.body.type as NSLogs.userType, type: 'failed' as NSLogs.Type, request: 'Register volunteer' + req.body.name - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'failed', + 'volunteer', + 'Register volunteer ' + req.body.name, + req.body.id, + req.body.name + ).then().catch() + next(err); }); }); @@ -56,11 +67,16 @@ router.post('/login', (req, res, next) => { userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'success' as NSLogs.Type, request: 'Login ' + res.locals.organizationAdmin?.name || res.locals.volunteer?.name - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'success', + 'volunteer', + 'Login ' + res.locals.organizationAdmin?.name || res.locals.volunteer?.name, + res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + res.locals.organizationAdmin?.name || res.locals.volunteer?.name + ).then().catch() + res.status(201).send("You logged in successfully !"); }) .catch(err => { @@ -70,11 +86,16 @@ router.post('/login', (req, res, next) => { userType: 'volunteer' as NSLogs.userType, type: 'failed' as NSLogs.Type, request: 'Login' + res.locals.organizationAdmin?.name || res.locals.volunteer?.name - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'failed', + 'volunteer', + 'Login ' + res.locals.organizationAdmin?.name || res.locals.volunteer?.name, + res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + res.locals.organizationAdmin?.name || res.locals.volunteer?.name + ).then().catch() + res.status(401).send(err); }) }); @@ -90,11 +111,16 @@ router.delete('/:id', authenticate, authorize("DELETE_volunteer"), async (req, r userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'success' as NSLogs.Type, request: 'Delete Volunteer with id: ' + id - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'success', + 'volunteer', + 'Delete Volunteer with id: ' + id, + res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + res.locals.organizationAdmin?.name || res.locals.volunteer?.name + ).then().catch() + res.send(data); }) .catch(error => { @@ -104,11 +130,16 @@ router.delete('/:id', authenticate, authorize("DELETE_volunteer"), async (req, r userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'failed' as NSLogs.Type, request: 'Delete Volunteer with id: ' + id - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'failed', + 'volunteer', + 'Delete Volunteer with id: ' + id, + res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + res.locals.organizationAdmin?.name || res.locals.volunteer?.name + ).then().catch() + next(error); }); }) @@ -121,11 +152,16 @@ router.put("/:id", authenticate, authorize("PUT_volunteer"), validateEditedVolun userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'success' as NSLogs.Type, request: 'Edit Volunteer with id: ' + req.params.id?.toString() - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'success', + 'volunteer', + 'Edit Volunteer with id: ' + req.params.id?.toString(), + res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + res.locals.organizationAdmin?.name || res.locals.volunteer?.name + ).then().catch() + res.status(201).send("Volunteer edited successfully!!") }).catch(err => { log({ @@ -134,11 +170,16 @@ router.put("/:id", authenticate, authorize("PUT_volunteer"), validateEditedVolun userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'failed' as NSLogs.Type, request: 'Edit Volunteer with id: ' + req.params.id?.toString() - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'failed', + 'volunteer', + 'Edit Volunteer with id: ' + req.params.id?.toString(), + res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + res.locals.organizationAdmin?.name || res.locals.volunteer?.name + ).then().catch() + next(err); }); }); @@ -166,11 +207,16 @@ router.get('/', authenticate, authorize("GET_volunteers"), async (req, res, next userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'success' as NSLogs.Type, request: 'get Volunteer/s' - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'success', + 'volunteer', + 'get Volunteer/s', + res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + res.locals.organizationAdmin?.name || res.locals.volunteer?.name + ).then().catch() + res.send(data); }) .catch(err => { @@ -180,11 +226,16 @@ router.get('/', authenticate, authorize("GET_volunteers"), async (req, res, next userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'failed' as NSLogs.Type, request: 'Get Volunteer/s' - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'failed', + 'volunteer', + 'get Volunteer/s', + res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + res.locals.organizationAdmin?.name || res.locals.volunteer?.name + ).then().catch() + next(err); }); }); @@ -202,11 +253,16 @@ router.get("/logout", authenticate, (req, res, next) => { userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'success' as NSLogs.Type, request: 'Logout ' + res.locals.organizationAdmin?.name || res.locals.volunteer?.name - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'success', + 'volunteer', + 'Logout ' + res.locals.organizationAdmin?.name || res.locals.volunteer?.name, + res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + res.locals.organizationAdmin?.name || res.locals.volunteer?.name + ).then().catch() + res.send("You logged out successfully !"); }) @@ -218,11 +274,16 @@ router.get('/me', authenticate, authorize("GET_me"), async (req, res, next) => { userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'success' as NSLogs.Type, request: 'Get my information' - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'success', + 'volunteer', + 'Get my information', + res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + res.locals.organizationAdmin?.name || res.locals.volunteer?.name + ).then().catch() + res.send(res.locals.volunteer); } else if (res.locals.organizationAdmin) { log({ @@ -231,11 +292,16 @@ router.get('/me', authenticate, authorize("GET_me"), async (req, res, next) => { userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, type: 'failed' as NSLogs.Type, request: 'Get my information' - }).then(() => { - console.log('logged'); - }).catch(err => { - console.log('NOT logged'); - }) + }).then().catch() + + logToCloudWatch( + 'failed', + 'volunteer', + 'Get my information', + res.locals.organizationAdmin?.id || res.locals.volunteer?.id, + res.locals.organizationAdmin?.name || res.locals.volunteer?.name + ).then().catch() + res.send(res.locals.organizationAdmin); } }); From 1a958eb3b382ffbd1d7d615fc31da3ef2ebade3c Mon Sep 17 00:00:00 2001 From: TarteelTamimi Date: Sun, 15 Oct 2023 13:18:17 +0300 Subject: [PATCH 128/146] test --- __test__/createOrgAdmin.test.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/__test__/createOrgAdmin.test.js b/__test__/createOrgAdmin.test.js index 124992ca..fc63a9e5 100644 --- a/__test__/createOrgAdmin.test.js +++ b/__test__/createOrgAdmin.test.js @@ -12,7 +12,7 @@ afterAll(async () => { const tmpData = { "name": "Sarah Abu Irmaileh", "email": "tamimitarteel27@gamil.com", - "password": "toto2003", + "password": "123456", "organizationId": "e4b41a72-2abe-459c-8657-7a09956f1243" }; @@ -26,3 +26,4 @@ describe("create an organization admin", () => { expect(data.name).toBe('Sarah Abu Irmaileh'); }) }) +////// From 833b980ec002641913903ceeb964290276162e05 Mon Sep 17 00:00:00 2001 From: TarteelTamimi Date: Sun, 15 Oct 2023 14:16:22 +0300 Subject: [PATCH 129/146] optimize error handler --- __test__/createOrgAdmin.test.js | 1 - src/controllers/OrganizationProfile .ts | 10 ++++---- src/controllers/organizationAdmin.ts | 12 ++++----- src/controllers/permission.ts | 8 +++--- src/controllers/role.ts | 8 +++--- src/controllers/voluntaryWork.ts | 28 ++++++++++----------- src/controllers/volunteer.ts | 10 ++++---- src/middleware/errorHandler/errorHandler.ts | 5 ++-- types/error.ts | 7 ++++++ 9 files changed, 48 insertions(+), 41 deletions(-) create mode 100644 types/error.ts diff --git a/__test__/createOrgAdmin.test.js b/__test__/createOrgAdmin.test.js index fc63a9e5..1a4a17a9 100644 --- a/__test__/createOrgAdmin.test.js +++ b/__test__/createOrgAdmin.test.js @@ -26,4 +26,3 @@ describe("create an organization admin", () => { expect(data.name).toBe('Sarah Abu Irmaileh'); }) }) -////// diff --git a/src/controllers/OrganizationProfile .ts b/src/controllers/OrganizationProfile .ts index 21c9ae37..e55ad5d1 100644 --- a/src/controllers/OrganizationProfile .ts +++ b/src/controllers/OrganizationProfile .ts @@ -10,7 +10,7 @@ const createOrganizationProfile = async (payload: NSOrganizationProfile.Item) => return newOrganizationProfile.save(); } catch (err) { baseLogger.error(err); - throw createError(404,); + throw ", when trying to create Organization profile"; } } @@ -25,7 +25,7 @@ const editOrganizationProfile = async (payload: { id: string, name: string, desc } } catch (err) { baseLogger.error(err); - throw createError(404); + throw createError({status: 404, message: "Organization"}); } } @@ -34,7 +34,7 @@ const deleteOrganizationProfile = async (profileId: string) => { return OrganizationProfile.delete(profileId); } catch (err) { baseLogger.error(err); - throw createError(404); + throw createError({status: 404, message: "Organization"}); } } @@ -63,7 +63,7 @@ const getOrganizationProfile = async (payload: { if (admin) { return admin; } else { - throw "Admin not found" + throw createError({status: 404, message: "Admin"}); } } @@ -84,7 +84,7 @@ const getOrganizationProfile = async (payload: { }; } catch (err) { baseLogger.error(err); - throw createError(404); + throw createError({status: 404, message: "Organization"}); } } diff --git a/src/controllers/organizationAdmin.ts b/src/controllers/organizationAdmin.ts index c223a751..1d59dd9f 100644 --- a/src/controllers/organizationAdmin.ts +++ b/src/controllers/organizationAdmin.ts @@ -23,11 +23,11 @@ const createOrganizationAdmin = async (payload: NSOrganizationAdmin.Item) => { newOrganizationAdmin.orgProfile = organization; return newOrganizationAdmin.save(); } else { - throw "Organization not found"; + throw createError({status: 404, message: "Organization"}); } } catch (err) { baseLogger.error(err); - throw createError(404); + throw ", when trying to create Organization admin"; } } @@ -68,7 +68,7 @@ const getOrganizationAdmins = async (payload: { const admin = await OrganizationAdmin.findOne({ where: { orgProfile: { id: organization.id } } }); return { name: admin?.name, createdAt: admin?.createdAt, email: admin?.email }; } else { - throw "Organization name not found"; + throw createError({status: 404, message: "Organization"}); } } @@ -92,7 +92,7 @@ const getOrganizationAdmins = async (payload: { }; } catch (err) { baseLogger.error(err) - throw createError(404); + throw createError({status: 404, message: "Organization admin"}); } } @@ -101,7 +101,7 @@ const deleteOrganizationAdmin = async (adminId: string) => { return OrganizationAdmin.delete(adminId); } catch (err) { baseLogger.error(err); - throw createError(404); + throw createError({status: 404, message: "Organization admin"}); } } @@ -138,7 +138,7 @@ const editOrganizationAdmin = async (payload: { id: string, name: string, email: } else { - throw "Organization admin not found"; + throw createError({status: 404, message: "Organization admin"}); } } catch (err) { baseLogger.error(err) diff --git a/src/controllers/permission.ts b/src/controllers/permission.ts index 1e6a3c43..fca7a9b9 100644 --- a/src/controllers/permission.ts +++ b/src/controllers/permission.ts @@ -10,7 +10,7 @@ const createPermission = async (payload: NSPermission.Item) => { } catch (error) { baseLogger.error(error); - throw createError(404); + throw ", when trying to create Permission"; } } @@ -19,7 +19,7 @@ const deletePermission = async (permissionId: number) => { return Permission.delete(permissionId); } catch (err) { baseLogger.error(err); - throw createError(404); + throw createError({status: 404, message: "Permission"}); } } @@ -34,7 +34,7 @@ const editPermission = async (payload: { name: string, id: number }) => { } } catch (err) { baseLogger.error(err); - throw createError(404); + throw createError({status: 404, message: "Permission"}); } } @@ -73,7 +73,7 @@ const getPermissions = async (payload: { }; } catch (err) { baseLogger.error(err); - throw err; + throw createError({status: 404, message: "Permission"}); } } diff --git a/src/controllers/role.ts b/src/controllers/role.ts index b429f9bb..a7b2799d 100644 --- a/src/controllers/role.ts +++ b/src/controllers/role.ts @@ -17,7 +17,7 @@ const createRole = async (payload: NSRole.Item) => { } catch (error) { baseLogger.error(error); - throw error; + throw ", when trying to create Role"; } } @@ -26,7 +26,7 @@ const deleteRole = async (roleId: number) => { return Role.delete(roleId); } catch (err) { baseLogger.error(err); - throw createError(404); + throw createError({status: 404, message: "Role"}); } } @@ -40,7 +40,7 @@ const editRole = async (payload: { name: NSRole.Type, id: number }) => { } } catch (err) { baseLogger.error(err); - throw createError(404); + throw createError({status: 404, message: "Role"}); } } @@ -78,7 +78,7 @@ const getRoles = async (payload: { }; } catch (err) { baseLogger.error(err); - throw err; + throw createError({status: 404, message: "Role"}); } } diff --git a/src/controllers/voluntaryWork.ts b/src/controllers/voluntaryWork.ts index 01aa9420..92f82706 100644 --- a/src/controllers/voluntaryWork.ts +++ b/src/controllers/voluntaryWork.ts @@ -23,7 +23,7 @@ const createVoluntaryWork = async (payload: NSVoluntaryWork.Item) => { return newVoluntaryWork.save(); } catch (err) { baseLogger.error(err); - throw createError(404,); + throw ", when trying to create Voluntary work"; } } @@ -33,7 +33,7 @@ const deleteVoluntaryWork = async (voluntaryWorkId: number) => { return VoluntaryWork.delete(voluntaryWorkId); } catch (err) { baseLogger.error(err); - throw createError(404,); + throw createError({status: 404, message: "Voluntary work"}); } } @@ -70,7 +70,7 @@ const editVoluntaryWork = async (payload: NSVoluntaryWork.Edit) => { } } catch (error) { baseLogger.error(error); - throw createError(404,); + throw createError({status: 404, message: "Voluntary work"}); } } @@ -79,7 +79,7 @@ const getVoluntaryWork = (payload: { id: number }) => { return VoluntaryWork.findOne({ where: { id: payload.id } }) } catch (err) { baseLogger.error(err); - throw err; + throw createError({status: 404, message: "Voluntary work"}); } } @@ -201,7 +201,7 @@ const getVoluntaryWorks = async (payload: NSVoluntaryWork.GetVoluntaryWorks) => }; } catch (err) { baseLogger.error(err); - throw createError(404,); + throw createError({status: 404, message: "Voluntary work"}); } } @@ -230,11 +230,11 @@ const putFeedback = async (id: number, feedback: string) => { voluntaryWork.feedback.push(feedback); await voluntaryWork.save(); } else { - throw "Voluntary work not found" + throw createError({status: 404, message: "Voluntary work"}); } } catch (err) { baseLogger.error(err); - throw createError(404,); + throw ", when trying to add Feedback"; } } @@ -264,7 +264,7 @@ const putImages = async (id: number, uploadedFiles: UploadedFile[]) => { } } catch (err) { baseLogger.error(err); - throw (err); + throw ", when trying to add Image"; } } @@ -273,7 +273,7 @@ const registerByVolunteer = async (workId: number, volunteerProfile: Volunteer[" const voluntaryWork = await VoluntaryWork.findOne({ where: { id: workId } }); if (!voluntaryWork) { - throw createError(404); + throw createError({status: 404, message: "Voluntary work"}); } if ( @@ -299,7 +299,7 @@ const registerByVolunteer = async (workId: number, volunteerProfile: Volunteer[" return "Registration successful!"; } catch (err) { baseLogger.error(err); - throw createError(400); + throw ", when trying to register by Volunteer"; } } @@ -329,7 +329,7 @@ const registerByOrganizationAdmin = async (workId: number, volunteerId: string) return "Registration successful!"; } catch (err) { baseLogger.error(err); - throw createError(404,); + throw ", when trying to register by organization admin"; } } @@ -341,11 +341,11 @@ const deregisterVoluntaryWork = async (workId: number, volunteerId: string) => { const volunteer = await Volunteer.findOne({ where: { id: volunteerId }, relations: ["volunteerProfile"] }); if (!voluntaryWork) { - throw "Voluntary work not found"; + throw createError({status: 404, message: "Voluntary work"}); } if (!volunteer) { - throw "Volunteer not found" + throw createError({status: 404, message: "Volunteer"}); } const index = voluntaryWork.volunteerProfiles.findIndex(profile => profile.id === volunteer.volunteerProfile.id); if (index !== -1) { @@ -357,7 +357,7 @@ const deregisterVoluntaryWork = async (workId: number, volunteerId: string) => { } } catch (err) { baseLogger.error(err); - throw createError(404); + throw ", when trying to deregister voluntary work"; } } diff --git a/src/controllers/volunteer.ts b/src/controllers/volunteer.ts index 95f0563b..848d0fd4 100644 --- a/src/controllers/volunteer.ts +++ b/src/controllers/volunteer.ts @@ -48,7 +48,7 @@ const createVolunteer = async (payload: NSVolunteer.Item) => { }); } catch (err) { baseLogger.error(err); - throw createError(404); + throw ", when trying to create volunteer"; } }; @@ -57,7 +57,7 @@ const deleteVolunteer = async (volunteerId: string) => { return Volunteer.delete(volunteerId); } catch (err) { baseLogger.error(err); - throw createError(404); + throw createError({status: 404, message: "Volunteer"}); } } @@ -88,7 +88,7 @@ const editVolunteer = async (payload: { name: string, id: string, email: string, } } catch (err) { baseLogger.error(err); - throw createError(404); + throw createError({status: 404, message: "Volunteer"}); } } @@ -127,7 +127,7 @@ const login = async (email: string, name: string, id: string) => { } } catch (err) { baseLogger.error(err); - throw err; + throw createError({status: 404, message: "Something"}); } } @@ -217,7 +217,7 @@ const getVolunteers = async (payload: NSVolunteer.Item & { page: string; pageSiz }; } catch (err) { baseLogger.error(err); - throw err; + throw createError({status: 404, message: "Volunteer"}); } } diff --git a/src/middleware/errorHandler/errorHandler.ts b/src/middleware/errorHandler/errorHandler.ts index ef22105c..2c38ef0c 100644 --- a/src/middleware/errorHandler/errorHandler.ts +++ b/src/middleware/errorHandler/errorHandler.ts @@ -1,4 +1,5 @@ import express from "express" +import { NSError } from "../../../types/error.js"; const errorHandler = ( error: any, @@ -6,13 +7,13 @@ const errorHandler = ( res: express.Response, next: express.NextFunction) => { if (error.status == 404) { - res.status(404).send("Something is not found"); + res.status(404).send(error.message + " is not found"); } else if (error.status == 401) { res.status(401).send("You are unauthorized"); } else if (error.status == 403) { res.status(401).send("You don't have the permission"); } else { - res.status(500).send('Something went wrong'); + res.status(500).send('Something went wrong, ' + error); } } diff --git a/types/error.ts b/types/error.ts new file mode 100644 index 00000000..5d683a45 --- /dev/null +++ b/types/error.ts @@ -0,0 +1,7 @@ +export namespace NSError { + + export interface Item { + status: number; + message: string; + } +} From 26e273a92a5e0998f30c4678c3a7d23e0f3f9b4e Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Sun, 15 Oct 2023 19:14:44 +0300 Subject: [PATCH 130/146] Edit logs and login controller and test AWS cloud Watch --- .dockerignore | 3 ++- src/controllers/volunteer.ts | 12 ++++++------ src/routes/volunteer.ts | 30 ++++++++++++++++-------------- 3 files changed, 24 insertions(+), 21 deletions(-) diff --git a/.dockerignore b/.dockerignore index 76add878..a0d218e3 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,2 +1,3 @@ node_modules -dist \ No newline at end of file +dist +.env \ No newline at end of file diff --git a/src/controllers/volunteer.ts b/src/controllers/volunteer.ts index 848d0fd4..fe1b6736 100644 --- a/src/controllers/volunteer.ts +++ b/src/controllers/volunteer.ts @@ -57,7 +57,7 @@ const deleteVolunteer = async (volunteerId: string) => { return Volunteer.delete(volunteerId); } catch (err) { baseLogger.error(err); - throw createError({status: 404, message: "Volunteer"}); + throw createError({ status: 404, message: "Volunteer" }); } } @@ -88,7 +88,7 @@ const editVolunteer = async (payload: { name: string, id: string, email: string, } } catch (err) { baseLogger.error(err); - throw createError({status: 404, message: "Volunteer"}); + throw createError({ status: 404, message: "Volunteer" }); } } @@ -112,7 +112,7 @@ const login = async (email: string, name: string, id: string) => { expiresIn: "1d" } ); - return token; + return { token, volunteer, organizationAdmin: null }; } else if (organizationAdmin) { const token = jwt.sign( { email, name, id }, @@ -121,13 +121,13 @@ const login = async (email: string, name: string, id: string) => { expiresIn: "1d" } ); - return token; + return { token, organizationAdmin, volunteer: null }; } else { throw ("Invalid email or name or id !"); } } catch (err) { baseLogger.error(err); - throw createError({status: 404, message: "Something"}); + throw createError({ status: 404, message: "Something" }); } } @@ -217,7 +217,7 @@ const getVolunteers = async (payload: NSVolunteer.Item & { page: string; pageSiz }; } catch (err) { baseLogger.error(err); - throw createError({status: 404, message: "Volunteer"}); + throw createError({ status: 404, message: "Volunteer" }); } } diff --git a/src/routes/volunteer.ts b/src/routes/volunteer.ts index 5fe6562e..d47a85e2 100644 --- a/src/routes/volunteer.ts +++ b/src/routes/volunteer.ts @@ -56,18 +56,20 @@ router.post('/login', (req, res, next) => { const id = req.body.id; login(email, name, id) .then(data => { - res.cookie('myApp', data, { + res.cookie('myApp', data.token, { httpOnly: true, maxAge: 60 * 24 * 60 * 1000, sameSite: "lax" // Protect against CSRF attacks }); - log({ - userId: res.locals.organizationAdmin?.id || res.locals.volunteer?.id, - userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, - userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, - type: 'success' as NSLogs.Type, - request: 'Login ' + res.locals.organizationAdmin?.name || res.locals.volunteer?.name - }).then().catch() + if (data.volunteer) res.locals.volunteer = data.volunteer; + if (data.organizationAdmin) res.locals.organizationAdmin = data.organizationAdmin; + // log({ + // userId: id, + // userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, + // userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + // type: 'success' as NSLogs.Type, + // request: 'Login ' + res.locals.organizationAdmin?.name || res.locals.volunteer?.name + // }).then().catch() logToCloudWatch( 'success', @@ -81,19 +83,19 @@ router.post('/login', (req, res, next) => { }) .catch(err => { log({ - userId: req.body.id, - userName: req.body.name, + userId: id, + userName: name, userType: 'volunteer' as NSLogs.userType, type: 'failed' as NSLogs.Type, - request: 'Login' + res.locals.organizationAdmin?.name || res.locals.volunteer?.name + request: 'Login ' + res.locals.organizationAdmin?.name || res.locals.volunteer?.name }).then().catch() logToCloudWatch( 'failed', 'volunteer', - 'Login ' + res.locals.organizationAdmin?.name || res.locals.volunteer?.name, - res.locals.organizationAdmin?.id || res.locals.volunteer?.id, - res.locals.organizationAdmin?.name || res.locals.volunteer?.name + 'Login ' + name, + id, + name ).then().catch() res.status(401).send(err); From 6e943a08f4fe29f2569d6815c48bd345d63ca85a Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <211027@ppu.edu.ps> Date: Sun, 15 Oct 2023 19:24:12 +0300 Subject: [PATCH 131/146] Adding instance ip --- .github/workflows/build.yml | 2 +- src/routes/volunteer.ts | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index eef7d8ef..c9effcf3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -37,7 +37,7 @@ jobs: - name: configer docker host uses: khaledez/configure-docker-host@v1 with: - host: 52.56.237.63 + host: 3.8.96.92 user: github ssh-private-key: ${{ secrets.DEPLOYMENT_KEY }} diff --git a/src/routes/volunteer.ts b/src/routes/volunteer.ts index d47a85e2..2fb5a55a 100644 --- a/src/routes/volunteer.ts +++ b/src/routes/volunteer.ts @@ -63,13 +63,13 @@ router.post('/login', (req, res, next) => { }); if (data.volunteer) res.locals.volunteer = data.volunteer; if (data.organizationAdmin) res.locals.organizationAdmin = data.organizationAdmin; - // log({ - // userId: id, - // userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, - // userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, - // type: 'success' as NSLogs.Type, - // request: 'Login ' + res.locals.organizationAdmin?.name || res.locals.volunteer?.name - // }).then().catch() + log({ + userId: id, + userName: res.locals.organizationAdmin?.name || res.locals.volunteer?.name, + userType: (res.locals.volunteer ? res.locals.volunteer?.type : res.locals.organizationAdmin?.name === "root" ? "root" : 'admin') as NSLogs.userType, + type: 'success' as NSLogs.Type, + request: 'Login ' + res.locals.organizationAdmin?.name || res.locals.volunteer?.name + }).then().catch() logToCloudWatch( 'success', From 740a3bca8a82c863e4e9807822c4a8fa576610b9 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <127017088+SarahAbuirmeileh@users.noreply.github.com> Date: Sun, 15 Oct 2023 19:37:05 +0300 Subject: [PATCH 132/146] edit id --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c9effcf3..d6650e4b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -37,7 +37,7 @@ jobs: - name: configer docker host uses: khaledez/configure-docker-host@v1 with: - host: 3.8.96.92 + host: 13.40.24.213 user: github ssh-private-key: ${{ secrets.DEPLOYMENT_KEY }} @@ -67,4 +67,4 @@ jobs: docker compose -f docker-compose-prod.yml exec app npx typeorm-ts-node-esm migration:run -d ./src/db/dataSource.ts && docker compose -f docker-compose-prod.yml exec app mv ./src/db/migrations/1697005554406-RootUser.ts ./src/db/migration && docker compose -f docker-compose-prod.yml exec app npx typeorm-ts-node-esm migration:run -d ./src/db/dataSource.ts - \ No newline at end of file + From 3df1223f883667b5542ba0123174ed000f008773 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <127017088+SarahAbuirmeileh@users.noreply.github.com> Date: Sun, 15 Oct 2023 19:49:13 +0300 Subject: [PATCH 133/146] =?UTF-8?q?=D9=8A=D8=A7=20=D8=B1=D8=A8=20=D9=8A?= =?UTF-8?q?=D8=B2=D8=A8=D8=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d6650e4b..f691f22f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -37,7 +37,7 @@ jobs: - name: configer docker host uses: khaledez/configure-docker-host@v1 with: - host: 13.40.24.213 + host: 13.40.160.142 user: github ssh-private-key: ${{ secrets.DEPLOYMENT_KEY }} From 91136eb55dac68d1666e055fdd0c423ecb667dfa Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <127017088+SarahAbuirmeileh@users.noreply.github.com> Date: Tue, 17 Oct 2023 14:21:41 +0300 Subject: [PATCH 134/146] Update ec2 instance --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f691f22f..25143555 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -37,7 +37,7 @@ jobs: - name: configer docker host uses: khaledez/configure-docker-host@v1 with: - host: 13.40.160.142 + host: 18.133.227.48 user: github ssh-private-key: ${{ secrets.DEPLOYMENT_KEY }} From 2e229dffc980b8265224f2ee6b58f2e4c22028ad Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <127017088+SarahAbuirmeileh@users.noreply.github.com> Date: Tue, 17 Oct 2023 17:58:30 +0300 Subject: [PATCH 135/146] Update build.yml --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 25143555..11d0ef05 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -37,7 +37,7 @@ jobs: - name: configer docker host uses: khaledez/configure-docker-host@v1 with: - host: 18.133.227.48 + host: 13.42.27.232 user: github ssh-private-key: ${{ secrets.DEPLOYMENT_KEY }} From 09057f8c0b689d4c683ade539e5ff393f25f9f1f Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <127017088+SarahAbuirmeileh@users.noreply.github.com> Date: Tue, 17 Oct 2023 18:19:19 +0300 Subject: [PATCH 136/146] Update dataSource.ts --- src/db/dataSource.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/db/dataSource.ts b/src/db/dataSource.ts index 464eb96f..5104893b 100644 --- a/src/db/dataSource.ts +++ b/src/db/dataSource.ts @@ -23,6 +23,8 @@ const dataSource = new DataSource({ logging: false }); +console.log(dataSource.options); + export const initDB = async () => await dataSource.initialize().then(() => { console.log("Connected to DB!"); @@ -30,4 +32,4 @@ export const initDB = async () => console.log('Failed to connect to DB: ' + err) }); -export default dataSource; \ No newline at end of file +export default dataSource; From 489b032e5d9b9ec557bb43fca2853e0fdbbd34cd Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <127017088+SarahAbuirmeileh@users.noreply.github.com> Date: Tue, 17 Oct 2023 18:28:03 +0300 Subject: [PATCH 137/146] Update build.yml --- .github/workflows/build.yml | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 11d0ef05..db9945ff 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -61,10 +61,18 @@ jobs: run: docker compose logs - name: Run Migrations - run: | - docker compose -f docker-compose-prod.yml exec app npx typeorm-ts-node-esm migration:run -d ./src/db/dataSource.ts && - docker compose -f docker-compose-prod.yml exec app mv ./src/db/migrations/1697005494066-CreateRoles.ts ./src/db/migration && - docker compose -f docker-compose-prod.yml exec app npx typeorm-ts-node-esm migration:run -d ./src/db/dataSource.ts && - docker compose -f docker-compose-prod.yml exec app mv ./src/db/migrations/1697005554406-RootUser.ts ./src/db/migration && + run: + docker compose -f docker-compose-prod.yml exec app npx typeorm-ts-node-esm migration:run -d ./src/db/dataSource.ts + - name: Run Migrations2 + run: + docker compose -f docker-compose-prod.yml exec app mv ./src/db/migrations/1697005494066-CreateRoles.ts ./src/db/migration + - name: Run Migrations3 + run: + docker compose -f docker-compose-prod.yml exec app npx typeorm-ts-node-esm migration:run -d ./src/db/dataSource.ts + - name: Run Migrations4 + run: + docker compose -f docker-compose-prod.yml exec app mv ./src/db/migrations/1697005554406-RootUser.ts ./src/db/migration + - name: Run Migrations5 + run: docker compose -f docker-compose-prod.yml exec app npx typeorm-ts-node-esm migration:run -d ./src/db/dataSource.ts From f9b2ad69c71c601deff3572de1b55ccea9772d3b Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <127017088+SarahAbuirmeileh@users.noreply.github.com> Date: Wed, 18 Oct 2023 14:00:29 +0300 Subject: [PATCH 138/146] Update build.yml --- .github/workflows/build.yml | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index db9945ff..5af6fd4e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -37,7 +37,7 @@ jobs: - name: configer docker host uses: khaledez/configure-docker-host@v1 with: - host: 13.42.27.232 + host: 13.43.121.108 user: github ssh-private-key: ${{ secrets.DEPLOYMENT_KEY }} @@ -55,24 +55,17 @@ jobs: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID}} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY}} AWS_REGION: ${{ secrets.AWS_REGION}} + AWS_CERTIFICATES_BUCKET_NAME: ${{ sercrets.AWS_CERTIFICATES_BUCKET_NAME}} - name: print logs if: always() run: docker compose logs - name: Run Migrations - run: - docker compose -f docker-compose-prod.yml exec app npx typeorm-ts-node-esm migration:run -d ./src/db/dataSource.ts - - name: Run Migrations2 - run: - docker compose -f docker-compose-prod.yml exec app mv ./src/db/migrations/1697005494066-CreateRoles.ts ./src/db/migration - - name: Run Migrations3 - run: - docker compose -f docker-compose-prod.yml exec app npx typeorm-ts-node-esm migration:run -d ./src/db/dataSource.ts - - name: Run Migrations4 - run: - docker compose -f docker-compose-prod.yml exec app mv ./src/db/migrations/1697005554406-RootUser.ts ./src/db/migration - - name: Run Migrations5 - run: - docker compose -f docker-compose-prod.yml exec app npx typeorm-ts-node-esm migration:run -d ./src/db/dataSource.ts + run: | + docker compose exec app npx typeorm-ts-node-esm migration:run -d ./src/db/dataSource.ts && + docker compose exec app mv ./src/db/migrations/1697005494066-CreateRoles.ts ./src/db/migration && + docker compose exec app npx typeorm-ts-node-esm migration:run -d ./src/db/dataSource.ts && + docker compose exec app mv ./src/db/migrations/1697005554406-RootUser.ts ./src/db/migration && + docker compose exec app npx typeorm-ts-node-esm migration:run -d ./src/db/dataSource.ts From c4486ae09629a1b44e31b4f525eec64e86caec51 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <127017088+SarahAbuirmeileh@users.noreply.github.com> Date: Wed, 18 Oct 2023 14:03:19 +0300 Subject: [PATCH 139/146] Update build.yml --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5af6fd4e..8cb07022 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -55,7 +55,7 @@ jobs: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID}} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY}} AWS_REGION: ${{ secrets.AWS_REGION}} - AWS_CERTIFICATES_BUCKET_NAME: ${{ sercrets.AWS_CERTIFICATES_BUCKET_NAME}} + AWS_CERTIFICATES_BUCKET_NAME: ${{ secrets.AWS_CERTIFICATES_BUCKET_NAME}} - name: print logs if: always() From 90a82221219452c707ae314d864b7dc658d8c688 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <127017088+SarahAbuirmeileh@users.noreply.github.com> Date: Wed, 18 Oct 2023 14:10:15 +0300 Subject: [PATCH 140/146] Update build.yml --- .github/workflows/build.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8cb07022..02cb5bc2 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -61,6 +61,15 @@ jobs: if: always() run: docker compose logs + - name: Print Environment Variables + run: printenv + env: + DB_PASSWORD: ${{ secrets.DB_PASSWORD }} + DB_NAME: ${{ secrets.DB_NAME }} + PORT: ${{ secrets.PORT }} + DB_USERNAME: ${{ secrets.DB_USERNAME }} + DB_PORT: ${{ secrets.DB_PORT }} + - name: Run Migrations run: | docker compose exec app npx typeorm-ts-node-esm migration:run -d ./src/db/dataSource.ts && From 32c927f22f4e70c1a48e220aac30110adbe516d3 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <127017088+SarahAbuirmeileh@users.noreply.github.com> Date: Wed, 18 Oct 2023 14:18:26 +0300 Subject: [PATCH 141/146] Update build.yml --- .github/workflows/build.yml | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 02cb5bc2..cadbdf11 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -62,13 +62,8 @@ jobs: run: docker compose logs - name: Print Environment Variables - run: printenv - env: - DB_PASSWORD: ${{ secrets.DB_PASSWORD }} - DB_NAME: ${{ secrets.DB_NAME }} - PORT: ${{ secrets.PORT }} - DB_USERNAME: ${{ secrets.DB_USERNAME }} - DB_PORT: ${{ secrets.DB_PORT }} + run: echo "DB_PASSWORD:"+ ${{ secrets.DB_PASSWORD }} +" DB_HOST:" +${{ secrets.DB_HOST }} + - name: Run Migrations run: | From 26a8b12dcd379c7b8a7789095740271eebd749c4 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <127017088+SarahAbuirmeileh@users.noreply.github.com> Date: Wed, 18 Oct 2023 14:24:46 +0300 Subject: [PATCH 142/146] Update build.yml --- .github/workflows/build.yml | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index cadbdf11..579082d3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -61,10 +61,6 @@ jobs: if: always() run: docker compose logs - - name: Print Environment Variables - run: echo "DB_PASSWORD:"+ ${{ secrets.DB_PASSWORD }} +" DB_HOST:" +${{ secrets.DB_HOST }} - - - name: Run Migrations run: | docker compose exec app npx typeorm-ts-node-esm migration:run -d ./src/db/dataSource.ts && @@ -72,4 +68,13 @@ jobs: docker compose exec app npx typeorm-ts-node-esm migration:run -d ./src/db/dataSource.ts && docker compose exec app mv ./src/db/migrations/1697005554406-RootUser.ts ./src/db/migration && docker compose exec app npx typeorm-ts-node-esm migration:run -d ./src/db/dataSource.ts + env: + DB_PASSWORD: ${{ secrets.DB_PASSWORD}} + DB_HOST: ${{ secrets.DB_HOST}} + DB_PORT: ${{ secrets.DB_PORT}} + DB_USERNAME: ${{ secrets.DB_USERNAME}} + DB_NAME: ${{ secrets.DB_NAME}} + GIT_VERSISON: ${{steps.image_version.outputs.gitsha}} + + From 5bb9832bfe759c6ae8a778338be80a417455c354 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <127017088+SarahAbuirmeileh@users.noreply.github.com> Date: Wed, 18 Oct 2023 14:29:03 +0300 Subject: [PATCH 143/146] Update build.yml --- .github/workflows/build.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 579082d3..a0ce6994 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -56,6 +56,7 @@ jobs: AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY}} AWS_REGION: ${{ secrets.AWS_REGION}} AWS_CERTIFICATES_BUCKET_NAME: ${{ secrets.AWS_CERTIFICATES_BUCKET_NAME}} + PORT: ${{ secrets.PORT}} - name: print logs if: always() @@ -75,6 +76,7 @@ jobs: DB_USERNAME: ${{ secrets.DB_USERNAME}} DB_NAME: ${{ secrets.DB_NAME}} GIT_VERSISON: ${{steps.image_version.outputs.gitsha}} + PORT: ${{ secrets.PORT}} From 1e04595e2297b167fd4bc45f94c3fa8dfa12c98c Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <127017088+SarahAbuirmeileh@users.noreply.github.com> Date: Wed, 18 Oct 2023 14:36:28 +0300 Subject: [PATCH 144/146] Update docker-compose-prod.yml --- docker-compose-prod.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docker-compose-prod.yml b/docker-compose-prod.yml index 143acbe3..22c2d6d7 100644 --- a/docker-compose-prod.yml +++ b/docker-compose-prod.yml @@ -18,6 +18,7 @@ services: app: image: ghcr.io/sarahabuirmeileh/serve-and-shine:$GIT_VERSISON + mem_limit: 5g restart: always #like sysd service environment: - PORT=80 @@ -32,4 +33,4 @@ services: condition: service_healthy volumes: - db-data: \ No newline at end of file + db-data: From eacd01267228764fcf326b4b3aa44868bc7357da Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <127017088+SarahAbuirmeileh@users.noreply.github.com> Date: Wed, 18 Oct 2023 14:52:55 +0300 Subject: [PATCH 145/146] Update build.yml --- .github/workflows/build.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a0ce6994..cd9854b4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -64,11 +64,11 @@ jobs: - name: Run Migrations run: | - docker compose exec app npx typeorm-ts-node-esm migration:run -d ./src/db/dataSource.ts && - docker compose exec app mv ./src/db/migrations/1697005494066-CreateRoles.ts ./src/db/migration && - docker compose exec app npx typeorm-ts-node-esm migration:run -d ./src/db/dataSource.ts && - docker compose exec app mv ./src/db/migrations/1697005554406-RootUser.ts ./src/db/migration && - docker compose exec app npx typeorm-ts-node-esm migration:run -d ./src/db/dataSource.ts + docker compose -f docker-compose-prod.yml exec app npx typeorm-ts-node-esm migration:run -d ./src/db/dataSource.ts && + docker compose -f docker-compose-prod.yml exec app mv ./src/db/migrations/1697005494066-CreateRoles.ts ./src/db/migration && + docker compose -f docker-compose-prod.yml exec app npx typeorm-ts-node-esm migration:run -d ./src/db/dataSource.ts && + docker compose -f docker-compose-prod.yml exec app mv ./src/db/migrations/1697005554406-RootUser.ts ./src/db/migration && + docker compose -f docker-compose-prod.yml exec app npx typeorm-ts-node-esm migration:run -d ./src/db/dataSource.ts env: DB_PASSWORD: ${{ secrets.DB_PASSWORD}} DB_HOST: ${{ secrets.DB_HOST}} From 42ca035dde9e4ba790840318f1e2cf5497efb9a6 Mon Sep 17 00:00:00 2001 From: Sarah Abu irmeileh <127017088+SarahAbuirmeileh@users.noreply.github.com> Date: Wed, 18 Oct 2023 16:05:08 +0300 Subject: [PATCH 146/146] Update build.yml --- .github/workflows/build.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index cd9854b4..3a373a5e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -77,6 +77,8 @@ jobs: DB_NAME: ${{ secrets.DB_NAME}} GIT_VERSISON: ${{steps.image_version.outputs.gitsha}} PORT: ${{ secrets.PORT}} + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID}} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY}}