#20-calendar-api #21
9 changed files with 109 additions and 41 deletions
|
@ -2,6 +2,7 @@ export interface CreateCalendarTypeCommand {
|
||||||
type: string;
|
type: string;
|
||||||
nscdr: boolean;
|
nscdr: boolean;
|
||||||
color: string;
|
color: string;
|
||||||
|
passphrase?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface UpdateCalendarTypeCommand {
|
export interface UpdateCalendarTypeCommand {
|
||||||
|
@ -9,6 +10,7 @@ export interface UpdateCalendarTypeCommand {
|
||||||
type: string;
|
type: string;
|
||||||
nscdr: boolean;
|
nscdr: boolean;
|
||||||
color: string;
|
color: string;
|
||||||
|
passphrase?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DeleteCalendarTypeCommand {
|
export interface DeleteCalendarTypeCommand {
|
||||||
|
|
|
@ -18,6 +18,7 @@ export default abstract class CalendarTypeCommandHandler {
|
||||||
type: createCalendarType.type,
|
type: createCalendarType.type,
|
||||||
nscdr: createCalendarType.nscdr,
|
nscdr: createCalendarType.nscdr,
|
||||||
color: createCalendarType.color,
|
color: createCalendarType.color,
|
||||||
|
passphrase: createCalendarType.nscdr ? null : createCalendarType.passphrase,
|
||||||
})
|
})
|
||||||
.execute()
|
.execute()
|
||||||
.then((result) => {
|
.then((result) => {
|
||||||
|
@ -41,6 +42,7 @@ export default abstract class CalendarTypeCommandHandler {
|
||||||
type: updateCalendarType.type,
|
type: updateCalendarType.type,
|
||||||
nscdr: updateCalendarType.nscdr,
|
nscdr: updateCalendarType.nscdr,
|
||||||
color: updateCalendarType.color,
|
color: updateCalendarType.color,
|
||||||
|
passphrase: updateCalendarType.nscdr ? null : updateCalendarType.passphrase,
|
||||||
})
|
})
|
||||||
.where("id = :id", { id: updateCalendarType.id })
|
.where("id = :id", { id: updateCalendarType.id })
|
||||||
.execute()
|
.execute()
|
||||||
|
|
|
@ -101,11 +101,13 @@ export async function createCalendarType(req: Request, res: Response): Promise<a
|
||||||
const type = req.body.type;
|
const type = req.body.type;
|
||||||
const nscdr = req.body.nscdr;
|
const nscdr = req.body.nscdr;
|
||||||
const color = req.body.color;
|
const color = req.body.color;
|
||||||
|
const passphrase = req.body.passphrase;
|
||||||
|
|
||||||
let createType: CreateCalendarTypeCommand = {
|
let createType: CreateCalendarTypeCommand = {
|
||||||
type,
|
type,
|
||||||
nscdr,
|
nscdr,
|
||||||
color,
|
color,
|
||||||
|
passphrase,
|
||||||
};
|
};
|
||||||
let id = await CalendarTypeCommandHandler.create(createType);
|
let id = await CalendarTypeCommandHandler.create(createType);
|
||||||
|
|
||||||
|
@ -154,12 +156,14 @@ export async function updateCalendarType(req: Request, res: Response): Promise<a
|
||||||
const type = req.body.type;
|
const type = req.body.type;
|
||||||
const nscdr = req.body.nscdr;
|
const nscdr = req.body.nscdr;
|
||||||
const color = req.body.color;
|
const color = req.body.color;
|
||||||
|
const passphrase = req.body.passphrase;
|
||||||
|
|
||||||
let updateType: UpdateCalendarTypeCommand = {
|
let updateType: UpdateCalendarTypeCommand = {
|
||||||
id,
|
id,
|
||||||
type,
|
type,
|
||||||
nscdr,
|
nscdr,
|
||||||
color,
|
color,
|
||||||
|
passphrase,
|
||||||
};
|
};
|
||||||
await CalendarTypeCommandHandler.update(updateType);
|
await CalendarTypeCommandHandler.update(updateType);
|
||||||
|
|
||||||
|
|
|
@ -4,29 +4,60 @@ import CalendarTypeService from "../service/calendarTypeService";
|
||||||
import { calendar } from "../entity/calendar";
|
import { calendar } from "../entity/calendar";
|
||||||
import { createEvents } from "ics";
|
import { createEvents } from "ics";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
|
import InternalException from "../exceptions/internalException";
|
||||||
|
import CalendarFactory from "../factory/admin/calendar";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description get all calendar items by types or nscdr
|
* @description get all calendar items by types or nscdr
|
||||||
|
* @summary passphrase is passed as value pair like `type:passphrase`
|
||||||
* @param req {Request} Express req object
|
* @param req {Request} Express req object
|
||||||
* @param res {Response} Express res object
|
* @param res {Response} Express res object
|
||||||
* @returns {Promise<*>}
|
* @returns {Promise<*>}
|
||||||
*/
|
*/
|
||||||
export async function getCalendarItemsByTypes(req: Request, res: Response): Promise<any> {
|
export async function getCalendarItemsByTypes(req: Request, res: Response): Promise<any> {
|
||||||
let types = Array.isArray(req.query.types) ? req.query.types : [req.query.types];
|
let types = Array.isArray(req.query.types) ? req.query.types : [req.query.types];
|
||||||
|
let output = (req.query.output as "ics" | "json") ?? "ics";
|
||||||
|
|
||||||
|
if (output != "ics" && output != "json") {
|
||||||
|
throw new InternalException("set output query value to `ics` or `json` (defaults to `ics`)");
|
||||||
|
}
|
||||||
|
|
||||||
|
types = types.filter((t) => t);
|
||||||
|
|
||||||
let items: Array<calendar> = [];
|
let items: Array<calendar> = [];
|
||||||
if (types.length == 0) {
|
if (types.length != 0) {
|
||||||
let typeIds = await CalendarTypeService.getByTypes(types as Array<string>);
|
let typeIds = await CalendarTypeService.getByTypes((types as Array<string>).map((t) => t.split(":")[0]));
|
||||||
|
typeIds = typeIds.filter(
|
||||||
|
(ti) =>
|
||||||
|
ti.passphrase == null ||
|
||||||
|
ti.passphrase == "" ||
|
||||||
|
ti.passphrase == (types as Array<string>).find((t) => t.includes(ti.type)).split(":")[1]
|
||||||
|
);
|
||||||
items = await CalendarService.getByTypes(typeIds.map((t) => t.id));
|
items = await CalendarService.getByTypes(typeIds.map((t) => t.id));
|
||||||
} else {
|
} else {
|
||||||
items = await CalendarService.getByTypeNSCDR();
|
items = await CalendarService.getByTypeNSCDR();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (output == "json") {
|
||||||
|
res.json(CalendarFactory.mapToBase(items));
|
||||||
|
} else {
|
||||||
let events = createEvents(
|
let events = createEvents(
|
||||||
items.map((i) => ({
|
items.map((i) => ({
|
||||||
calName: process.env.CLUB_NAME,
|
calName: process.env.CLUB_NAME,
|
||||||
uid: i.id,
|
uid: i.id,
|
||||||
sequence: 1,
|
sequence: 1,
|
||||||
|
...(i.allDay
|
||||||
|
? {
|
||||||
|
start: moment(i.starttime)
|
||||||
|
.format("YYYY-M-D")
|
||||||
|
.split("-")
|
||||||
|
.map((a) => parseInt(a)) as [number, number, number],
|
||||||
|
end: moment(i.endtime)
|
||||||
|
.format("YYYY-M-D")
|
||||||
|
.split("-")
|
||||||
|
.map((a) => parseInt(a)) as [number, number, number],
|
||||||
|
}
|
||||||
|
: {
|
||||||
start: moment(i.starttime)
|
start: moment(i.starttime)
|
||||||
.format("YYYY-M-D-H-m")
|
.format("YYYY-M-D-H-m")
|
||||||
.split("-")
|
.split("-")
|
||||||
|
@ -35,6 +66,7 @@ export async function getCalendarItemsByTypes(req: Request, res: Response): Prom
|
||||||
.format("YYYY-M-D-H-m")
|
.format("YYYY-M-D-H-m")
|
||||||
.split("-")
|
.split("-")
|
||||||
.map((a) => parseInt(a)) as [number, number, number, number, number],
|
.map((a) => parseInt(a)) as [number, number, number, number, number],
|
||||||
|
}),
|
||||||
title: i.title,
|
title: i.title,
|
||||||
description: i.content,
|
description: i.content,
|
||||||
location: i.location,
|
location: i.location,
|
||||||
|
@ -63,4 +95,5 @@ export async function getCalendarItemsByTypes(req: Request, res: Response): Prom
|
||||||
);
|
);
|
||||||
|
|
||||||
res.type("ics").send(events.value);
|
res.type("ics").send(events.value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,7 @@ import { Calendar1729947763295 } from "./migrations/1729947763295-calendar";
|
||||||
import { reset } from "./entity/reset";
|
import { reset } from "./entity/reset";
|
||||||
import { ResetToken1732358596823 } from "./migrations/1732358596823-resetToken";
|
import { ResetToken1732358596823 } from "./migrations/1732358596823-resetToken";
|
||||||
import { SMSAlarming1732696919191 } from "./migrations/1732696919191-SMSAlarming";
|
import { SMSAlarming1732696919191 } from "./migrations/1732696919191-SMSAlarming";
|
||||||
|
import { SecuringCalendarType1733249553766 } from "./migrations/1733249553766-securingCalendarType";
|
||||||
|
|
||||||
const dataSource = new DataSource({
|
const dataSource = new DataSource({
|
||||||
type: DB_TYPE as any,
|
type: DB_TYPE as any,
|
||||||
|
@ -96,6 +97,7 @@ const dataSource = new DataSource({
|
||||||
Calendar1729947763295,
|
Calendar1729947763295,
|
||||||
ResetToken1732358596823,
|
ResetToken1732358596823,
|
||||||
SMSAlarming1732696919191,
|
SMSAlarming1732696919191,
|
||||||
|
SecuringCalendarType1733249553766,
|
||||||
],
|
],
|
||||||
migrationsRun: true,
|
migrationsRun: true,
|
||||||
migrationsTransactionMode: "each",
|
migrationsTransactionMode: "each",
|
||||||
|
|
|
@ -15,6 +15,9 @@ export class calendarType {
|
||||||
@Column({ type: "varchar", length: 255 })
|
@Column({ type: "varchar", length: 255 })
|
||||||
color: string;
|
color: string;
|
||||||
|
|
||||||
|
@Column({ type: "varchar", length: 255, nullable: true, default: null })
|
||||||
|
passphrase: string | null;
|
||||||
|
|
||||||
@OneToMany(() => calendar, (c) => c.type, {
|
@OneToMany(() => calendar, (c) => c.type, {
|
||||||
nullable: false,
|
nullable: false,
|
||||||
onDelete: "RESTRICT",
|
onDelete: "RESTRICT",
|
||||||
|
|
|
@ -13,6 +13,7 @@ export default abstract class CalendarTypeFactory {
|
||||||
type: record.type,
|
type: record.type,
|
||||||
nscdr: record.nscdr,
|
nscdr: record.nscdr,
|
||||||
color: record.color,
|
color: record.color,
|
||||||
|
passphrase: record.passphrase,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
20
src/migrations/1733249553766-securingCalendarType.ts
Normal file
20
src/migrations/1733249553766-securingCalendarType.ts
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
import { MigrationInterface, QueryRunner, TableColumn } from "typeorm";
|
||||||
|
|
||||||
|
export class SecuringCalendarType1733249553766 implements MigrationInterface {
|
||||||
|
name = "SecuringCalendarType1733249553766";
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.addColumns("calendar_type", [
|
||||||
|
new TableColumn({
|
||||||
|
name: "passphrase",
|
||||||
|
type: "varchar",
|
||||||
|
length: "255",
|
||||||
|
isNullable: true,
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.dropColumn("calendar_type", "passphrase");
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,4 +3,5 @@ export interface CalendarTypeViewModel {
|
||||||
type: string;
|
type: string;
|
||||||
nscdr: boolean;
|
nscdr: boolean;
|
||||||
color: string;
|
color: string;
|
||||||
|
passphrase: string | null;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue